Browse Source

Rector and phpcs agree on code style now.

release-1750933279
James Cole 4 months ago
parent
commit
0dae43e2aa
  1. 6
      .ci/php-cs-fixer/.php-cs-fixer.php
  2. 1
      .ci/phpcs.sh
  3. 5
      app/Console/AutoImports.php
  4. 12
      app/Console/Commands/UpgradeImportConfigurations.php
  5. 5
      app/Console/Kernel.php
  6. 3
      app/Console/VerifyJSON.php
  7. 4
      app/Exceptions/AgreementExpiredException.php
  8. 4
      app/Exceptions/ApiException.php
  9. 4
      app/Exceptions/ApiHttpException.php
  10. 8
      app/Exceptions/Handler.php
  11. 4
      app/Exceptions/ImportException.php
  12. 4
      app/Exceptions/ImporterErrorException.php
  13. 4
      app/Exceptions/ImporterHttpException.php
  14. 4
      app/Exceptions/RateLimitException.php
  15. 4
      app/Exceptions/SpectreErrorException.php
  16. 4
      app/Exceptions/SpectreHttpException.php
  17. 5
      app/Http/Controllers/DebugController.php
  18. 2
      app/Http/Controllers/Import/AuthenticateController.php
  19. 6
      app/Http/Controllers/Import/ConfigurationController.php
  20. 11
      app/Http/Controllers/Import/ConversionController.php
  21. 3
      app/Http/Controllers/Import/DownloadController.php
  22. 3
      app/Http/Controllers/Import/DuplicateCheckController.php
  23. 18
      app/Http/Controllers/Import/MapController.php
  24. 3
      app/Http/Controllers/Import/Nordigen/SelectionController.php
  25. 5
      app/Http/Controllers/Import/Spectre/ConnectionController.php
  26. 6
      app/Http/Controllers/Import/SubmitController.php
  27. 5
      app/Http/Controllers/Import/UploadController.php
  28. 11
      app/Http/Controllers/TokenController.php
  29. 3
      app/Http/Middleware/Authenticate.php
  30. 3
      app/Http/Middleware/IsReadyForStep.php
  31. 3
      app/Http/Middleware/RedirectIfAuthenticated.php
  32. 3
      app/Http/Request/Request.php
  33. 14
      app/Jobs/ProcessImportSubmissionJob.php
  34. 3
      app/Providers/AppServiceProvider.php
  35. 3
      app/Rules/Iban.php
  36. 3
      app/Services/CSV/Configuration/ConfigFileProcessor.php
  37. 3
      app/Services/CSV/Conversion/Routine/CSVFileProcessor.php
  38. 6
      app/Services/CSV/Conversion/Routine/ColumnValueConverter.php
  39. 3
      app/Services/CSV/Conversion/RoutineManager.php
  40. 3
      app/Services/CSV/Converter/ConverterService.php
  41. 4
      app/Services/CSV/Converter/Date.php
  42. 3
      app/Services/CSV/Converter/Iban.php
  43. 7
      app/Services/CSV/Roles/RoleService.php
  44. 3
      app/Services/Camt/Conversion/RoutineManager.php
  45. 3
      app/Services/Nordigen/Conversion/RoutineManager.php
  46. 15
      app/Services/Nordigen/Model/Transaction.php
  47. 5
      app/Services/Nordigen/Request/Request.php
  48. 2
      app/Services/Nordigen/Response/GetTransactionsResponse.php
  49. 2
      app/Services/Nordigen/Response/ListAccountsResponse.php
  50. 2
      app/Services/Nordigen/Response/ListBanksResponse.php
  51. 6
      app/Services/Shared/Configuration/Configuration.php
  52. 6
      app/Services/Shared/Conversion/GeneratesIdentifier.php
  53. 28
      app/Services/Shared/Conversion/RoutineStatusManager.php
  54. 5
      app/Services/Shared/File/FileContentSherlock.php
  55. 28
      app/Services/Shared/Import/Status/SubmissionStatusManager.php
  56. 6
      app/Services/Shared/Submission/GeneratesIdentifier.php
  57. 3
      app/Services/SimpleFIN/Conversion/AccountMapper.php
  58. 3
      app/Services/SimpleFIN/Conversion/RoutineManager.php
  59. 3
      app/Services/SimpleFIN/Conversion/TransactionTransformer.php
  60. 11
      app/Services/SimpleFIN/Model/Account.php
  61. 11
      app/Services/SimpleFIN/Model/Transaction.php
  62. 11
      app/Services/SimpleFIN/SimpleFINService.php
  63. 3
      app/Services/Spectre/Conversion/RoutineManager.php
  64. 3
      app/Services/Spectre/Model/TransactionExtra.php
  65. 29
      app/Services/Spectre/Request/Request.php
  66. 2
      app/Services/Spectre/Response/GetAccountsResponse.php
  67. 2
      app/Services/Spectre/Response/GetTransactionsResponse.php
  68. 2
      app/Services/Spectre/Response/ListConnectionsResponse.php
  69. 2
      app/Services/Spectre/Response/ListCustomersResponse.php
  70. 13
      app/Services/Storage/StorageService.php
  71. 3
      app/Support/Internal/CollectsAccounts.php
  72. 27
      tests/Feature/SimpleFIN/DemoModeTest.php
  73. 2
      tests/Unit/ExampleTest.php
  74. 56
      tests/Unit/Services/CSV/Converter/AmountTest.php
  75. 96
      tests/Unit/Services/SimpleFIN/Validation/ConfigurationContractValidatorTest.php

6
.ci/php-cs-fixer/.php-cs-fixer.php

