whisper-money/tests/Feature
Víctor Falcón 690be20f21
feat(open-banking): add update credentials flow for API-key connections (#154)
## Why

### Problem

When API tokens for Indexa Capital, Binance, or Bitpanda expire or are
revoked, syncs fail silently with 401/403 errors. Users have no way to
replace their credentials without disconnecting and recreating the
entire connection (losing account mappings and history).

## What

### Changes

- **Auth failure email notification**: on the final retry attempt (3rd
of 3), if a sync job fails with 401/403 for an API-key provider, an
email is sent to the user with a link to the connections settings page
- **Update credentials endpoint**: `PATCH
/settings/connections/{connection}/credentials` validates new
credentials against the provider API before saving, then triggers a sync
- **Update credentials dialog**: provider-specific form (API token for
Indexa/Bitpanda, API key + secret for Binance) shown via an "Update
Credentials" button in the error banner and dropdown menu
- **Mailable**: `BankingConnectionAuthFailedEmail` follows existing
patterns (queued, rate-limited, Markdown template)
- **Form request**: `UpdateConnectionCredentialsRequest` with dynamic
validation rules per provider and authorization check

### Files changed

| File | Change |
|------|--------|
| `app/Jobs/SyncBankingConnectionJob.php` | Send auth failed email on
final attempt for auth errors on API-key providers |
| `app/Mail/BankingConnectionAuthFailedEmail.php` | New queued mailable
|
| `resources/views/mail/banking-connection-auth-failed.blade.php` |
Email template |
| `app/Http/Controllers/OpenBanking/ConnectionController.php` |
`updateCredentials()` action with provider credential validation |
| `app/Http/Requests/OpenBanking/UpdateConnectionCredentialsRequest.php`
| Dynamic validation per provider |
| `routes/settings.php` | PATCH route for credential updates |
| `resources/js/components/open-banking/update-credentials-dialog.tsx` |
Dialog with provider-specific fields |
| `resources/js/pages/settings/connections.tsx` | Update Credentials
button in error state and dropdown |

## Verification

### Tests

- **12 new tests** across 2 test files, all passing:
- `SyncBankingConnectionJobTest`: 5 tests covering email sent on final
retry (Indexa 401, Binance 403), not sent before final retry, not sent
for non-auth errors, not sent for EnableBanking
- `ConnectionControllerTest`: 7 tests covering valid credential update
for each provider, invalid credentials, EnableBanking rejection,
authorization, feature flag, required field validation
- Full OpenBanking test suite: **145 tests, 473 assertions** passing
2026-02-25 13:41:24 +01:00
..
Api Remove encryption from bank account names (#104) 2026-02-09 14:15:26 +01:00
Auth fix: Disable email verification on dev/local 2026-02-07 17:52:53 +01:00
Console Remove encryption from browser tests and demo user (#129) 2026-02-17 11:45:27 +01:00
Jobs/Drip Add subscription cancellation email with manual trigger command (#47) 2025-12-30 20:32:44 +01:00
Listeners chore: Sync users to Resend after email verification (#98) 2026-02-03 22:59:28 +01:00
Onboarding User Onboarding Flow (#23) 2025-12-12 13:06:08 +01:00
OpenBanking feat(open-banking): add update credentials flow for API-key connections (#154) 2026-02-25 13:41:24 +01:00
Settings Remove encryption from bank account names (#104) 2026-02-09 14:15:26 +01:00
Sync refactor: Simplify transaction endpoints architecture (#76) 2026-01-25 16:15:17 +01:00
AccountBalanceControllerTest.php feat: investment benefits — show gains/losses on investment accounts (#140) 2026-02-23 13:59:10 +01:00
AccountControllerTest.php perf(accounts): replace client-side API calls with Inertia deferred prop (#144) 2026-02-23 20:08:41 +01:00
AutomationRuleEvaluationTest.php feat: Apply automation rules to bank-synced transactions (#112) 2026-02-12 14:20:55 +01:00
AutomationRuleTest.php chore: Simplify IndexedDB sync by moving to Inertia shared props (#63) 2026-01-19 19:15:26 +01:00
BalanceLookupTest.php feat: investment benefits — show gains/losses on investment accounts (#140) 2026-02-23 13:59:10 +01:00
BudgetHistoricalAssignmentTest.php Remove budgets feature flag (#108) 2026-02-12 09:58:01 +01:00
BudgetPeriodDateTest.php Remove budgets feature flag (#108) 2026-02-12 09:58:01 +01:00
BudgetTest.php Remove budgets feature flag (#108) 2026-02-12 09:58:01 +01:00
BudgetTransactionServiceTest.php fix(budgets): handle refunds correctly in budget spending calculations (#152) 2026-02-24 21:12:36 +01:00
BulkUpdateTransactionsTest.php refactor: Simplify transaction endpoints architecture (#76) 2026-01-25 16:15:17 +01:00
CashflowAnalyticsTest.php test: Fix Carbon month overflow in date calculations (#87) 2026-02-01 11:33:09 +01:00
CurrencyConversionServiceTest.php feat: Add Binance integration (#131) 2026-02-18 15:23:46 +01:00
DashboardAnalyticsTest.php feat: enable invested amount tracking for savings accounts (#142) 2026-02-23 17:19:33 +01:00
DashboardTest.php User Onboarding Flow (#23) 2025-12-12 13:06:08 +01:00
DecryptTransactionsTest.php feat: Decrypt encrypted transactions on key unlock (#123) 2026-02-16 10:37:43 +01:00
DeleteUserCommandTest.php test: Optimize tests performance 2026-01-17 19:20:23 +01:00
DemoAccountRestrictionsTest.php test: Optimize DemoAccountRestrictionsTest to run under 10s 2026-01-28 21:27:27 +01:00
EncryptionTest.php User Onboarding Flow (#23) 2025-12-12 13:06:08 +01:00
ExampleTest.php Install Pest 2025-11-07 12:01:58 +00:00
ExchangeRateServiceTest.php feat: Add multi-currency conversion for net worth charts (#138) 2026-02-20 10:45:23 +01:00
IdorVulnerabilityTest.php refactor: Simplify transaction endpoints architecture (#76) 2026-01-25 16:15:17 +01:00
ImportDataTest.php fix: Apply automation rule labels on transaction creation and import (#79) 2026-01-27 11:11:29 +01:00
InertiaSharedDataTest.php SEO landing page 2025-11-25 11:33:11 +01:00
LabelTest.php feat: add transaction labels feature (#24) 2025-12-13 13:02:19 +01:00
PlaintextTransactionsTest.php Remove plaintext-transactions feature flag & E2E references (#116) 2026-02-13 11:10:21 +01:00
PwaTest.php feat: Improve PWA standalone experience and redirect to dashboard (#90) 2026-02-01 11:33:10 +01:00
ResendSyncCommandTest.php feat: Sync new users to Resend contacts (#85) 2026-01-28 21:25:58 +01:00
SitemapTest.php User Onboarding Flow (#23) 2025-12-12 13:06:08 +01:00
SubscriptionTest.php User Onboarding Flow (#23) 2025-12-12 13:06:08 +01:00
SyncBankingConnectionsCommandTest.php perf: make banking syncs incremental on subsequent runs (#141) 2026-02-23 15:10:40 +01:00
TransactionFilterTest.php Move transaction filtering from client-side to server-side (#126) 2026-02-16 12:49:04 +01:00
TransactionTest.php Move transaction filtering from client-side to server-side (#126) 2026-02-16 12:49:04 +01:00
UserLeadTest.php Add User Lead functionality and tests 2025-11-25 10:31:25 +01:00