whisper-money/tests/Feature/OpenBanking
Víctor Falcón 845f51abb5
refactor(open-banking): extract shared connect-controller flow into a base class (#639)
## Why

The five API-key OpenBanking "connect" controllers — Binance, Bitpanda,
Coinbase, Indexa Capital and Interactive Brokers — each carried a
~60-line `store()` that was near-identical: subscription gate →
credential validation → `Bank::firstOrCreate` → create the
`BankingConnection` (Pending) → update it to `AwaitingMapping` with
pending accounts → auto-map during onboarding or redirect to mapping.
Any change to that flow, or a bug in it, had to be made five times.

## What

Extract the shared flow into a small class hierarchy, so each controller
declares only what actually varies per provider.

- **`OpenBankingConnectController`** (abstract) owns the whole flow in a
`connect()` template method, with per-provider extension points:
`provider()`, `providerName()`, `bankLogo()`, `aspspCountry()`,
`fetchProviderData()`, `credentialErrorMessage()`,
`buildPendingAccounts()`, and an optional `emptyProviderDataMessage()`
guard.
- **`CryptoPortfolioConnectController`** (abstract, extends the above)
implements the two hooks the crypto providers share: `aspspCountry()`
(from the request) and the single "Crypto Portfolio"
`buildPendingAccounts()` (uid derived from the provider enum value, so
the generated uids are unchanged).
- The five controllers shrink to their genuine differences (client,
names, logo, error copy, and — for IB — the Flex error mapping and
empty-statement guard).

Net **−110 lines** across the five `store()` methods, and the connection
lifecycle now lives in one place.

## Behavior

No functional change. The credential-failure warning log is now a single
structured message with a `provider` key instead of five free-text
variants (the only observable difference; HTTP responses are
byte-for-byte identical). Verified by the full suite: **1869 passing, 0
failing** (`--exclude-testsuite=Browser`); `pint --test`, `format` and
`lint` clean.

## Review-driven follow-up commits

Two review agents (architecture/duplication/coverage, and
behavior/regressions) ran against the first commit. Applied, each as its
own commit:

- Finished the crypto dedup via the intermediate base (the reviewers
flagged the still-duplicated crypto hooks).
- Dropped the over-engineered per-provider
`validationFailureLogMessage()` hook in favor of a structured base log.
- Added the missing test for the Interactive Brokers empty-statement
guard (the only conditional hook, previously unexercised): asserts 422 +
NAV-section message, no connection row, and no warning logged.

## Deliberately out of scope

- **Wise** is left as-is: it builds pending accounts mid-flow (needs the
client), creates the connection in one step, and has its own
empty-portfolio guard — it does not fit this template.
- **Pre-existing** (not introduced here, noted by review):
`Bank::firstOrCreate` returns an existing bank without refreshing its
logo, so `aspsp_logo` can copy a stale/null value. Worth a separate fix.
2026-07-04 20:24:54 +02:00
..
AccountMappingTest.php fix(open-banking): stop storing the XXX no-currency placeholder on accounts (#602) 2026-06-27 16:01:21 +00:00
AuthorizationControllerTest.php feat(open-banking): finalize bank connection without a session via state token (#498) 2026-06-06 12:12:07 +02: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 feat(settings): centralize currency options and split profile/account support (#256) 2026-04-02 19:23:10 +02:00
BinanceControllerTest.php feat(open-banking): remove feature flag gating (#297) 2026-04-17 10:20:05 +02:00
BitpandaBalanceSyncTest.php feat(settings): centralize currency options and split profile/account support (#256) 2026-04-02 19:23:10 +02:00
BitpandaControllerTest.php feat(open-banking): remove feature flag gating (#297) 2026-04-17 10:20:05 +02:00
CoinbaseBalanceSyncTest.php Backfill Coinbase monthly history (#395) 2026-05-14 10:52:46 +01: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
EnableBankingProviderTest.php fix(banking): skip inaccessible EnableBanking accounts instead of failing the connection (#559) 2026-06-19 08:59:05 +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 feat(open-banking): finalize bank connection without a session via state token (#498) 2026-06-06 12:12:07 +02:00
SyncBankingConnectionJobTest.php feat(banking): add Interactive Brokers sync via Flex Web Service (#581) 2026-06-23 11:39:24 +02:00
SyncBinanceHistoricalBalancesJobTest.php chore: upgrade Laravel 12 to 13 (#242) 2026-03-25 12:56:33 +00:00
SyncRetryAndLoggingTest.php fix(banking): only log sync failures once the connection gives up (#603) 2026-06-27 16:04:36 +00:00
TransactionSyncServiceTest.php perf(banking): kill per-transaction dedup N+1 in bank sync (PHP-LARAVEL-3Y) (#621) 2026-07-02 13:34:29 +00: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