individual()->create(); $this->actingAs($user) ->get(route('client.dashboard')) ->assertOk(); }); test('company client can view dashboard', function () { $user = User::factory()->company()->create(); $this->actingAs($user) ->get(route('client.dashboard')) ->assertOk(); }); test('unauthenticated user cannot access dashboard', function () { $this->get(route('client.dashboard')) ->assertRedirect(route('login')); }); test('admin cannot access client dashboard', function () { $admin = User::factory()->admin()->create(); $this->actingAs($admin) ->get(route('client.dashboard')) ->assertForbidden(); }); // Welcome Section Tests test('dashboard shows welcome message with user name', function () { $user = User::factory()->individual()->create(['full_name' => 'John Doe']); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee('John Doe'); }); // Upcoming Consultation Widget Tests test('dashboard shows upcoming approved consultation', function () { $user = User::factory()->individual()->create(); $consultation = Consultation::factory()->approved()->create([ 'user_id' => $user->id, 'booking_date' => today()->addDays(3), 'booking_time' => '10:00:00', ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee('10:00 AM'); }); test('dashboard shows only authenticated user consultations', function () { $user = User::factory()->individual()->create(); $otherUser = User::factory()->individual()->create(); Consultation::factory()->approved()->create([ 'user_id' => $user->id, 'booking_date' => today()->addDays(3), 'booking_time' => '09:00:00', ]); Consultation::factory()->approved()->create([ 'user_id' => $otherUser->id, 'booking_date' => today()->addDays(2), 'booking_time' => '14:00:00', ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee('9:00 AM') ->assertDontSee('2:00 PM'); }); test('dashboard shows no upcoming consultations when none exist', function () { $user = User::factory()->individual()->create(); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.no_upcoming')); }); test('dashboard does not show past approved consultations', function () { $user = User::factory()->individual()->create(); Consultation::factory()->approved()->create([ 'user_id' => $user->id, 'booking_date' => today()->subDay(), 'booking_time' => '10:00:00', ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.no_upcoming')); }); test('dashboard does not show pending consultations as upcoming', function () { $user = User::factory()->individual()->create(); Consultation::factory()->pending()->create([ 'user_id' => $user->id, 'booking_date' => today()->addDays(3), 'booking_time' => '11:00:00', ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.no_upcoming')); }); // Active Cases Widget Tests test('dashboard shows correct active timelines count', function () { $user = User::factory()->individual()->create(); Timeline::factory()->active()->count(3)->create(['user_id' => $user->id]); Timeline::factory()->archived()->count(2)->create(['user_id' => $user->id]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee('3'); }); test('dashboard shows no cases empty state when user has no timelines', function () { $user = User::factory()->individual()->create(); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.no_cases')); }); test('dashboard shows latest update preview for active cases', function () { $user = User::factory()->individual()->create(); $timeline = Timeline::factory()->active()->create(['user_id' => $user->id]); TimelineUpdate::factory()->create([ 'timeline_id' => $timeline->id, 'update_text' => 'This is the latest case update for testing purposes.', ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee('This is the latest case update'); }); // Recent Updates Widget Tests test('dashboard shows last 3 timeline updates', function () { $user = User::factory()->individual()->create(); $timeline = Timeline::factory()->create(['user_id' => $user->id]); TimelineUpdate::factory()->create([ 'timeline_id' => $timeline->id, 'update_text' => 'Update One', 'created_at' => now()->subDays(4), ]); TimelineUpdate::factory()->create([ 'timeline_id' => $timeline->id, 'update_text' => 'Update Two', 'created_at' => now()->subDays(3), ]); TimelineUpdate::factory()->create([ 'timeline_id' => $timeline->id, 'update_text' => 'Update Three', 'created_at' => now()->subDays(2), ]); TimelineUpdate::factory()->create([ 'timeline_id' => $timeline->id, 'update_text' => 'Update Four', 'created_at' => now()->subDay(), ]); TimelineUpdate::factory()->create([ 'timeline_id' => $timeline->id, 'update_text' => 'Update Five', 'created_at' => now(), ]); $this->actingAs($user); // Should see the 3 most recent updates, not the older ones Volt::test('client.dashboard') ->assertSee('Update Five') ->assertSee('Update Four') ->assertSee('Update Three') ->assertDontSee('Update Two') ->assertDontSee('Update One'); }); test('dashboard shows no updates empty state when user has no timeline updates', function () { $user = User::factory()->individual()->create(); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.no_updates')); }); // Booking Status Widget Tests test('canBookToday is false when user has approved booking today', function () { $user = User::factory()->individual()->create(); Consultation::factory()->approved()->create([ 'user_id' => $user->id, 'booking_date' => today(), ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.cannot_book')); }); test('canBookToday is false when user has pending booking today', function () { $user = User::factory()->individual()->create(); Consultation::factory()->pending()->create([ 'user_id' => $user->id, 'booking_date' => today(), ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.cannot_book')); }); test('canBookToday is true when user has no booking today', function () { $user = User::factory()->individual()->create(); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.can_book')); }); test('canBookToday is true when user has only rejected booking today', function () { $user = User::factory()->individual()->create(); Consultation::factory()->rejected()->create([ 'user_id' => $user->id, 'booking_date' => today(), ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.can_book')); }); test('canBookToday is true when user has only cancelled booking today', function () { $user = User::factory()->individual()->create(); Consultation::factory()->cancelled()->create([ 'user_id' => $user->id, 'booking_date' => today(), ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.can_book')); }); test('dashboard shows pending bookings count', function () { $user = User::factory()->individual()->create(); Consultation::factory()->pending()->count(3)->create([ 'user_id' => $user->id, 'booking_date' => today()->addDays(5), ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee('3'); }); // Empty State Tests test('dashboard handles empty state gracefully', function () { $user = User::factory()->individual()->create(); $this->actingAs($user); Volt::test('client.dashboard') ->assertSee(__('client.dashboard.no_upcoming')) ->assertSee(__('client.dashboard.no_cases')) ->assertSee(__('client.dashboard.no_updates')) ->assertSee(__('client.dashboard.can_book')); }); // Data Isolation Tests test('dashboard does not show other users timeline updates', function () { $user = User::factory()->individual()->create(); $otherUser = User::factory()->individual()->create(); $otherTimeline = Timeline::factory()->create(['user_id' => $otherUser->id]); TimelineUpdate::factory()->create([ 'timeline_id' => $otherTimeline->id, 'update_text' => 'Other user secret update', ]); $this->actingAs($user); Volt::test('client.dashboard') ->assertDontSee('Other user secret update'); }); test('dashboard does not count other users active timelines', function () { $user = User::factory()->individual()->create(); $otherUser = User::factory()->individual()->create(); Timeline::factory()->active()->create(['user_id' => $user->id]); Timeline::factory()->active()->count(5)->create(['user_id' => $otherUser->id]); $this->actingAs($user); // User should only see their 1 active timeline, not the 5 from other user Volt::test('client.dashboard') ->assertSee('1'); });