229 lines
7.5 KiB
PHP
229 lines
7.5 KiB
PHP
<?php
|
|
|
|
use App\Enums\AccountType;
|
|
use App\Models\User;
|
|
|
|
beforeEach(function () {
|
|
config(['app.demo' => [
|
|
'email' => 'demo@whisper.money',
|
|
'password' => 'demo',
|
|
'encryption_key' => 'demo',
|
|
]]);
|
|
});
|
|
|
|
test('demo:reset creates demo user if not exists', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
expect(User::where('email', 'demo@whisper.money')->exists())->toBeTrue();
|
|
});
|
|
|
|
test('demo:reset creates 5 accounts', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
expect($user->accounts()->count())->toBe(6);
|
|
|
|
$types = $user->accounts->pluck('type')->toArray();
|
|
expect($types)->toContain(AccountType::Checking);
|
|
expect($types)->toContain(AccountType::Savings);
|
|
expect($types)->toContain(AccountType::Retirement);
|
|
expect($types)->toContain(AccountType::Investment);
|
|
});
|
|
|
|
test('demo:reset creates 12 months of transactions per account', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
|
|
foreach ($user->accounts as $account) {
|
|
if ($account->type === AccountType::Investment || $account->type === AccountType::Retirement) {
|
|
continue;
|
|
}
|
|
|
|
expect($account->transactions()->count())->toBeGreaterThan(100);
|
|
}
|
|
|
|
expect($user->transactions()->count())->toBeGreaterThan(2000);
|
|
});
|
|
|
|
test('demo:reset creates 3 labels', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
expect($user->labels()->count())->toBe(3);
|
|
});
|
|
|
|
test('demo:reset creates 5 automation rules', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
expect($user->automationRules()->count())->toBe(5);
|
|
});
|
|
|
|
test('demo:reset creates default categories', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
expect($user->categories()->count())->toBe(63);
|
|
});
|
|
|
|
test('demo:reset deletes existing data before recreating', function () {
|
|
$this->artisan('demo:reset')->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
$originalAccountIds = $user->accounts->pluck('id')->toArray();
|
|
$originalTransactionCount = $user->transactions()->count();
|
|
|
|
$this->artisan('demo:reset')->assertSuccessful();
|
|
|
|
$user->refresh();
|
|
$newAccountIds = $user->accounts->pluck('id')->toArray();
|
|
|
|
expect(array_intersect($originalAccountIds, $newAccountIds))->toBeEmpty();
|
|
|
|
expect($user->accounts()->count())->toBe(6);
|
|
expect($user->transactions()->count())->toBeGreaterThan(2000);
|
|
});
|
|
|
|
test('demo:reset fails if demo email is not configured', function () {
|
|
config(['app.demo.email' => null]);
|
|
|
|
$this->artisan('demo:reset')
|
|
->assertFailed();
|
|
});
|
|
|
|
test('demo:reset assigns labels to transactions based on percentage', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
|
|
$transactionsWithLabels = $user->transactions()->whereHas('labels')->count();
|
|
expect($transactionsWithLabels)->toBeGreaterThan(0);
|
|
});
|
|
|
|
test('demo:reset creates an active subscription', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
|
|
expect($user->subscriptions()->count())->toBe(1);
|
|
expect($user->subscribed('default'))->toBeTrue();
|
|
expect($user->hasProPlan())->toBeTrue();
|
|
});
|
|
|
|
test('demo:reset creates 12 months of balance history for all accounts', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
|
|
foreach ($user->accounts as $account) {
|
|
expect($account->balances()->count())->toBe(13);
|
|
expect($account->balances()->first()->balance)->toBeGreaterThan(0);
|
|
|
|
$balances = $account->balances()->pluck('balance')->toArray();
|
|
foreach ($balances as $balance) {
|
|
$cents = $balance % 100;
|
|
expect($cents)->toBeGreaterThanOrEqual(0);
|
|
}
|
|
}
|
|
});
|
|
|
|
test('demo:reset creates balance history with at least 5% growth over the year', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
$minGrowthPercentage = 0.05;
|
|
|
|
foreach ($user->accounts as $account) {
|
|
$balances = $account->balances()
|
|
->orderBy('balance_date', 'desc')
|
|
->pluck('balance')
|
|
->toArray();
|
|
|
|
$currentBalance = $balances[0];
|
|
$oldestBalance = $balances[12];
|
|
|
|
$growth = ($currentBalance - $oldestBalance) / $oldestBalance;
|
|
expect($growth)->toBeGreaterThanOrEqual($minGrowthPercentage);
|
|
}
|
|
});
|
|
|
|
test('demo:reset assigns categories to all transactions', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
|
|
$transactionsWithoutCategory = $user->transactions()->whereNull('category_id')->count();
|
|
expect($transactionsWithoutCategory)->toBe(0);
|
|
});
|
|
|
|
test('demo:reset assigns accounts to all transactions', function () {
|
|
$this->artisan('demo:reset')
|
|
->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
|
|
$transactionsWithoutAccount = $user->transactions()->whereNull('account_id')->count();
|
|
expect($transactionsWithoutAccount)->toBe(0);
|
|
});
|
|
|
|
test('demo:reset creates encrypted message that can be decrypted', function () {
|
|
$this->artisan('demo:reset')->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
$encryptedMessage = $user->encryptedMessage;
|
|
|
|
expect($encryptedMessage)->not->toBeNull();
|
|
expect($encryptedMessage->encrypted_content)->not->toBeEmpty();
|
|
expect($encryptedMessage->iv)->not->toBeEmpty();
|
|
|
|
$service = new \App\Services\Demo\DemoEncryptionService;
|
|
$key = $service->deriveKey('demo', $user->encryption_salt);
|
|
|
|
$decrypted = $service->decrypt($encryptedMessage->encrypted_content, $key, $encryptedMessage->iv);
|
|
expect($decrypted)->toBe('Hello, world');
|
|
});
|
|
|
|
test('demo:reset encrypts account names correctly', function () {
|
|
$this->artisan('demo:reset')->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
$service = new \App\Services\Demo\DemoEncryptionService;
|
|
$key = $service->deriveKey('demo', $user->encryption_salt);
|
|
|
|
$account = $user->accounts()->first();
|
|
$decryptedName = $service->decrypt($account->name, $key, $account->name_iv);
|
|
|
|
expect($decryptedName)->toBeIn([
|
|
'Primary Checking',
|
|
'Joint Checking',
|
|
'Emergency Fund',
|
|
'401(k) Retirement',
|
|
'Brokerage Account',
|
|
]);
|
|
});
|
|
|
|
test('demo:reset encrypts transaction descriptions correctly', function () {
|
|
$this->artisan('demo:reset')->assertSuccessful();
|
|
|
|
$user = User::where('email', 'demo@whisper.money')->first();
|
|
$service = new \App\Services\Demo\DemoEncryptionService;
|
|
$key = $service->deriveKey('demo', $user->encryption_salt);
|
|
|
|
$transaction = $user->transactions()->first();
|
|
$decryptedDescription = $service->decrypt($transaction->description, $key, $transaction->description_iv);
|
|
|
|
expect($decryptedDescription)->not->toBeEmpty();
|
|
});
|