whisper-money/tests/Feature/OpenBanking
Víctor Falcón 271b659260 fix(banking): give every account its turn when the bank refuses one of them
`EnableBankingSyncer::sync` wrapped the transaction call but only caught
`InaccessibleBankAccountException` and `WrongTransactionsPeriodException`. A
`TransientBankingProviderException` — what EnableBanking's HTTP 400
`{"error":"ASPSP_ERROR"}` becomes, i.e. "the bank's connector failed" — propagated
out and abandoned the loop, so every account behind the failing one was skipped
along with its balance, cycle after cycle.

Verified in production on a CaixaBank connection with three accounts: account 1
kept importing transactions until 2026-07-18 (618 rows, 231 balance days), while
accounts 2 and 3 sat at zero transactions with their balances frozen at
2026-06-12 — the date of the last complete run. Five weeks of it. That user has
since deleted their account, so this ships as a latent fix rather than a rescue;
84 of the 260 live EnableBanking connections have two or more accounts.

Deliberately conservative about everything else. The failure is still raised once
every account has had its turn, so the connection keeps its Error state, its
retries and its unset `last_synced_at` exactly as before. Recording a partial run
as a success would have shown an Active badge and a fresh timestamp over an
account that had stopped updating, and nothing in the product distinguishes a
stale account from a fresh one — a quieter dead end than the one being fixed. It
would also have stamped `bank_transactions_email_cutoff_at` and consumed the
connection-level first sync, permanently losing the failing account's derived
balance history and reporting its eventual backfill as "new transactions today".

A provider that never answered is rethrown immediately instead: `statusCode` is
null only on the `ConnectionException` path, and carrying on there would spend the
client's timeout per account against the job's 120s — a 26-account connection
already takes 62s when everything works.
2026-08-13 10:13:56 +02:00
..
AccountMappingTest.php fix(open-banking): unblock account mapping when the bank reports accounts without a uid (#746) 2026-08-09 18:41:35 +02:00
AuthorizationControllerTest.php refactor(open-banking): bring the authorization callback back under the complexity threshold (#784) 2026-08-12 09:47:22 +00:00
BalanceSyncServiceTest.php Batch historical balance writes (#356) 2026-05-05 15:26:28 +01:00
BankingConnectionSyncerFactoryTest.php feat(banking): add Interactive Brokers sync via Flex Web Service (#581) 2026-06-23 11:39:24 +02:00
BinanceBalanceSyncTest.php fix(binance): value past days from Binance's own snapshot total (#763) 2026-08-11 11:04:06 +00:00
BinanceControllerTest.php feat(open-banking): remove feature flag gating (#297) 2026-04-17 10:20:05 +02:00
BitpandaBalanceSyncTest.php fix(banking): stop crypto holdings quoted only in USD from vanishing from the balance (#759) 2026-08-11 02:56:03 +00:00
BitpandaControllerTest.php feat(open-banking): remove feature flag gating (#297) 2026-04-17 10:20:05 +02:00
CoinbaseBalanceSyncTest.php fix(coinbase): stop one unlisted stablecoin from unpricing the whole portfolio (#761) 2026-08-11 08:24:14 +00:00
CoinbaseControllerTest.php feat: Coinbase banking integration (#388) 2026-05-13 19:53:30 +02:00
ConnectionAccountTest.php feat(open-banking): enable manage bank accounts for everyone (#572) 2026-06-20 17:35:43 +00:00
ConnectionControllerTest.php feat(banking): let Wise credentials be updated (#588) 2026-06-23 09:54:31 +00:00
DailyEmailTransactionsIndexTest.php perf(db): index transactions for the daily synced-email slow query (PHP-LARAVEL-3X) (#622) 2026-07-02 15:51:15 +02:00
EnableBankingPartialAccountFailureTest.php fix(banking): give every account its turn when the bank refuses one of them 2026-08-13 10:13:56 +02:00
EnableBankingProviderTest.php fix(banking): stop unclassified bank responses from silently killing a connection (#742) 2026-08-09 17:26:34 +02:00
IndexaCapitalBalanceSyncTest.php fix(banking): treat Indexa Capital performance 404 as empty data (#386) 2026-05-13 09:34:28 +01:00
IndexaCapitalControllerTest.php feat(open-banking): remove feature flag gating (#297) 2026-04-17 10:20:05 +02:00
InstitutionControllerTest.php feat(open-banking): remove feature flag gating (#297) 2026-04-17 10:20:05 +02:00
InteractiveBrokersBalanceSyncTest.php feat(banking): add Interactive Brokers sync via Flex Web Service (#581) 2026-06-23 11:39:24 +02:00
InteractiveBrokersControllerTest.php refactor(open-banking): extract shared connect-controller flow into a base class (#639) 2026-07-04 20:24:54 +02:00
OpenBankingFeatureFlagTest.php refactor: remove HIDE_AUTH_BUTTONS launch gate and waitlist apparatus (#717) 2026-07-22 08:51:48 +02:00
SyncBankingConnectionJobTest.php fix(banking): stop bank connections from silently dropping out of scheduled syncing (#782) 2026-08-12 11:32:36 +02:00
SyncBinanceHistoricalBalancesJobTest.php chore: upgrade Laravel 12 to 13 (#242) 2026-03-25 12:56:33 +00:00
SyncRetryAndLoggingTest.php fix(banking): stop bank connections from silently dropping out of scheduled syncing (#782) 2026-08-12 11:32:36 +02:00
TransactionSyncServiceTest.php feat(transactions): allow manual transactions on bank-connected accounts (#747) 2026-08-10 05:32:40 +02:00
WiseBalanceSyncTest.php feat: add Wise open banking integration with balance sync (#525) 2026-06-16 13:23:25 +00:00
WiseControllerTest.php feat: add Wise open banking integration with balance sync (#525) 2026-06-16 13:23:25 +00:00
WisePaginationTest.php fix(wise): send the pagination cursor under the name Wise reads (#788) 2026-08-12 11:30:37 +00:00
WiseSyncBudgetTest.php fix(wise): send the pagination cursor under the name Wise reads (#788) 2026-08-12 11:30:37 +00:00
WiseTransientErrorTest.php fix(banking): stop Wise outages from silently parking a bank connection (#757) 2026-08-10 16:40:09 +02:00