@ -60,7 +60,13 @@ return $config->setRules(
'type_declaration_spaces' => false,
'cast_spaces' => false,
// enabled rules
'global_namespace_import' => true, // matches with rector.
// complex rules
'php_unit_test_case_static_method_calls' => [
'call_type' => 'this',
],
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'default' => 'at_least_single_space',

1
.ci/phpcs.sh

@ -29,6 +29,7 @@ rm -f .php-cs-fixer.cache
PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix \
--config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \
--format=txt \
-v \
--allow-risky=yes
EXIT_CODE=$?

5
app/Console/AutoImports.php

@ -50,6 +50,7 @@ use GrumpyDictator\FFIIIApiSupport\Response\GetAccountResponse;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use JsonException;
/**
* Trait AutoImports
@ -378,7 +379,7 @@ trait AutoImports
try {
$disk->put(sprintf('%s.json', $this->identifier), json_encode($transactions, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR));
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error(sprintf('JSON exception: %s', $e->getMessage()));
RoutineStatusManager::setConversionStatus(ConversionStatus::CONVERSION_ERRORED, $this->identifier);
$this->conversionMessages = $manager->getAllMessages();
@ -454,7 +455,7 @@ trait AutoImports
$json = $disk->get($fileName);
$transactions = json_decode((string) $json, true, 512, JSON_THROW_ON_ERROR);
Log::debug(sprintf('Found %d transactions on the drive.', count($transactions)));
} catch (FileNotFoundException|\JsonException $e) {
} catch (FileNotFoundException|JsonException $e) {
SubmissionStatusManager::setSubmissionStatus(SubmissionStatus::SUBMISSION_ERRORED, $this->identifier);
$message = sprintf('[a101]: File "%s" could not be decoded, cannot continue..', $fileName);
$this->error($message);

12
app/Console/Commands/UpgradeImportConfigurations.php

@ -27,6 +27,10 @@ namespace App\Console\Commands;
use App\Services\Shared\Configuration\Configuration;
use Illuminate\Console\Command;
use FilesystemIterator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplFileInfo;
final class UpgradeImportConfigurations extends Command
{
@ -66,12 +70,12 @@ final class UpgradeImportConfigurations extends Command
private function processRoot(string $directory): void
{
$dir = new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS);
$files = new \RecursiveIteratorIterator($dir, \RecursiveIteratorIterator::SELF_FIRST);
$dir = new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::SELF_FIRST);
/**
* @var string $name
* @var \SplFileInfo $object
* @var string $name
* @var SplFileInfo $object
*/
foreach ($files as $name => $object) {
$this->processFile($name);

5
app/Console/Kernel.php

@ -27,6 +27,7 @@ namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Override;
/**
* Class Kernel
@ -45,7 +46,7 @@ class Kernel extends ConsoleKernel
/**
* Register the commands for the application.
*/
#[\Override]
#[Override]
protected function commands(): void
{
$accessToken = (string) env('FIREFLY_III_ACCESS_TOKEN', '');
@ -77,6 +78,6 @@ class Kernel extends ConsoleKernel
/**
* Define the application's command schedule.
*/
#[\Override]
#[Override]
protected function schedule(Schedule $schedule): void {}
}

3
app/Console/VerifyJSON.php

@ -26,6 +26,7 @@ declare(strict_types=1);
namespace App\Console;
use Illuminate\Support\Facades\Log;
use JsonException;
/**
* Trait VerifyJSON
@ -39,7 +40,7 @@ trait VerifyJSON
try {
json_decode($json, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
$message = sprintf('The importer can\'t import: could not decode the JSON in the config file: %s', $e->getMessage());
Log::error($message);

4
app/Exceptions/AgreementExpiredException.php

@ -25,10 +25,12 @@ declare(strict_types=1);
namespace App\Exceptions;
use Exception;
/**
* Class AgreementExpiredException
*/
class AgreementExpiredException extends \Exception
class AgreementExpiredException extends Exception
{
public array $json = [];
}

4
app/Exceptions/ApiException.php

@ -25,9 +25,11 @@ declare(strict_types=1);
namespace App\Exceptions;
use Exception;
/**
* Class ApiException
*
* @deprecated
*/
class ApiException extends \Exception {}
class ApiException extends Exception {}

4
app/Exceptions/ApiHttpException.php

@ -25,9 +25,11 @@ declare(strict_types=1);
namespace App\Exceptions;
use Exception;
/**
* Class ApiHttpException
*
* @deprecated
*/
class ApiHttpException extends \Exception {}
class ApiHttpException extends Exception {}

8
app/Exceptions/Handler.php

@ -29,6 +29,8 @@ use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Override;
use Throwable;
/**
* Class Handler
@ -50,10 +52,10 @@ class Handler extends ExceptionHandler
*
* @return \Illuminate\Http\Response|JsonResponse|Response
*
* @throws \Throwable
* @throws Throwable
*/
#[\Override]
public function render($request, \Throwable $e)
#[Override]
public function render($request, Throwable $e)
{
if ($e instanceof ImporterErrorException || $e instanceof ImporterHttpException) {
$isDebug = config('app.debug');

4
app/Exceptions/ImportException.php

@ -25,9 +25,11 @@ declare(strict_types=1);
namespace App\Exceptions;
use Exception;
/**
* Class ImportException
*
* @deprecated
*/
class ImportException extends \Exception {}
class ImportException extends Exception {}

4
app/Exceptions/ImporterErrorException.php

@ -25,10 +25,12 @@ declare(strict_types=1);
namespace App\Exceptions;
use Exception;
/**
* Class ImporterErrorException
*/
class ImporterErrorException extends \Exception
class ImporterErrorException extends Exception
{
public array $json;
public int $statusCode = 0;

4
app/Exceptions/ImporterHttpException.php

@ -25,7 +25,9 @@ declare(strict_types=1);
namespace App\Exceptions;
use Exception;
/**
* Class ImporterHttpException
*/
class ImporterHttpException extends \Exception {}
class ImporterHttpException extends Exception {}

4
app/Exceptions/RateLimitException.php

@ -25,4 +25,6 @@ declare(strict_types=1);
namespace App\Exceptions;
class RateLimitException extends \Exception {}
use Exception;
class RateLimitException extends Exception {}

4
app/Exceptions/SpectreErrorException.php

@ -25,12 +25,14 @@ declare(strict_types=1);
namespace App\Exceptions;
use Exception;
/**
* Class SpectreErrorException
*
* @deprecated
*/
class SpectreErrorException extends \Exception
class SpectreErrorException extends Exception
{
public array $json;
}

4
app/Exceptions/SpectreHttpException.php

@ -25,9 +25,11 @@ declare(strict_types=1);
namespace App\Exceptions;
use Exception;
/**
* Class SpectreHttpException
*
* @deprecated
*/
class SpectreHttpException extends \Exception {}
class SpectreHttpException extends Exception {}

5
app/Http/Controllers/DebugController.php

@ -32,6 +32,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;
use Exception;
class DebugController extends Controller
{
@ -55,7 +56,7 @@ class DebugController extends Controller
if (null !== $logFile) {
try {
$logContent = (string)file_get_contents($logFile);
} catch (\Exception) {
} catch (Exception) {
// @ignoreException
}
}
@ -109,7 +110,7 @@ class DebugController extends Controller
if (file_exists('/var/www/counter-main.txt')) {
$build = trim((string) file_get_contents('/var/www/counter-main.txt'));
}
} catch (\Exception $e) {
} catch (Exception $e) {
Log::debug('Could not check build counter, but that\'s ok.');
Log::warning($e->getMessage());
}

2
app/Http/Controllers/Import/AuthenticateController.php

@ -69,7 +69,7 @@ class AuthenticateController extends Controller
$pageTitle = 'Authentication';
$flow = $request->cookie(Constants::FLOW_COOKIE);
$subTitle = ucfirst($flow);
$error = \Session::get('error');
$error = Session::get('error');
if ('spectre' === $flow) {
$validator = new SpectreValidator();

6
app/Http/Controllers/Import/ConfigurationController.php

@ -47,6 +47,8 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use Exception;
use JsonException;
/**
* Class ConfigurationController
@ -283,7 +285,7 @@ class ConfigurationController extends Controller
$mapper = app(TransactionCurrencies::class);
return $mapper->getMap();
} catch (\Exception $e) {
} catch (Exception $e) {
Log::error(sprintf('Failed to load currencies: %s', $e->getMessage()));
return [];
@ -372,7 +374,7 @@ class ConfigurationController extends Controller
try {
$json = json_encode($configuration->toArray(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT);
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
throw new ImporterErrorException($e->getMessage(), 0, $e);

11
app/Http/Controllers/Import/ConversionController.php

@ -44,6 +44,9 @@ use Illuminate\Foundation\Application;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use JsonException;
use Storage;
use Throwable;
/**
* Class ConversionController
@ -140,7 +143,7 @@ class ConversionController extends Controller
try {
$routine = new SimpleFINRoutineManager($identifier);
Log::debug('SimpleFIN routine manager created successfully.');
} catch (\Throwable $e) {
} catch (Throwable $e) {
Log::error(sprintf('Failed to create SimpleFIN routine manager: %s', $e->getMessage()));
Log::error(sprintf('Error class: %s', $e::class));
Log::error(sprintf('Error file: %s:%d', $e->getFile(), $e->getLine()));
@ -264,7 +267,7 @@ class ConversionController extends Controller
try {
$routine = new SimpleFINRoutineManager($identifier);
Log::debug('SimpleFIN routine manager created successfully in start method.');
} catch (\Throwable $e) {
} catch (Throwable $e) {
Log::error(sprintf('Failed to create SimpleFIN routine manager in start method: %s', $e->getMessage()));
Log::error(sprintf('Error class: %s', $e::class));
Log::error(sprintf('Error file: %s:%d', $e->getFile(), $e->getLine()));
@ -303,11 +306,11 @@ class ConversionController extends Controller
}
Log::debug(sprintf('Conversion routine "%s" yielded %d transaction(s).', $flow, count($transactions)));
// save transactions in 'jobs' directory under the same key as the conversion thing.
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
$disk->put(sprintf('%s.json', $identifier), json_encode($transactions, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR));
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error(sprintf('JSON exception: %s', $e->getMessage()));
Log::error($e->getTraceAsString());
RoutineStatusManager::setConversionStatus(ConversionStatus::CONVERSION_ERRORED);

3
app/Http/Controllers/Import/DownloadController.php

@ -31,6 +31,7 @@ use App\Support\Http\RestoresConfiguration;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\Response;
use JsonException;
/**
* Class DownloadController
@ -40,7 +41,7 @@ class DownloadController extends Controller
use RestoresConfiguration;
/**
* @throws \JsonException
* @throws JsonException
*/
public function download(): Application|Response|ResponseFactory
{

3
app/Http/Controllers/Import/DuplicateCheckController.php

@ -31,6 +31,7 @@ use App\Services\SimpleFIN\Validation\ConfigurationContractValidator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Exception;
/**
* Class DuplicateCheckController
@ -108,7 +109,7 @@ class DuplicateCheckController extends Controller
'message' => $message,
]);
} catch (\Exception $e) {
} catch (Exception $e) {
Log::error('DUPLICATE_CHECK: Exception during duplicate check', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),

18
app/Http/Controllers/Import/MapController.php

@ -41,6 +41,8 @@ use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;
use InvalidArgumentException;
use JsonException;
/**
* Class MapController
@ -144,7 +146,7 @@ class MapController extends Controller
// create the "mapper" class which will get data from Firefly III.
$class = sprintf('App\Services\CSV\Mapper\%s', $info['mapper']);
if (!class_exists($class)) {
throw new \InvalidArgumentException(sprintf('Class %s does not exist.', $class));
throw new InvalidArgumentException(sprintf('Class %s does not exist.', $class));
}
Log::debug(sprintf('Associated class is %s', $class));
@ -220,7 +222,7 @@ class MapController extends Controller
// create the "mapper" class which will get data from Firefly III.
$class = sprintf('App\Services\CSV\Mapper\%s', $info['mapper']);
if (!class_exists($class)) {
throw new \InvalidArgumentException(sprintf('Class %s does not exist.', $class));
throw new InvalidArgumentException(sprintf('Class %s does not exist.', $class));
}
Log::debug(sprintf('Associated class is %s', $class));
@ -264,7 +266,7 @@ class MapController extends Controller
// create the "mapper" class which will get data from Firefly III.
$class = sprintf('App\Services\CSV\Mapper\%s', $opposingName['mapper']);
if (!class_exists($class)) {
throw new \InvalidArgumentException(sprintf('Class %s does not exist.', $class));
throw new InvalidArgumentException(sprintf('Class %s does not exist.', $class));
}
Log::debug(sprintf('Associated class is %s', $class));
@ -285,7 +287,7 @@ class MapController extends Controller
// create the "mapper" class which will get data from Firefly III.
$class = sprintf('App\Services\CSV\Mapper\%s', $category['mapper']);
if (!class_exists($class)) {
throw new \InvalidArgumentException(sprintf('Class %s does not exist.', $class));
throw new InvalidArgumentException(sprintf('Class %s does not exist.', $class));
}
Log::debug(sprintf('Associated class is %s', $class));
@ -305,7 +307,7 @@ class MapController extends Controller
// Use ExpenseRevenueAccounts mapper for SimpleFIN
$class = ExpenseRevenueAccounts::class;
if (!class_exists($class)) {
throw new \InvalidArgumentException(sprintf('Class %s does not exist.', $class));
throw new InvalidArgumentException(sprintf('Class %s does not exist.', $class));
}
Log::debug(sprintf('Associated class is %s', $class));
@ -348,7 +350,7 @@ class MapController extends Controller
try {
$array = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
throw new ImporterErrorException(sprintf('Could not decode download: %s', $e->getMessage()), 0, $e);
}
$opposing = [];
@ -401,7 +403,7 @@ class MapController extends Controller
try {
$array = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
throw new ImporterErrorException(sprintf('Could not decode download: %s', $e->getMessage()), 0, $e);
}
$expenseRevenue = [];
@ -446,7 +448,7 @@ class MapController extends Controller
try {
$array = json_decode((string) $json, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
throw new ImporterErrorException(sprintf('Could not decode download: %s', $e->getMessage()), 0, $e);
}
$categories = [];

3
app/Http/Controllers/Import/Nordigen/SelectionController.php

@ -44,6 +44,7 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use JsonException;
/**
* Class SelectionController
@ -127,7 +128,7 @@ class SelectionController extends Controller
try {
$json = json_encode($configuration->toArray(), JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
}
StorageService::storeContent($json);

5
app/Http/Controllers/Import/Spectre/ConnectionController.php

@ -49,6 +49,7 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use JsonException;
/**
* Class ConnectionController
@ -119,7 +120,7 @@ class ConnectionController extends Controller
try {
$json = json_encode($configuration->toArray(), JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
}
StorageService::storeContent($json);
@ -174,7 +175,7 @@ class ConnectionController extends Controller
try {
$json = json_encode($configuration->toArray(), JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
}
StorageService::storeContent($json);

6
app/Http/Controllers/Import/SubmitController.php

@ -42,6 +42,8 @@ use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use JsonException;
use Storage;
/**
* Class SubmitController
@ -114,7 +116,7 @@ class SubmitController extends Controller
// search for transactions on disk using the import routine's identifier, NOT the submission routine's:
$conversionIdentifier = session()->get(Constants::CONVERSION_JOB_IDENTIFIER);
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
$fileName = sprintf('%s.json', $conversionIdentifier);
// get files from disk:
@ -130,7 +132,7 @@ class SubmitController extends Controller
$json = $disk->get($fileName);
$transactions = json_decode((string) $json, true, 512, JSON_THROW_ON_ERROR);
Log::debug(sprintf('Found %d transactions on the drive.', count($transactions)));
} catch (FileNotFoundException|\JsonException $e) {
} catch (FileNotFoundException|JsonException $e) {
Log::error(sprintf('The file "%s" on "%s" disk contains error: %s', $fileName, self::DISK_NAME, $e->getMessage()));
// TODO error in logs
SubmissionStatusManager::setSubmissionStatus(SubmissionStatus::SUBMISSION_ERRORED);

5
app/Http/Controllers/Import/UploadController.php

@ -43,6 +43,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\MessageBag;
use Illuminate\View\View;
use League\Flysystem\FilesystemException;
use Storage;
/**
* Class UploadController
@ -80,7 +81,7 @@ class UploadController extends Controller
$simpleFinOriginUrl = config('simplefin.origin_url');
// get existing configs.
$disk = \Storage::disk('configurations');
$disk = Storage::disk('configurations');
Log::debug(sprintf('Going to check directory for config files: %s', config('filesystems.disks.configurations.root')));
$all = $disk->files();
@ -275,7 +276,7 @@ class UploadController extends Controller
{
if (!$file instanceof UploadedFile && '' !== $selection) {
Log::debug('User selected a config file from the store.');
$disk = \Storage::disk('configurations');
$disk = Storage::disk('configurations');
$configFileName = StorageService::storeContent($disk->get($selection));
session()->put(Constants::UPLOAD_CONFIG_FILE, $configFileName);

11
app/Http/Controllers/TokenController.php

@ -43,6 +43,9 @@ use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use JsonException;
use Str;
use Throwable;
/**
* Class TokenController
@ -56,7 +59,7 @@ class TokenController extends Controller
*
* @throws ImporterErrorException
* @throws GuzzleException
* @throws \Throwable
* @throws Throwable
*/
public function callback(Request $request)
{
@ -113,7 +116,7 @@ class TokenController extends Controller
try {
$data = json_decode((string)$response->getBody(), true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error(sprintf('JSON exception when decoding response: %s', $e->getMessage()));
Log::error(sprintf('Response from server: "%s"', (string)$response->getBody()));
@ -269,8 +272,8 @@ class TokenController extends Controller
$vanityURL = rtrim($vanityURL, '/');
Log::debug(sprintf('Now in %s(request, "%s", "%s", %d)', __METHOD__, $baseURL, $vanityURL, $clientId));
$state = \Str::random(40);
$codeVerifier = \Str::random(128);
$state = Str::random(40);
$codeVerifier = Str::random(128);
$request->session()->put('state', $state);
$request->session()->put('code_verifier', $codeVerifier);
$request->session()->put('form_client_id', $clientId);

3
app/Http/Middleware/Authenticate.php

@ -27,6 +27,7 @@ namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Http\Request;
use Override;
/**
* Class Authenticate
@ -38,7 +39,7 @@ class Authenticate extends Middleware
*
* @param Request $request
*/
#[\Override]
#[Override]
protected function redirectTo($request): ?string
{
if (!$request->expectsJson()) {

3
app/Http/Middleware/IsReadyForStep.php

@ -30,6 +30,7 @@ use App\Services\Session\Constants;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Closure;
/**
* Trait IsReadyForStep
@ -38,7 +39,7 @@ trait IsReadyForStep
{
public const string TEST = 'test';
public function handle(Request $request, \Closure $next): mixed
public function handle(Request $request, Closure $next): mixed
{
$result = $this->isReadyForStep($request);
if (true === $result) {

3
app/Http/Middleware/RedirectIfAuthenticated.php

@ -28,6 +28,7 @@ namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Closure;
/**
* Class RedirectIfAuthenticated
@ -42,7 +43,7 @@ class RedirectIfAuthenticated
*
* @return mixed
*/
public function handle($request, \Closure $next, $guard = null)
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);

3
app/Http/Request/Request.php

@ -28,6 +28,7 @@ namespace App\Http\Request;
use Carbon\Carbon;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Exception;
/**
* Class Request.
@ -130,7 +131,7 @@ class Request extends FormRequest
try {
$result = $this->get($field) ? new Carbon($this->get($field)) : null;
} catch (\Exception $e) {
} catch (Exception $e) {
Log::debug(sprintf('Exception when parsing date. Not interesting: %s', $e->getMessage()));
}

14
app/Jobs/ProcessImportSubmissionJob.php

@ -14,6 +14,8 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Exception;
use Throwable;
class ProcessImportSubmissionJob implements ShouldQueue
{
@ -53,11 +55,11 @@ class ProcessImportSubmissionJob implements ShouldQueue
// Validate authentication credentials before proceeding
if ('' === $this->accessToken) {
throw new \Exception('Access token is empty - cannot authenticate with Firefly III');
throw new Exception('Access token is empty - cannot authenticate with Firefly III');
}
if ('' === $this->baseUrl) {
throw new \Exception('Base URL is empty - cannot connect to Firefly III');
throw new Exception('Base URL is empty - cannot connect to Firefly III');
}
Log::info('Job authentication credentials validation', [
@ -112,13 +114,13 @@ class ProcessImportSubmissionJob implements ShouldQueue
]);
if ($verifyToken !== $this->accessToken) {
throw new \Exception(
throw new Exception(
'Failed to set access token in config properly'
);
}
if ($verifyUrl !== $this->baseUrl) {
throw new \Exception(
throw new Exception(
'Failed to set base URL in config properly'
);
}
@ -153,7 +155,7 @@ class ProcessImportSubmissionJob implements ShouldQueue
'warnings' => count($routine->getAllWarnings()),
'errors' => count($routine->getAllErrors()),
]);
} catch (\Throwable $e) {
} catch (Throwable $e) {
Log::error('ProcessImportSubmissionJob failed', [
'identifier' => $this->identifier,
'error' => $e->getMessage(),
@ -181,7 +183,7 @@ class ProcessImportSubmissionJob implements ShouldQueue
/**
* Handle a job failure.
*/
public function failed(\Throwable $exception): void
public function failed(Throwable $exception): void
{
Log::error('ProcessImportSubmissionJob marked as failed', [
'identifier' => $this->identifier,

3
app/Providers/AppServiceProvider.php

@ -27,6 +27,7 @@ namespace App\Providers;
use App\Support\Steam;
use Illuminate\Support\ServiceProvider;
use Override;
/**
* Class AppServiceProvider
@ -41,7 +42,7 @@ class AppServiceProvider extends ServiceProvider
/**
* Register any application services.
*/
#[\Override]
#[Override]
public function register(): void
{
$this->app->bind(

3
app/Rules/Iban.php

@ -26,6 +26,7 @@ namespace App\Rules;
use App\Services\CSV\Converter\Iban as IbanConverter;
use Illuminate\Contracts\Validation\ValidationRule;
use Closure;
/**
* IBAN rule class.
@ -43,7 +44,7 @@ class Iban implements ValidationRule
/**
* Determine if the given value is a valid IBAN.
*/
public function validate(string $attribute, mixed $value, \Closure $fail): void
public function validate(string $attribute, mixed $value, Closure $fail): void
{
$result = IbanConverter::isValidIban((string)$value);
if (!$result) {

3
app/Services/CSV/Configuration/ConfigFileProcessor.php

@ -30,6 +30,7 @@ use App\Services\Shared\Configuration\Configuration;
use App\Services\Storage\StorageService;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Facades\Log;
use JsonException;
/**
* Class ConfigFileProcessor
@ -55,7 +56,7 @@ class ConfigFileProcessor
try {
$json = json_decode($content, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
throw new ImporterErrorException(sprintf('Invalid JSON configuration file: %s', $e->getMessage()));

3
app/Services/CSV/Conversion/Routine/CSVFileProcessor.php

@ -33,6 +33,7 @@ use League\Csv\Exception;
use League\Csv\Reader;
use League\Csv\ResultSet;
use League\Csv\Statement;
use JsonException;
/**
* Class CSVFileProcessor
@ -157,7 +158,7 @@ class CSVFileProcessor
foreach ($array as $index => $line) {
try {
$hash = hash('sha256', json_encode($line, JSON_THROW_ON_ERROR));
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
// Log::error($e->getTraceAsString());

6
app/Services/CSV/Conversion/Routine/ColumnValueConverter.php

@ -29,6 +29,8 @@ use App\Exceptions\ImporterErrorException;
use App\Services\Shared\Configuration\Configuration;
use App\Services\Shared\Conversion\ProgressInformation;
use Illuminate\Support\Facades\Log;
use JsonException;
use UnexpectedValueException;
/**
* Class ColumnValueConverter
@ -113,7 +115,7 @@ class ColumnValueConverter
$transactionField = $this->roleToTransaction[$role] ?? null;
$parsedValue = $value->getParsedValue();
if (null === $transactionField) {
throw new \UnexpectedValueException(sprintf('No place for role "%s"', $value->getRole()));
throw new UnexpectedValueException(sprintf('No place for role "%s"', $value->getRole()));
}
if (null === $parsedValue) {
Log::debug(sprintf('Skip column #%d with role "%s" (in field "%s")', $columnIndex + 1, $role, $transactionField));
@ -187,7 +189,7 @@ class ColumnValueConverter
if (is_array($value)) {
try {
return json_encode($value, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
throw new ImporterErrorException($e->getMessage(), 0, $e);
}
}

3
app/Services/CSV/Conversion/RoutineManager.php

@ -40,6 +40,7 @@ use App\Services\Shared\Conversion\RoutineManagerInterface;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Override;
/**
* Class RoutineManager
@ -75,7 +76,7 @@ class RoutineManager implements RoutineManagerInterface
}
}
#[\Override]
#[Override]
public function getServiceAccounts(): array
{
return [];

3
app/Services/CSV/Converter/ConverterService.php

@ -26,6 +26,7 @@ declare(strict_types=1);
namespace App\Services\CSV\Converter;
use Illuminate\Support\Facades\Log;
use UnexpectedValueException;
/**
* Class ConverterService
@ -51,7 +52,7 @@ class ConverterService
return $object->convert($value);
}
throw new \UnexpectedValueException(sprintf('No such converter: "%s"', $class));
throw new UnexpectedValueException(sprintf('No such converter: "%s"', $class));
}
public static function exists(string $class): bool

4
app/Services/CSV/Converter/Date.php

@ -28,6 +28,8 @@ namespace App\Services\CSV\Converter;
use Carbon\Carbon;
use Carbon\Language;
use Illuminate\Support\Facades\Log;
use Exception;
use InvalidArgumentException;
/**
* Class Date
@ -74,7 +76,7 @@ class Date implements ConverterInterface
try {
$carbon = Carbon::createFromLocaleFormat($this->dateFormat, $this->dateLocale, $string);
} catch (\Exception|\InvalidArgumentException $e) {
} catch (Exception|InvalidArgumentException $e) {
Log::error(sprintf('%s converting the date: %s', $e::class, $e->getMessage()));
Log::debug('Date parsing error, will return today instead.');

3
app/Services/CSV/Converter/Iban.php

@ -26,6 +26,7 @@ declare(strict_types=1);
namespace App\Services\CSV\Converter;
use Illuminate\Support\Facades\Log;
use ValueError;
/**
* Class Iban
@ -97,7 +98,7 @@ class Iban implements ConverterInterface
try {
$checksum = bcmod($iban, '97');
} catch (\ValueError $e) {
} catch (ValueError $e) {
Log::error(sprintf('Bad IBAN: %s', $e->getMessage()));
$checksum = 2;
}

7
app/Services/CSV/Roles/RoleService.php

@ -38,6 +38,7 @@ use League\Csv\InvalidArgument;
use League\Csv\Reader;
use League\Csv\Statement;
use League\Csv\UnableToProcessCsv;
use InvalidArgumentException;
/**
* Class RoleService
@ -86,7 +87,7 @@ class RoleService
} catch (Exception $e) {
Log::error($e->getMessage());
throw new \InvalidArgumentException($e->getMessage());
throw new InvalidArgumentException($e->getMessage());
}
// @codeCoverageIgnoreEnd
Log::debug('Detected file headers:', $headers);
@ -106,7 +107,7 @@ class RoleService
} catch (Exception $e) {
Log::error($e->getMessage());
throw new \InvalidArgumentException($e->getMessage());
throw new InvalidArgumentException($e->getMessage());
}
}
@ -151,7 +152,7 @@ class RoleService
} catch (Exception $e) {
Log::error($e->getMessage());
throw new \InvalidArgumentException($e->getMessage());
throw new InvalidArgumentException($e->getMessage());
}
/** @codeCoverageIgnoreEnd */

3
app/Services/Camt/Conversion/RoutineManager.php

@ -39,6 +39,7 @@ use Genkgo\Camt\DTO\Message;
use Genkgo\Camt\Exception\InvalidMessageException;
use Genkgo\Camt\Reader;
use Illuminate\Support\Facades\Log;
use Override;
/**
* Class RoutineManager
@ -72,7 +73,7 @@ class RoutineManager implements RoutineManagerInterface
}
}
#[\Override]
#[Override]
public function getServiceAccounts(): array
{
return [];

3
app/Services/Nordigen/Conversion/RoutineManager.php

@ -39,6 +39,7 @@ use App\Services\Shared\Conversion\ProgressInformation;
use App\Services\Shared\Conversion\RoutineManagerInterface;
use GrumpyDictator\FFIIIApiSupport\Exceptions\ApiHttpException;
use Illuminate\Support\Facades\Log;
use Override;
/**
* Class RoutineManager
@ -76,7 +77,7 @@ class RoutineManager implements RoutineManagerInterface
$this->transactionFilter = new FilterTransactions();
}
#[\Override]
#[Override]
public function getServiceAccounts(): array
{
return $this->transactionProcessor->getAccounts();

15
app/Services/Nordigen/Model/Transaction.php

@ -30,6 +30,9 @@ use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
use Illuminate\Support\Facades\Log;
use Ramsey\Uuid\Uuid;
use DateTimeInterface;
use JsonException;
use Validator;
/**
* Class Transaction
@ -198,7 +201,7 @@ class Transaction
try {
$hash = hash('sha256', json_encode($array, JSON_THROW_ON_ERROR));
Log::warning('Generated random transaction ID from array!');
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error(sprintf('Could not parse array into JSON: %s', $e->getMessage()));
}
$object->transactionId = sprintf('ff3-%s', Uuid::uuid5(config('importer.namespace'), $hash));
@ -223,7 +226,7 @@ class Transaction
$object->additionalInformationStructured = $array['additional_information_structured'];
$object->balanceAfterTransaction = Balance::fromLocalArray($array['balance_after_transaction']);
$object->bankTransactionCode = $array['bank_transaction_code'];
$object->bookingDate = Carbon::createFromFormat(\DateTimeInterface::W3C, $array['booking_date']);
$object->bookingDate = Carbon::createFromFormat(DateTimeInterface::W3C, $array['booking_date']);
$object->checkId = $array['check_id'];
$object->creditorAgent = $array['creditor_agent'];
$object->creditorId = $array['creditor_id'];
@ -244,7 +247,7 @@ class Transaction
$object->transactionId = $array['transaction_id'];
$object->ultimateCreditor = $array['ultimate_creditor'];
$object->ultimateDebtor = $array['ultimate_debtor'];
$object->valueDate = Carbon::createFromFormat(\DateTimeInterface::W3C, $array['value_date']);
$object->valueDate = Carbon::createFromFormat(DateTimeInterface::W3C, $array['value_date']);
$object->transactionAmount = $array['transaction_amount']['amount'];
$object->currencyCode = $array['transaction_amount']['currency'];
$object->accountIdentifier = $array['account_identifier'];
@ -275,7 +278,7 @@ class Transaction
try {
$hash = hash('sha256', json_encode($array, JSON_THROW_ON_ERROR));
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error(sprintf('Could not parse array into JSON: %s', $e->getMessage()));
}
$object->transactionId = (string) Uuid::uuid5(config('importer.namespace'), $hash);
@ -361,7 +364,7 @@ class Transaction
if ('' !== $this->creditorAccountIban) {
$data = ['iban' => $this->creditorAccountIban];
$rules = ['iban' => ['required', new Iban()]];
$validator = \Validator::make($data, $rules);
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
Log::warning(sprintf('Destination IBAN is "%s" (creditor), but it is invalid, so ignoring', $this->creditorAccountIban));
@ -441,7 +444,7 @@ class Transaction
if ('' !== $this->debtorAccountIban) {
$data = ['iban' => $this->debtorAccountIban];
$rules = ['iban' => ['required', new Iban()]];
$validator = \Validator::make($data, $rules);
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
Log::warning(sprintf('Source IBAN is "%s" (debtor), but it is invalid, so ignoring', $this->debtorAccountIban));

5
app/Services/Nordigen/Request/Request.php

@ -36,6 +36,7 @@ use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\TransferException;
use Illuminate\Support\Facades\Log;
use Psr\Http\Message\ResponseInterface;
use JsonException;
/**
* Class Request
@ -170,7 +171,7 @@ abstract class Request
try {
$json = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
throw new ImporterHttpException(
sprintf(
'Could not decode JSON (%s). Error[%d] is: %s. Response: %s',
@ -271,7 +272,7 @@ abstract class Request
try {
$json = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
// TODO error response, not an exception.
throw new ImporterHttpException(sprintf('AuthenticatedJsonPost JSON: %s', $e->getMessage()), 0, $e);
}

2
app/Services/Nordigen/Response/GetTransactionsResponse.php

@ -34,7 +34,7 @@ use Iterator;
/**
* Class GetTransactionsResponse
*/
class GetTransactionsResponse extends Response implements \Iterator, \Countable
class GetTransactionsResponse extends Response implements Iterator, Countable
{
private readonly Collection $collection;
private int $position = 0;

2
app/Services/Nordigen/Response/ListAccountsResponse.php

@ -35,7 +35,7 @@ use Iterator;
/**
* Class ListAccountsResponse
*/
class ListAccountsResponse extends Response implements \Iterator, \Countable
class ListAccountsResponse extends Response implements Iterator, Countable
{
private array $accounts;
private readonly Collection $collection;

2
app/Services/Nordigen/Response/ListBanksResponse.php

@ -35,7 +35,7 @@ use Iterator;
/**
* Class ListBanksResponse
*/
class ListBanksResponse extends Response implements \Iterator, \Countable
class ListBanksResponse extends Response implements Iterator, Countable
{
private readonly Collection $collection;
private array $countries;

6
app/Services/Shared/Configuration/Configuration.php

@ -27,6 +27,8 @@ namespace App\Services\Shared\Configuration;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use DateTimeInterface;
use UnexpectedValueException;
/**
* Class Configuration
@ -194,7 +196,7 @@ class Configuration
return self::fromVersionThree($data);
}
throw new \UnexpectedValueException(sprintf('Configuration file version "%s" cannot be parsed.', $version));
throw new UnexpectedValueException(sprintf('Configuration file version "%s" cannot be parsed.', $version));
}
/**
@ -823,7 +825,7 @@ class Configuration
$array = [
'version' => $this->version,
'source' => sprintf('ff3-importer-%s', config('importer.version')),
'created_at' => date(\DateTimeInterface::W3C),
'created_at' => date(DateTimeInterface::W3C),
'date' => $this->date,
'default_account' => $this->defaultAccount,
'delimiter' => $this->delimiter,

6
app/Services/Shared/Conversion/GeneratesIdentifier.php

@ -26,6 +26,8 @@ declare(strict_types=1);
namespace App\Services\Shared\Conversion;
use Illuminate\Support\Facades\Log;
use Storage;
use Str;
/**
* Trait GeneratesIdentifier
@ -43,10 +45,10 @@ trait GeneratesIdentifier
protected function generateIdentifier(): void
{
Log::debug('Going to generate conversion routine identifier.');
$disk = \Storage::disk($this->diskName);
$disk = Storage::disk($this->diskName);
$count = 0;
do {
$generatedId = sprintf('conversion-%s', \Str::random(12));
$generatedId = sprintf('conversion-%s', Str::random(12));
++$count;
Log::debug(sprintf('Attempt #%d results in "%s"', $count, $generatedId));
} while ($count < 30 && $disk->exists($generatedId));

28
app/Services/Shared/Conversion/RoutineStatusManager.php

@ -31,6 +31,8 @@ use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use JsonException;
use Storage;
/**
* Class RoutineStatusManager
@ -44,13 +46,13 @@ class RoutineStatusManager
$lineNo = $index + 1;
Log::debug(sprintf('Add error on index #%d (line no. %d): %s', $index, $lineNo, $error));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
if ($disk->exists($identifier)) {
try {
$status = ConversionStatus::fromArray(json_decode((string) $disk->get($identifier), true, 512, JSON_THROW_ON_ERROR));
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
$status = new ConversionStatus();
}
@ -68,13 +70,13 @@ class RoutineStatusManager
$lineNo = $index + 1;
Log::debug(sprintf('Add rate limit message on index #%d (line no. %d): %s', $index, $lineNo, $message));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
if ($disk->exists($identifier)) {
try {
$status = ConversionStatus::fromArray(json_decode((string) $disk->get($identifier), true, 512, JSON_THROW_ON_ERROR));
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
$status = new ConversionStatus();
}
@ -91,11 +93,11 @@ class RoutineStatusManager
{
Log::debug(sprintf('Now in storeConversionStatus(%s): %s', $identifier, $status->status));
Log::debug(sprintf('Messages: %d, warnings: %d, errors: %d', count($status->messages), count($status->warnings), count($status->errors)));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
$disk->put($identifier, json_encode($status->toArray(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT));
} catch (\JsonException $e) {
} catch (JsonException $e) {
// do nothing
Log::error($e->getMessage());
}
@ -106,13 +108,13 @@ class RoutineStatusManager
$lineNo = $index + 1;
Log::debug(sprintf('Add message on index #%d (line no. %d): %s', $index, $lineNo, $message));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
if ($disk->exists($identifier)) {
try {
$status = ConversionStatus::fromArray(json_decode((string) $disk->get($identifier), true, 512, JSON_THROW_ON_ERROR));
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
$status = new ConversionStatus();
}
@ -130,13 +132,13 @@ class RoutineStatusManager
$lineNo = $index + 1;
Log::debug(sprintf('Add warning on index #%d (line no. %d): %s', $index, $lineNo, $warning));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
if ($disk->exists($identifier)) {
try {
$status = ConversionStatus::fromArray(json_decode((string) $disk->get($identifier), true, 512, JSON_THROW_ON_ERROR));
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
$status = new ConversionStatus();
}
@ -175,14 +177,14 @@ class RoutineStatusManager
public static function startOrFindConversion(string $identifier): ConversionStatus
{
Log::debug(sprintf('Now in startOrFindConversion(%s)', $identifier));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
// Log::debug(sprintf('Try to see if file exists for conversion "%s".', $identifier));
if ($disk->exists($identifier)) {
// Log::debug(sprintf('Status file exists for conversion "%s".', $identifier));
try {
$array = json_decode((string) $disk->get($identifier), true, 512, JSON_THROW_ON_ERROR);
$status = ConversionStatus::fromArray($array);
} catch (FileNotFoundException|\JsonException $e) {
} catch (FileNotFoundException|JsonException $e) {
Log::error($e->getMessage());
$status = new ConversionStatus();
}
@ -195,7 +197,7 @@ class RoutineStatusManager
try {
$disk->put($identifier, json_encode($status->toArray(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT));
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
}

5
app/Services/Shared/File/FileContentSherlock.php

@ -27,6 +27,7 @@ namespace App\Services\Shared\File;
use Genkgo\Camt\Config;
use Genkgo\Camt\Reader;
use Illuminate\Support\Facades\Log;
use Exception;
/**
* Class FileContentSherlock
@ -51,7 +52,7 @@ class FileContentSherlock
Log::debug('CAMT.053 Check on file: positive');
return 'camt';
} catch (\Exception $e) {
} catch (Exception $e) {
Log::debug('CAMT.053 Check on file: negative');
Log::debug($e->getMessage());
}
@ -70,7 +71,7 @@ class FileContentSherlock
Log::debug('CAMT.053 Check of content: positive');
return 'camt';
} catch (\Exception) {
} catch (Exception) {
Log::debug('CAMT.053 Check of content: negative');
// Log::debug($e->getMessage());
}

28
app/Services/Shared/Import/Status/SubmissionStatusManager.php

@ -31,6 +31,8 @@ use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use JsonException;
use Storage;
/**
* Class SubmissionStatusManager
@ -45,13 +47,13 @@ class SubmissionStatusManager
{
$lineNo = $index + 1;
Log::debug(sprintf('Add error on index #%d (line no. %d): %s', $index, $lineNo, $error));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
if ($disk->exists($identifier)) {
try {
$status = SubmissionStatus::fromArray(json_decode((string) $disk->get($identifier), true, 512, JSON_THROW_ON_ERROR));
} catch (\JsonException) {
} catch (JsonException) {
$status = new SubmissionStatus();
}
$status->errors[$index] ??= [];
@ -70,11 +72,11 @@ class SubmissionStatusManager
{
Log::debug(sprintf('Now in %s(%s): %s', __METHOD__, $identifier, $status->status));
Log::debug(sprintf('Messages: %d, warnings: %d, errors: %d', count($status->messages), count($status->warnings), count($status->errors)));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
$disk->put($identifier, json_encode($status->toArray(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT));
} catch (\JsonException $e) {
} catch (JsonException $e) {
// do nothing
Log::error($e->getMessage());
}
@ -85,13 +87,13 @@ class SubmissionStatusManager
$lineNo = $index + 1;
Log::debug(sprintf('Add message on index #%d (line no. %d): %s', $index, $lineNo, $message));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
if ($disk->exists($identifier)) {
try {
$status = SubmissionStatus::fromArray(json_decode((string) $disk->get($identifier), true, 512, JSON_THROW_ON_ERROR));
} catch (\JsonException) {
} catch (JsonException) {
$status = new SubmissionStatus();
}
$status->messages[$index] ??= [];
@ -111,13 +113,13 @@ class SubmissionStatusManager
$lineNo = $index + 1;
Log::debug(sprintf('Add warning on index #%d (line no. %d): %s', $index, $lineNo, $warning));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
if ($disk->exists($identifier)) {
try {
$status = SubmissionStatus::fromArray(json_decode((string) $disk->get($identifier), true, 512, JSON_THROW_ON_ERROR));
} catch (\JsonException) {
} catch (JsonException) {
$status = new SubmissionStatus();
}
$status->warnings[$index] ??= [];
@ -136,13 +138,13 @@ class SubmissionStatusManager
{
Log::debug(sprintf('Update progress for %s: %d/%d transactions', $identifier, $currentTransaction, $totalTransactions));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
if ($disk->exists($identifier)) {
try {
$status = SubmissionStatus::fromArray(json_decode((string) $disk->get($identifier), true, 512, JSON_THROW_ON_ERROR));
} catch (\JsonException) {
} catch (JsonException) {
$status = new SubmissionStatus();
}
@ -184,7 +186,7 @@ class SubmissionStatusManager
public static function startOrFindSubmission(string $identifier): SubmissionStatus
{
Log::debug(sprintf('Now in startOrFindJob(%s)', $identifier));
$disk = \Storage::disk(self::DISK_NAME);
$disk = Storage::disk(self::DISK_NAME);
try {
Log::debug(sprintf('Try to see if file exists for job %s.', $identifier));
@ -194,7 +196,7 @@ class SubmissionStatusManager
try {
$array = json_decode((string) $disk->get($identifier), true, 512, JSON_THROW_ON_ERROR);
$status = SubmissionStatus::fromArray($array);
} catch (FileNotFoundException|\JsonException $e) {
} catch (FileNotFoundException|JsonException $e) {
Log::error($e->getMessage());
$status = new SubmissionStatus();
}
@ -212,7 +214,7 @@ class SubmissionStatusManager
try {
$json = json_encode($status->toArray(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT);
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
$json = '{}';
}

6
app/Services/Shared/Submission/GeneratesIdentifier.php

@ -26,6 +26,8 @@ declare(strict_types=1);
namespace App\Services\Shared\Submission;
use Illuminate\Support\Facades\Log;
use Storage;
use Str;
/**
* Trait GeneratesIdentifier
@ -38,10 +40,10 @@ trait GeneratesIdentifier
public function generateIdentifier(): string
{
Log::debug('Going to generate submission routine identifier.');
$disk = \Storage::disk($this->diskName);
$disk = Storage::disk($this->diskName);
$count = 0;
do {
$generatedId = sprintf('submission-%s', \Str::random(12));
$generatedId = sprintf('submission-%s', Str::random(12));
++$count;
Log::debug(sprintf('Attempt #%d results in "%s"', $count, $generatedId));
} while ($count < 30 && $disk->exists($generatedId));

3
app/Services/SimpleFIN/Conversion/AccountMapper.php

@ -41,6 +41,7 @@ use GrumpyDictator\FFIIIApiSupport\Response\GetAccountsResponse;
use GrumpyDictator\FFIIIApiSupport\Response\Response;
use GrumpyDictator\FFIIIApiSupport\Response\ValidationErrorResponse;
use Illuminate\Support\Facades\Log;
use Exception;
/**
* Class AccountMapper
@ -260,7 +261,7 @@ class AccountMapper
Log::error(sprintf('API error creating account "%s": %s', $accountName, $e->getMessage()));
return null;
} catch (\Exception $e) {
} catch (Exception $e) {
Log::error(sprintf('Unexpected error creating account "%s": %s', $accountName, $e->getMessage()));
return null;

3
app/Services/SimpleFIN/Conversion/RoutineManager.php

@ -34,6 +34,7 @@ use App\Services\SimpleFIN\Model\Account;
use App\Services\SimpleFIN\SimpleFINService;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Override;
/**
* Class RoutineManager
@ -64,7 +65,7 @@ class RoutineManager implements RoutineManagerInterface
return $this->identifier;
}
#[\Override]
#[Override]
public function getServiceAccounts(): array
{
return session()->get(Constants::SIMPLEFIN_ACCOUNTS_DATA, []);

3
app/Services/SimpleFIN/Conversion/TransactionTransformer.php

@ -29,6 +29,7 @@ use App\Support\Http\CollectsAccounts;
use Carbon\Carbon;
use App\Services\Shared\Authentication\SecretManager;
use Illuminate\Support\Facades\Log;
use Exception;
// Removed SimpleFINModel imports as we now use arrays
@ -485,7 +486,7 @@ class TransactionTransformer
));
$this->accountsCollected = true;
} catch (\Exception $e) {
} catch (Exception $e) {
Log::error(sprintf('Failed to collect accounts: %s', $e->getMessage()));
Log::debug('Continuing without smart expense matching due to collection failure');
$this->expenseAccounts = [];

11
app/Services/SimpleFIN/Model/Account.php

@ -26,6 +26,7 @@ declare(strict_types=1);
namespace App\Services\SimpleFIN\Model;
use Carbon\Carbon;
use InvalidArgumentException;
/**
* Class Account
@ -183,17 +184,17 @@ class Account
foreach ($requiredFields as $field) {
if (!array_key_exists($field, $data)) {
throw new \InvalidArgumentException(sprintf('Missing required field: %s', $field));
throw new InvalidArgumentException(sprintf('Missing required field: %s', $field));
}
}
// Validate organization structure
if (!is_array($data['org'])) {
throw new \InvalidArgumentException('Organization must be an array');
throw new InvalidArgumentException('Organization must be an array');
}
if (!array_key_exists('sfin-url', $data['org']) && null !== $data['org']['sfin-url']) {
throw new \InvalidArgumentException('Organization must have sfin-url');
throw new InvalidArgumentException('Organization must have sfin-url');
}
@ -203,12 +204,12 @@ class Account
&& null !== $data['org']['domain']
&& null !== $data['org']['name']
) {
throw new \InvalidArgumentException('Organization must have either domain or name');
throw new InvalidArgumentException('Organization must have either domain or name');
}
// Validate balance-date is numeric
if (!is_numeric($data['balance-date'])) {
throw new \InvalidArgumentException('Balance date must be a numeric timestamp');
throw new InvalidArgumentException('Balance date must be a numeric timestamp');
}
}
}

11
app/Services/SimpleFIN/Model/Transaction.php

@ -26,6 +26,7 @@ declare(strict_types=1);
namespace App\Services\SimpleFIN\Model;
use Carbon\Carbon;
use InvalidArgumentException;
/**
* Class Transaction
@ -172,28 +173,28 @@ class Transaction
foreach ($requiredFields as $field) {
if (!array_key_exists($field, $data)) {
throw new \InvalidArgumentException(sprintf('Missing required field: %s', $field));
throw new InvalidArgumentException(sprintf('Missing required field: %s', $field));
}
}
// Validate posted is numeric
if (!is_numeric($data['posted'])) {
throw new \InvalidArgumentException('Posted date must be a numeric timestamp');
throw new InvalidArgumentException('Posted date must be a numeric timestamp');
}
// Validate amount is numeric string
if (!is_numeric($data['amount'])) {
throw new \InvalidArgumentException('Amount must be a numeric string');
throw new InvalidArgumentException('Amount must be a numeric string');
}
// Validate transacted_at if present
if (isset($data['transacted_at']) && !is_numeric($data['transacted_at'])) {
throw new \InvalidArgumentException('Transacted at must be a numeric timestamp');
throw new InvalidArgumentException('Transacted at must be a numeric timestamp');
}
// Validate pending if present
if (isset($data['pending']) && !is_bool($data['pending'])) {
throw new \InvalidArgumentException('Pending must be a boolean');
throw new InvalidArgumentException('Pending must be a boolean');
}
}
}

11
app/Services/SimpleFIN/SimpleFINService.php

@ -34,6 +34,9 @@ use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Log;
use DateTime;
use DateTimeZone;
use Exception;
/**
* Class SimpleFINService
@ -155,15 +158,15 @@ class SimpleFINService
if (isset($dateRange['start']) && '' !== (string)$dateRange['start']) {
try {
$startDateTimestamp = new \DateTime($dateRange['start'], new \DateTimeZone('UTC'))->setTime(0, 0, 0)->getTimestamp();
} catch (\Exception $e) {
$startDateTimestamp = new DateTime($dateRange['start'], new DateTimeZone('UTC'))->setTime(0, 0, 0)->getTimestamp();
} catch (Exception $e) {
Log::warning('Invalid start date format for SimpleFIN transaction filtering.', ['date' => $dateRange['start'], 'error' => $e->getMessage()]);
}
}
if (isset($dateRange['end']) && '' !== (string)$dateRange['end']) {
try {
$endDateTimestamp = new \DateTime($dateRange['end'], new \DateTimeZone('UTC'))->setTime(23, 59, 59)->getTimestamp();
} catch (\Exception $e) {
$endDateTimestamp = new DateTime($dateRange['end'], new DateTimeZone('UTC'))->setTime(23, 59, 59)->getTimestamp();
} catch (Exception $e) {
Log::warning('Invalid end date format for SimpleFIN transaction filtering.', ['date' => $dateRange['end'], 'error' => $e->getMessage()]);
}
}

3
app/Services/Spectre/Conversion/RoutineManager.php

@ -37,6 +37,7 @@ use App\Services\Spectre\Conversion\Routine\TransactionProcessor;
use App\Support\Http\CollectsAccounts;
use GrumpyDictator\FFIIIApiSupport\Exceptions\ApiHttpException;
use Illuminate\Support\Facades\Log;
use Override;
/**
* Class RoutineManager
@ -74,7 +75,7 @@ class RoutineManager implements RoutineManagerInterface
}
}
#[\Override]
#[Override]
public function getServiceAccounts(): array
{
return [];

3
app/Services/Spectre/Model/TransactionExtra.php

@ -27,6 +27,7 @@ namespace App\Services\Spectre\Model;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Exception;
/**
* Class TransactionExtra
@ -66,7 +67,7 @@ class TransactionExtra
/**
* TransactionExtra constructor.
*
* @throws \Exception
* @throws Exception
*/
private function __construct() {}

29
app/Services/Spectre/Request/Request.php

@ -34,6 +34,9 @@ use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\TransferException;
use Illuminate\Support\Facades\Log;
use Exception;
use JsonException;
use RuntimeException;
/**
* Class Request
@ -132,7 +135,7 @@ abstract class Request
try {
$json = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
throw new ImporterHttpException(
sprintf(
'Could not decode JSON (%s). Error[%d] is: %s. Response: %s',
@ -219,7 +222,7 @@ abstract class Request
try {
$body = json_encode($data, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
throw new ImporterErrorException($e->getMessage());
}
@ -228,13 +231,13 @@ abstract class Request
try {
$client = $this->getClient();
$res = $client->request('POST', $fullUrl, ['headers' => $headers, 'body' => $body]);
} catch (\Exception|GuzzleException $e) {
} catch (Exception|GuzzleException $e) {
throw new ImporterHttpException(sprintf('Guzzle Exception: %s', $e->getMessage()));
}
try {
$body = $res->getBody()->getContents();
} catch (\RuntimeException $e) {
} catch (RuntimeException $e) {
Log::error(sprintf('sendSignedSpectrePost: Could not get body from SpectreRequest::POST result: %s', $e->getMessage()));
$body = '{}';
}
@ -244,7 +247,7 @@ abstract class Request
try {
$json = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
throw new ImporterHttpException($e->getMessage());
}
$json['ResponseHeaders'] = $responseHeaders;
@ -285,7 +288,7 @@ abstract class Request
try {
$body = json_encode($data, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
}
if ('{}' !== (string) $body) {
@ -297,7 +300,7 @@ abstract class Request
try {
$client = $this->getClient();
$res = $client->request('POST', $fullUrl, $opts);
} catch (\Exception|GuzzleException $e) {
} catch (Exception|GuzzleException $e) {
Log::error($e->getMessage());
throw new ImporterHttpException(sprintf('Guzzle Exception: %s', $e->getMessage()));
@ -305,7 +308,7 @@ abstract class Request
try {
$body = $res->getBody()->getContents();
} catch (\RuntimeException $e) {
} catch (RuntimeException $e) {
Log::error(sprintf('sendUnsignedSpectrePost: Could not get body from SpectreRequest::POST result: %s', $e->getMessage()));
$body = '{}';
}
@ -315,7 +318,7 @@ abstract class Request
try {
$json = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
throw new ImporterHttpException($e->getMessage());
}
$json['ResponseHeaders'] = $responseHeaders;
@ -340,7 +343,7 @@ abstract class Request
try {
$body = json_encode($data, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
}
if ('{}' !== (string) $body) {
@ -362,7 +365,7 @@ abstract class Request
try {
$json = json_decode((string) $e->getResponse()->getBody(), true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
Log::error($e->getMessage());
}
$json['ResponseHeaders'] = $responseHeaders;
@ -380,7 +383,7 @@ abstract class Request
try {
$body = $res->getBody()->getContents();
} catch (\RuntimeException $e) {
} catch (RuntimeException $e) {
Log::error(sprintf('sendUnsignedSpectrePut: Could not get body from SpectreRequest::POST result: %s', $e->getMessage()));
$body = '{}';
}
@ -390,7 +393,7 @@ abstract class Request
try {
$json = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
} catch (JsonException $e) {
throw new ImporterHttpException($e->getMessage());
}
$json['ResponseHeaders'] = $responseHeaders;

2
app/Services/Spectre/Response/GetAccountsResponse.php

@ -34,7 +34,7 @@ use Iterator;
/**
* Class GetAccountsResponse
*/
class GetAccountsResponse extends Response implements \Iterator, \Countable
class GetAccountsResponse extends Response implements Iterator, Countable
{
private readonly Collection $collection;

2
app/Services/Spectre/Response/GetTransactionsResponse.php

@ -34,7 +34,7 @@ use Iterator;
/**
* Class GetTransactionsResponse
*/
class GetTransactionsResponse extends Response implements \Iterator, \Countable
class GetTransactionsResponse extends Response implements Iterator, Countable
{
private readonly Collection $collection;
private int $position = 0;

2
app/Services/Spectre/Response/ListConnectionsResponse.php

@ -34,7 +34,7 @@ use Iterator;
/**
* Class ListConnectionsResponse
*/
class ListConnectionsResponse extends Response implements \Iterator, \Countable
class ListConnectionsResponse extends Response implements Iterator, Countable
{
private readonly Collection $collection;
private int $position = 0;

2
app/Services/Spectre/Response/ListCustomersResponse.php

@ -34,7 +34,7 @@ use Iterator;
/**
* Class ListCustomersResponse
*/
class ListCustomersResponse extends Response implements \Iterator, \Countable
class ListCustomersResponse extends Response implements Iterator, Countable
{
private readonly Collection $collection;
private int $position = 0;

13
app/Services/Storage/StorageService.php

@ -28,6 +28,9 @@ namespace App\Services\Storage;
use App\Exceptions\ImporterErrorException;
use Illuminate\Support\Facades\Log;
use League\Flysystem\FilesystemException;
use JsonException;
use Storage;
use UnexpectedValueException;
/**
* Class StorageService
@ -36,9 +39,9 @@ class StorageService
{
public static function getContent(string $name, bool $convert = false): string
{
$disk = \Storage::disk('uploads');
$disk = Storage::disk('uploads');
if (!$disk->exists($name)) {
throw new \UnexpectedValueException(sprintf('No such file %s', $name));
throw new UnexpectedValueException(sprintf('No such file %s', $name));
}
if (false === $convert) {
return $disk->get($name);
@ -60,11 +63,11 @@ class StorageService
/**
* @throws FilesystemException
* @throws \JsonException
* @throws JsonException
*/
public static function storeArray(array $array): string
{
$disk = \Storage::disk('uploads');
$disk = Storage::disk('uploads');
$json = json_encode($array, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT, 256);
$fileName = hash('sha256', $json);
@ -85,7 +88,7 @@ class StorageService
public static function storeContent(string $content): string
{
$fileName = hash('sha256', $content);
$disk = \Storage::disk('uploads');
$disk = Storage::disk('uploads');
if ('{}' === $content) {
throw new ImporterErrorException('Content is {}');
}

3
app/Support/Internal/CollectsAccounts.php

@ -44,6 +44,7 @@ use GrumpyDictator\FFIIIApiSupport\Request\GetAccountsRequest;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Exception;
trait CollectsAccounts
{
@ -116,7 +117,7 @@ trait CollectsAccounts
]);
// Return the (potentially partially filled) $accounts array so the app doesn't hard crash.
// The view should handle cases where account lists are empty.
} catch (\Exception $e) {
} catch (Exception $e) {
Log::error('CollectsAccounts::getFireflyIIIAccounts - Generic Exception while fetching Firefly III accounts.', [
'message' => $e->getMessage(),
'code' => $e->getCode(),

27
tests/Feature/SimpleFIN/DemoModeTest.php

@ -9,6 +9,8 @@ use App\Support\Constants;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;
use Mockery;
use Override;
/**
* @internal
@ -19,6 +21,7 @@ final class DemoModeTest extends TestCase
{
use RefreshDatabase;
#[Override]
protected function setUp(): void
{
parent::setUp();
@ -38,16 +41,16 @@ final class DemoModeTest extends TestCase
;
// Check that we don't redirect back to upload (which indicates validation failure)
self::assertNotSame(route('003-upload.index'), $response->getTargetUrl());
$this->assertNotSame(route('003-upload.index'), $response->getTargetUrl());
// If demo mode works correctly, we should redirect to configuration
$response->assertRedirect(route('004-configure.index'));
// Verify session data was set correctly
self::assertSame('demo_token_123', session(Constants::SIMPLEFIN_TOKEN));
self::assertSame('https://demo:demo@beta-bridge.simplefin.org/simplefin', session(Constants::SIMPLEFIN_BRIDGE_URL));
self::assertTrue(session(Constants::SIMPLEFIN_IS_DEMO));
self::assertTrue(session(Constants::HAS_UPLOAD));
$this->assertSame('demo_token_123', session(Constants::SIMPLEFIN_TOKEN));
$this->assertSame('https://demo:demo@beta-bridge.simplefin.org/simplefin', session(Constants::SIMPLEFIN_BRIDGE_URL));
$this->assertTrue(session(Constants::SIMPLEFIN_IS_DEMO));
$this->assertTrue(session(Constants::HAS_UPLOAD));
}
public function testDemoModeCheckboxValueInterpretation(): void
@ -65,11 +68,7 @@ final class DemoModeTest extends TestCase
->post(route('003-upload.upload'), $case)
;
self::assertNotSame(
route('003-upload.index'),
$response->getTargetUrl(),
'Failed for case: '.json_encode($case)
);
$this->assertNotSame(route('003-upload.index'), $response->getTargetUrl(), 'Failed for case: '.json_encode($case));
}
}
@ -98,24 +97,24 @@ final class DemoModeTest extends TestCase
// Should attempt to connect (may fail due to invalid credentials, but shouldn't fail validation)
// The exact behavior depends on whether SimpleFINService is mocked
self::assertNotSame(route('003-upload.index'), $response->getTargetUrl());
$this->assertNotSame(route('003-upload.index'), $response->getTargetUrl());
}
public function testRequestDataLogging(): void
{
// Enable debug logging to capture the request data
Log::shouldReceive('debug')
->with('UploadController::upload() - Request All:', \Mockery::type('array'))
->with('UploadController::upload() - Request All:', Mockery::type('array'))
->once()
;
Log::shouldReceive('debug')
->with('handleSimpleFINFlow() - Request All:', \Mockery::type('array'))
->with('handleSimpleFINFlow() - Request All:', Mockery::type('array'))
->once()
;
Log::shouldReceive('debug')
->with('handleSimpleFINFlow() - Raw use_demo input:', \Mockery::type('array'))
->with('handleSimpleFINFlow() - Raw use_demo input:', Mockery::type('array'))
->once()
;

2
tests/Unit/ExampleTest.php

@ -39,6 +39,6 @@ final class ExampleTest extends TestCase
*/
public function testBasicTest(): void
{
self::assertTrue(true);
$this->assertTrue(true);
}
}

56
tests/Unit/Services/CSV/Converter/AmountTest.php

@ -42,41 +42,41 @@ final class AmountTest extends TestCase
{
$amount = new Amount();
self::assertSame('0', $amount->convert('0'));
self::assertSame('0.0', $amount->convert('0.0'));
self::assertSame('0.1', $amount->convert('0.1'));
self::assertSame('0.1', $amount->convert(0.1));
self::assertSame('1', $amount->convert(1));
self::assertSame('1', $amount->convert('1'));
self::assertSame('1.0', $amount->convert('1.0'));
self::assertSame('1000', $amount->convert('1000,-'));
self::assertSame('1000', $amount->convert('EUR 1000,-'));
self::assertSame('1000', $amount->convert('€ 1000,-'));
self::assertSame('1000', $amount->convert('1.000,-'));
self::assertSame('1000', $amount->convert('EUR 1.000,-'));
self::assertSame('1000', $amount->convert('€ 1.000,-'));
self::assertSame('1000.00', $amount->convert('1000,00'));
self::assertSame('1000.00', $amount->convert('1.000,00'));
self::assertSame('1000', $amount->convert('1.000,'));
self::assertSame('1000', $amount->convert('1.000'));
self::assertSame('1.00', $amount->convert('1.00'));
$this->assertSame('0', $amount->convert('0'));
$this->assertSame('0.0', $amount->convert('0.0'));
$this->assertSame('0.1', $amount->convert('0.1'));
$this->assertSame('0.1', $amount->convert(0.1));
$this->assertSame('1', $amount->convert(1));
$this->assertSame('1', $amount->convert('1'));
$this->assertSame('1.0', $amount->convert('1.0'));
$this->assertSame('1000', $amount->convert('1000,-'));
$this->assertSame('1000', $amount->convert('EUR 1000,-'));
$this->assertSame('1000', $amount->convert('€ 1000,-'));
$this->assertSame('1000', $amount->convert('1.000,-'));
$this->assertSame('1000', $amount->convert('EUR 1.000,-'));
$this->assertSame('1000', $amount->convert('€ 1.000,-'));
$this->assertSame('1000.00', $amount->convert('1000,00'));
$this->assertSame('1000.00', $amount->convert('1.000,00'));
$this->assertSame('1000', $amount->convert('1.000,'));
$this->assertSame('1000', $amount->convert('1.000'));
$this->assertSame('1.00', $amount->convert('1.00'));
// new tests
self::assertSame('25.00000', $amount->convert('25.00000'));
self::assertSame('251.000000', $amount->convert('251.000000'));
self::assertSame('2502.0000000', $amount->convert('2502.0000000'));
$this->assertSame('25.00000', $amount->convert('25.00000'));
$this->assertSame('251.000000', $amount->convert('251.000000'));
$this->assertSame('2502.0000000', $amount->convert('2502.0000000'));
self::assertSame('2530000000', $amount->convert('2.530.000.000,'));
self::assertSame('254.0000000', $amount->convert('254.0000000'));
self::assertSame('255.000000000', $amount->convert('255.000000000'));
$this->assertSame('2530000000', $amount->convert('2.530.000.000,'));
$this->assertSame('254.0000000', $amount->convert('254.0000000'));
$this->assertSame('255.000000000', $amount->convert('255.000000000'));
self::assertSame('1256.0000000', $amount->convert('1,256.0000000'));
self::assertSame('1001257.0000000', $amount->convert('1,001,257.0000000'));
$this->assertSame('1256.0000000', $amount->convert('1,256.0000000'));
$this->assertSame('1001257.0000000', $amount->convert('1,001,257.0000000'));
// the original problem from issue #8482
self::assertSame('25.00000', $amount->convert('25.00000'));
$this->assertSame('25.00000', $amount->convert('25.00000'));
// the original problem from issue #8404
self::assertSame('1000', $amount->convert('1.000'));
$this->assertSame('1000', $amount->convert('1.000'));
}
}

96
tests/Unit/Services/SimpleFIN/Validation/ConfigurationContractValidatorTest.php

@ -25,12 +25,14 @@ declare(strict_types=1);
namespace Tests\Unit\Services\SimpleFIN\Validation;
use Carbon\Carbon;
use App\Services\Shared\Configuration\Configuration;
use App\Services\SimpleFIN\Validation\ConfigurationContractValidator;
use App\Services\SimpleFIN\Validation\ValidationResult;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Facades\Session;
use Tests\TestCase;
use Override;
/**
* Class ConfigurationContractValidatorTest
@ -46,6 +48,7 @@ final class ConfigurationContractValidatorTest extends TestCase
private ConfigurationContractValidator $validator;
private Configuration $mockConfiguration;
#[Override]
protected function setUp(): void
{
parent::setUp();
@ -55,6 +58,7 @@ final class ConfigurationContractValidatorTest extends TestCase
$this->mockConfiguration = $this->createMockConfiguration();
}
#[Override]
protected function tearDown(): void
{
Session::flush();
@ -70,8 +74,8 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateConfigurationContract($this->mockConfiguration);
self::assertTrue($result->isValid());
self::assertEmpty($result->getErrors());
$this->assertTrue($result->isValid());
$this->assertEmpty($result->getErrors());
}
/**
@ -83,9 +87,9 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateConfigurationContract($invalidConfig);
self::assertFalse($result->isValid());
self::assertNotEmpty($result->getErrors());
self::assertStringContainsString('SimpleFIN flow', $result->getErrorMessages()[0]);
$this->assertFalse($result->isValid());
$this->assertNotEmpty($result->getErrors());
$this->assertStringContainsString('SimpleFIN flow', $result->getErrorMessages()[0]);
}
/**
@ -97,8 +101,8 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateConfigurationContract($this->mockConfiguration);
self::assertFalse($result->isValid());
self::assertStringContainsString('SimpleFIN accounts data missing', $result->getErrorMessages()[0]);
$this->assertFalse($result->isValid());
$this->assertStringContainsString('SimpleFIN accounts data missing', $result->getErrorMessages()[0]);
}
/**
@ -116,8 +120,8 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateConfigurationContract($this->mockConfiguration);
self::assertFalse($result->isValid());
self::assertTrue(count($result->getErrors()) >= 4); // Missing 4 required fields
$this->assertFalse($result->isValid());
$this->assertGreaterThanOrEqual(4, count($result->getErrors())); // Missing 4 required fields
}
/**
@ -136,8 +140,8 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateConfigurationContract($config);
self::assertFalse($result->isValid());
self::assertNotEmpty($result->getErrors());
$this->assertFalse($result->isValid());
$this->assertNotEmpty($result->getErrors());
}
/**
@ -154,8 +158,8 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateConfigurationContract($config);
self::assertFalse($result->isValid());
self::assertStringContainsString('New account configuration missing', $result->getErrorMessages()[0]);
$this->assertFalse($result->isValid());
$this->assertStringContainsString('New account configuration missing', $result->getErrorMessages()[0]);
}
/**
@ -178,8 +182,8 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateConfigurationContract($config);
self::assertFalse($result->isValid());
self::assertTrue(count($result->getErrors()) >= 4);
$this->assertFalse($result->isValid());
$this->assertGreaterThanOrEqual(4, count($result->getErrors()));
}
/**
@ -203,14 +207,10 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateConfigurationContract($config);
self::assertFalse($result->isValid());
$this->assertFalse($result->isValid());
$errors = $result->getErrors();
self::assertTrue(
collect($errors)->contains(fn ($error) => str_contains($error['message'], 'Liability type required'))
);
self::assertTrue(
collect($errors)->contains(fn ($error) => str_contains($error['message'], 'Liability direction required'))
);
$this->assertTrue(collect($errors)->contains(fn ($error) => str_contains((string) $error['message'], 'Liability type required')));
$this->assertTrue(collect($errors)->contains(fn ($error) => str_contains((string) $error['message'], 'Liability direction required')));
}
/**
@ -233,8 +233,8 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateFormFieldStructure($validFormData);
self::assertTrue($result->isValid());
self::assertEmpty($result->getErrors());
$this->assertTrue($result->isValid());
$this->assertEmpty($result->getErrors());
}
/**
@ -249,8 +249,8 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateFormFieldStructure($invalidFormData);
self::assertFalse($result->isValid());
self::assertTrue(count($result->getErrors()) >= 3); // Missing/invalid fields
$this->assertFalse($result->isValid());
$this->assertGreaterThanOrEqual(3, count($result->getErrors())); // Missing/invalid fields
}
/**
@ -267,26 +267,26 @@ final class ConfigurationContractValidatorTest extends TestCase
// Test invalid result
$invalidResult = new ValidationResult(false, $errors, $warnings);
self::assertFalse($invalidResult->isValid());
self::assertTrue($invalidResult->hasErrors());
self::assertTrue($invalidResult->hasWarnings());
self::assertSame(['Test error'], $invalidResult->getErrorMessages());
self::assertSame(['Test warning'], $invalidResult->getWarningMessages());
$this->assertFalse($invalidResult->isValid());
$this->assertTrue($invalidResult->hasErrors());
$this->assertTrue($invalidResult->hasWarnings());
$this->assertSame(['Test error'], $invalidResult->getErrorMessages());
$this->assertSame(['Test warning'], $invalidResult->getWarningMessages());
// Test valid result
$validResult = new ValidationResult(true);
self::assertTrue($validResult->isValid());
self::assertFalse($validResult->hasErrors());
self::assertFalse($validResult->hasWarnings());
self::assertEmpty($validResult->getErrors());
self::assertEmpty($validResult->getWarnings());
$this->assertTrue($validResult->isValid());
$this->assertFalse($validResult->hasErrors());
$this->assertFalse($validResult->hasWarnings());
$this->assertEmpty($validResult->getErrors());
$this->assertEmpty($validResult->getWarnings());
// Test toArray
$array = $invalidResult->toArray();
self::assertArrayHasKey('valid', $array);
self::assertArrayHasKey('errors', $array);
self::assertArrayHasKey('warnings', $array);
self::assertFalse($array['valid']);
$this->assertArrayHasKey('valid', $array);
$this->assertArrayHasKey('errors', $array);
$this->assertArrayHasKey('warnings', $array);
$this->assertFalse($array['valid']);
}
/**
@ -310,10 +310,8 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateConfigurationContract($config);
self::assertFalse($result->isValid());
self::assertTrue(
collect($result->getErrors())->contains(fn ($error) => str_contains($error['message'], 'Invalid account role'))
);
$this->assertFalse($result->isValid());
$this->assertTrue(collect($result->getErrors())->contains(fn ($error) => str_contains((string) $error['message'], 'Invalid account role')));
}
/**
@ -326,10 +324,8 @@ final class ConfigurationContractValidatorTest extends TestCase
$result = $this->validator->validateConfigurationContract($this->mockConfiguration);
self::assertFalse($result->isValid());
self::assertTrue(
collect($result->getErrors())->contains(fn ($error) => str_contains($error['message'], 'selected for import but not in account mappings'))
);
$this->assertFalse($result->isValid());
$this->assertTrue(collect($result->getErrors())->contains(fn ($error) => str_contains((string) $error['message'], 'selected for import but not in account mappings')));
}
/**
@ -363,7 +359,7 @@ final class ConfigurationContractValidatorTest extends TestCase
'name' => 'Test Account 1',
'currency' => 'USD',
'balance' => '1000.00',
'balance-date' => time(),
'balance-date' => Carbon::now()->getTimestamp(),
'org' => ['name' => 'Test Bank'],
'extra' => [],
],
@ -372,7 +368,7 @@ final class ConfigurationContractValidatorTest extends TestCase
'name' => 'Test Account 2',
'currency' => 'USD',
'balance' => '2000.00',
'balance-date' => time(),
'balance-date' => Carbon::now()->getTimestamp(),
'org' => ['name' => 'Test Bank'],
'extra' => [],
],

Loading…
Cancel
Save