test: expand browser coverage for account types and transactions (#279)
## Summary - add browser coverage for manual credit card, investment, retirement, and other account creation flows - replace placeholder transaction search coverage with real filter assertions and add edit/delete transaction browser tests - keep the new coverage focused on the existing account and transaction browser test files ## Testing - vendor/bin/pint --dirty --format agent - php artisan test --compact tests/Browser/BankAccountsTest.php tests/Browser/TransactionsTest.php
This commit is contained in:
parent
a7c1bd35ef
commit
db359a0572
|
|
@ -9,6 +9,35 @@ use Laravel\Pennant\Feature;
|
|||
|
||||
use function Pest\Laravel\actingAs;
|
||||
|
||||
function createManualAccountTypeViaUi($page, string $displayName, string $bankName, string $type, string $currency = 'EUR', ?string $balance = null): void
|
||||
{
|
||||
$page->assertSee('Bank accounts')
|
||||
->click('Create Account')
|
||||
->wait(0.5)
|
||||
->fill('#display_name', $displayName)
|
||||
->click('[data-testid="bank-select"]')
|
||||
->wait(0.5)
|
||||
->fill('input[placeholder="Search bank..."]', $bankName)
|
||||
->wait(0.5)
|
||||
->click($bankName)
|
||||
->click('button[name="type"]')
|
||||
->wait(0.5)
|
||||
->click("[role=\"option\"]:has-text(\"{$type}\")")
|
||||
->wait(0.3)
|
||||
->click('button[name="currency_code"]')
|
||||
->wait(0.5)
|
||||
->click("[role=\"option\"]:has-text(\"{$currency}\")")
|
||||
->wait(0.3);
|
||||
|
||||
if ($balance !== null) {
|
||||
$page->fill('#balance', $balance);
|
||||
}
|
||||
|
||||
$page->click('[data-testid="submit-account"]')
|
||||
->wait(2)
|
||||
->assertNoJavascriptErrors();
|
||||
}
|
||||
|
||||
it('can view bank accounts page', function () {
|
||||
$user = User::factory()->onboarded()->create();
|
||||
|
||||
|
|
@ -144,6 +173,43 @@ it('can create a loan account with balance and loan details', function () {
|
|||
expect($loan->loanDetail->original_amount)->toBe(25000000);
|
||||
});
|
||||
|
||||
it('can create the remaining manual account types', function (string $typeLabel, AccountType $type, ?string $balance) {
|
||||
$user = User::factory()->onboarded()->create();
|
||||
$bank = Bank::factory()->create(['name' => 'Coverage Bank', 'logo' => null]);
|
||||
|
||||
actingAs($user);
|
||||
|
||||
$page = visit('/settings/accounts');
|
||||
|
||||
createManualAccountTypeViaUi(
|
||||
$page,
|
||||
"{$typeLabel} Coverage Account",
|
||||
'Coverage Bank',
|
||||
$typeLabel,
|
||||
'EUR',
|
||||
$balance,
|
||||
);
|
||||
|
||||
$account = Account::query()
|
||||
->where('user_id', $user->id)
|
||||
->where('type', $type)
|
||||
->first();
|
||||
|
||||
expect($account)->not->toBeNull();
|
||||
expect($account->currency_code)->toBe('EUR');
|
||||
|
||||
if ($balance === null) {
|
||||
expect($account->balances)->toHaveCount(0);
|
||||
} else {
|
||||
expect($account->balances)->toHaveCount(1);
|
||||
}
|
||||
})->with([
|
||||
'credit card' => ['Credit Card', AccountType::CreditCard, null],
|
||||
'investment' => ['Investment', AccountType::Investment, '125000'],
|
||||
'retirement' => ['Retirement / Pension', AccountType::Retirement, '250000'],
|
||||
'others' => ['Others', AccountType::Others, null],
|
||||
]);
|
||||
|
||||
it('can create a real estate account linked to an existing loan', function () {
|
||||
$user = User::factory()->onboarded()->create();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
use App\Models\Account;
|
||||
use App\Models\Bank;
|
||||
use App\Models\Category;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User;
|
||||
|
||||
use function Pest\Laravel\actingAs;
|
||||
|
|
@ -101,12 +102,141 @@ it('shows empty state when no transactions exist', function () {
|
|||
|
||||
it('can filter transactions by search text', function () {
|
||||
$user = User::factory()->onboarded()->create();
|
||||
$bank = Bank::factory()->create(['name' => 'Filter Bank']);
|
||||
$category = Category::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'name' => 'Groceries',
|
||||
]);
|
||||
$account = Account::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'bank_id' => $bank->id,
|
||||
'name' => 'Daily Account',
|
||||
'currency_code' => 'USD',
|
||||
'type' => 'checking',
|
||||
]);
|
||||
|
||||
Transaction::factory()->plaintext()->create([
|
||||
'user_id' => $user->id,
|
||||
'account_id' => $account->id,
|
||||
'category_id' => $category->id,
|
||||
'description' => 'Weekly groceries',
|
||||
'amount' => -4500,
|
||||
]);
|
||||
|
||||
Transaction::factory()->plaintext()->create([
|
||||
'user_id' => $user->id,
|
||||
'account_id' => $account->id,
|
||||
'category_id' => $category->id,
|
||||
'description' => 'Electric bill',
|
||||
'amount' => -8000,
|
||||
]);
|
||||
|
||||
actingAs($user);
|
||||
|
||||
$page = visit('/transactions');
|
||||
|
||||
$page->assertSee('Transactions')
|
||||
->wait(2)
|
||||
->waitForText('Weekly groceries', 10)
|
||||
->assertSee('Electric bill')
|
||||
->fill('input[placeholder="Search description or notes..."]', 'groceries')
|
||||
->wait(1)
|
||||
->assertSee('Weekly groceries')
|
||||
->assertDontSee('Electric bill')
|
||||
->assertNoJavascriptErrors();
|
||||
});
|
||||
|
||||
it('can edit an existing transaction from the list', function () {
|
||||
$user = User::factory()->onboarded()->create();
|
||||
$bank = Bank::factory()->create(['name' => 'Edit Tx Bank']);
|
||||
$category = Category::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'name' => 'Groceries',
|
||||
]);
|
||||
$replacementCategory = Category::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'name' => 'Dining Out',
|
||||
]);
|
||||
$account = Account::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'bank_id' => $bank->id,
|
||||
'name' => 'Editing Account',
|
||||
'currency_code' => 'USD',
|
||||
'type' => 'checking',
|
||||
]);
|
||||
|
||||
$transaction = Transaction::factory()->plaintext()->create([
|
||||
'user_id' => $user->id,
|
||||
'account_id' => $account->id,
|
||||
'category_id' => $category->id,
|
||||
'description' => 'Original transaction note',
|
||||
'amount' => -3200,
|
||||
'notes' => 'Original note',
|
||||
'source' => 'manually_created',
|
||||
]);
|
||||
|
||||
actingAs($user);
|
||||
|
||||
$page = visit('/transactions');
|
||||
|
||||
$page->assertSee('Transactions')
|
||||
->waitForText('Original transaction note', 10)
|
||||
->click('Original transaction note')
|
||||
->wait(1)
|
||||
->assertSee('Edit Transaction')
|
||||
->fill('#description', 'Updated dinner transaction')
|
||||
->click('[data-testid="category-select"]')
|
||||
->wait(1)
|
||||
->click('Dining Out')
|
||||
->fill('#notes', 'Updated note for browser test')
|
||||
->click('[data-testid="submit-transaction"]')
|
||||
->wait(3)
|
||||
->waitForText('Updated dinner transaction', 10)
|
||||
->assertSee('Dining Out')
|
||||
->assertNoJavascriptErrors();
|
||||
|
||||
$updatedTransaction = $transaction->fresh();
|
||||
|
||||
expect($updatedTransaction->description)->toBe('Updated dinner transaction');
|
||||
expect($updatedTransaction->notes)->toBe('Updated note for browser test');
|
||||
expect($updatedTransaction->category_id)->toBe($replacementCategory->id);
|
||||
});
|
||||
|
||||
it('can delete a transaction from the actions menu', function () {
|
||||
$user = User::factory()->onboarded()->create();
|
||||
$bank = Bank::factory()->create(['name' => 'Delete Tx Bank']);
|
||||
$category = Category::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'name' => 'Household',
|
||||
]);
|
||||
$account = Account::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'bank_id' => $bank->id,
|
||||
'name' => 'Delete Account',
|
||||
'currency_code' => 'USD',
|
||||
'type' => 'checking',
|
||||
]);
|
||||
|
||||
$transaction = Transaction::factory()->plaintext()->create([
|
||||
'user_id' => $user->id,
|
||||
'account_id' => $account->id,
|
||||
'category_id' => $category->id,
|
||||
'description' => 'Disposable transaction',
|
||||
'amount' => -1500,
|
||||
]);
|
||||
|
||||
actingAs($user);
|
||||
|
||||
$page = visit('/transactions');
|
||||
|
||||
$page->assertSee('Transactions')
|
||||
->waitForText('Disposable transaction', 10)
|
||||
->click('button:has-text("Open menu")')
|
||||
->wait(0.5)
|
||||
->click('Delete')
|
||||
->wait(0.5)
|
||||
->assertSee('Delete Transaction')
|
||||
->click('button:has-text("Delete")')
|
||||
->wait(3)
|
||||
->assertDontSee('Disposable transaction')
|
||||
->assertNoJavascriptErrors();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue