create(); $household = $user->currentHousehold; $revenu = $household->categories()->create(['name' => 'Salaire', 'type' => 'revenu', 'position' => 1]); $depense = $household->categories()->create(['name' => 'Loyer', 'type' => 'depense', 'position' => 1]); $epargne = $household->categories()->create(['name' => 'Vacances', 'type' => 'epargne', 'position' => 1]); $household->transactions()->create([ 'category_id' => $revenu->id, 'user_id' => $user->id, 'date' => '2026-01-01', 'date_effective' => '2026-01-01', 'amount' => 2000, ]); $household->transactions()->create([ 'category_id' => $depense->id, 'user_id' => $user->id, 'date' => '2026-01-02', 'date_effective' => '2026-01-02', 'amount' => 1200, ]); $household->transactions()->create([ 'category_id' => $epargne->id, 'user_id' => $user->id, 'date' => '2026-01-03', 'date_effective' => '2026-01-03', 'amount' => 300, ]); $component = Livewire::actingAs($user)->test(Index::class) ->set('year', 2026) ->set('period', 'year'); $flows = $component->viewData('flows'); expect($flows)->toHaveCount(3); // Loyer, Vacances, Non affecté expect($flows->firstWhere('to', 'Loyer')['flow'])->toBe(1200.0); expect($flows->firstWhere('to', 'Vacances')['flow'])->toBe(300.0); expect($flows->firstWhere('to', 'Non affecté')['flow'])->toBe(500.0); expect($component->viewData('totalRevenue'))->toBe(2000.0); expect($component->viewData('hasData'))->toBeTrue(); }); it('omits the unallocated flow when all revenue is spent or saved', function (): void { $user = User::factory()->create(); $household = $user->currentHousehold; $revenu = $household->categories()->create(['name' => 'Salaire', 'type' => 'revenu', 'position' => 1]); $depense = $household->categories()->create(['name' => 'Loyer', 'type' => 'depense', 'position' => 1]); $household->transactions()->create([ 'category_id' => $revenu->id, 'user_id' => $user->id, 'date' => '2026-01-01', 'date_effective' => '2026-01-01', 'amount' => 1000, ]); $household->transactions()->create([ 'category_id' => $depense->id, 'user_id' => $user->id, 'date' => '2026-01-02', 'date_effective' => '2026-01-02', 'amount' => 1000, ]); $component = Livewire::actingAs($user)->test(Index::class) ->set('year', 2026) ->set('period', 'year'); $flows = $component->viewData('flows'); expect($flows)->toHaveCount(1); expect($flows->firstWhere('to', 'Non affecté'))->toBeNull(); }); it('shows no data state when there is no tracked revenue', function (): void { $user = User::factory()->create(); $component = Livewire::actingAs($user)->test(Index::class); expect($component->viewData('hasData'))->toBeFalse(); expect($component->viewData('flows'))->toHaveCount(0); }); it('does not leak another household categories into the flows', function (): void { $ownerA = User::factory()->create(); $ownerB = User::factory()->create(); $revenuA = $ownerA->currentHousehold->categories()->create(['name' => 'Salaire A', 'type' => 'revenu', 'position' => 1]); $depenseB = $ownerB->currentHousehold->categories()->create(['name' => 'Loyer B', 'type' => 'depense', 'position' => 1]); $ownerA->currentHousehold->transactions()->create([ 'category_id' => $revenuA->id, 'user_id' => $ownerA->id, 'date' => now(), 'date_effective' => now(), 'amount' => 1000, ]); $component = Livewire::actingAs($ownerA)->test(Index::class); expect($component->viewData('flows')->pluck('to'))->not->toContain('Loyer B'); });