libra/tests/Feature/Client/DashboardTest.php

327 lines
9.7 KiB
PHP

<?php
use App\Models\Consultation;
use App\Models\Timeline;
use App\Models\TimelineUpdate;
use App\Models\User;
use Livewire\Volt\Volt;
// Authorization Tests
test('client can view their dashboard', function () {
$user = User::factory()->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');
});