229 lines
7.1 KiB
PHP
229 lines
7.1 KiB
PHP
<?php
|
|
|
|
use App\Models\Timeline;
|
|
use App\Models\TimelineUpdate;
|
|
use App\Models\User;
|
|
use Livewire\Volt\Volt;
|
|
|
|
// Authorization Tests
|
|
test('client can view own timelines list', function () {
|
|
$client = User::factory()->individual()->create();
|
|
Timeline::factory()->count(3)->create(['user_id' => $client->id]);
|
|
|
|
$this->actingAs($client)
|
|
->get(route('client.timelines.index'))
|
|
->assertOk();
|
|
});
|
|
|
|
test('client cannot view other clients timelines in list', function () {
|
|
$client = User::factory()->individual()->create();
|
|
$otherClient = User::factory()->individual()->create();
|
|
Timeline::factory()->create([
|
|
'user_id' => $otherClient->id,
|
|
'case_name' => 'Other Client Case',
|
|
]);
|
|
|
|
$this->actingAs($client);
|
|
|
|
Volt::test('client.timelines.index')
|
|
->assertDontSee('Other Client Case');
|
|
});
|
|
|
|
test('client can view own timeline detail', function () {
|
|
$client = User::factory()->individual()->create();
|
|
$timeline = Timeline::factory()->create([
|
|
'user_id' => $client->id,
|
|
'case_name' => 'My Contract Case',
|
|
]);
|
|
|
|
$this->actingAs($client)
|
|
->get(route('client.timelines.show', $timeline))
|
|
->assertOk()
|
|
->assertSee('My Contract Case');
|
|
});
|
|
|
|
test('client cannot view other clients timeline detail', function () {
|
|
$client = User::factory()->individual()->create();
|
|
$otherClient = User::factory()->individual()->create();
|
|
$otherTimeline = Timeline::factory()->create(['user_id' => $otherClient->id]);
|
|
|
|
$this->actingAs($client)
|
|
->get(route('client.timelines.show', $otherTimeline))
|
|
->assertForbidden();
|
|
});
|
|
|
|
test('guest cannot access timelines', function () {
|
|
$this->get(route('client.timelines.index'))
|
|
->assertRedirect(route('login'));
|
|
});
|
|
|
|
test('admin cannot access client timeline routes', function () {
|
|
$admin = User::factory()->admin()->create();
|
|
|
|
$this->actingAs($admin)
|
|
->get(route('client.timelines.index'))
|
|
->assertForbidden();
|
|
});
|
|
|
|
// List View Tests
|
|
test('active timelines displayed separately from archived', function () {
|
|
$client = User::factory()->individual()->create();
|
|
Timeline::factory()->create([
|
|
'user_id' => $client->id,
|
|
'case_name' => 'Active Case',
|
|
'status' => 'active',
|
|
]);
|
|
Timeline::factory()->create([
|
|
'user_id' => $client->id,
|
|
'case_name' => 'Archived Case',
|
|
'status' => 'archived',
|
|
]);
|
|
|
|
$this->actingAs($client);
|
|
|
|
Volt::test('client.timelines.index')
|
|
->assertSee('Active Case')
|
|
->assertSee('Archived Case')
|
|
->assertSeeInOrder([__('client.active_cases'), 'Active Case', __('client.archived_cases'), 'Archived Case']);
|
|
});
|
|
|
|
test('timeline list shows update count', function () {
|
|
$client = User::factory()->individual()->create();
|
|
$timeline = Timeline::factory()->create(['user_id' => $client->id]);
|
|
TimelineUpdate::factory()->count(5)->create(['timeline_id' => $timeline->id]);
|
|
|
|
$this->actingAs($client);
|
|
|
|
Volt::test('client.timelines.index')
|
|
->assertSee('5');
|
|
});
|
|
|
|
test('empty state shown when no timelines', function () {
|
|
$client = User::factory()->individual()->create();
|
|
|
|
$this->actingAs($client);
|
|
|
|
Volt::test('client.timelines.index')
|
|
->assertSee(__('client.no_cases_yet'));
|
|
});
|
|
|
|
// Detail View Tests
|
|
test('timeline detail shows all updates chronologically', function () {
|
|
$client = User::factory()->individual()->create();
|
|
$timeline = Timeline::factory()->create(['user_id' => $client->id]);
|
|
|
|
TimelineUpdate::factory()->create([
|
|
'timeline_id' => $timeline->id,
|
|
'update_text' => 'First Update',
|
|
'created_at' => now()->subDays(2),
|
|
]);
|
|
TimelineUpdate::factory()->create([
|
|
'timeline_id' => $timeline->id,
|
|
'update_text' => 'Second Update',
|
|
'created_at' => now()->subDay(),
|
|
]);
|
|
|
|
$this->actingAs($client);
|
|
|
|
Volt::test('client.timelines.show', ['timeline' => $timeline])
|
|
->assertSeeInOrder(['First Update', 'Second Update']);
|
|
});
|
|
|
|
test('timeline detail shows case name and reference', function () {
|
|
$client = User::factory()->individual()->create();
|
|
$timeline = Timeline::factory()->create([
|
|
'user_id' => $client->id,
|
|
'case_name' => 'Property Dispute',
|
|
'case_reference' => 'REF-2024-001',
|
|
]);
|
|
|
|
$this->actingAs($client);
|
|
|
|
Volt::test('client.timelines.show', ['timeline' => $timeline])
|
|
->assertSee('Property Dispute')
|
|
->assertSee('REF-2024-001');
|
|
});
|
|
|
|
test('timeline detail shows status badge', function () {
|
|
$client = User::factory()->individual()->create();
|
|
$activeTimeline = Timeline::factory()->create([
|
|
'user_id' => $client->id,
|
|
'status' => 'active',
|
|
]);
|
|
|
|
$this->actingAs($client);
|
|
|
|
Volt::test('client.timelines.show', ['timeline' => $activeTimeline])
|
|
->assertSee(__('client.active'));
|
|
});
|
|
|
|
test('empty updates shows no updates message', function () {
|
|
$client = User::factory()->individual()->create();
|
|
$timeline = Timeline::factory()->create(['user_id' => $client->id]);
|
|
|
|
$this->actingAs($client);
|
|
|
|
Volt::test('client.timelines.show', ['timeline' => $timeline])
|
|
->assertSee(__('client.no_updates_yet'));
|
|
});
|
|
|
|
// Read-Only Enforcement Tests
|
|
test('client timeline view is read-only with no edit actions', function () {
|
|
$client = User::factory()->individual()->create();
|
|
$timeline = Timeline::factory()->create(['user_id' => $client->id]);
|
|
|
|
$this->actingAs($client);
|
|
|
|
// Verify no edit/delete/archive buttons or forms exist in the view
|
|
Volt::test('client.timelines.show', ['timeline' => $timeline])
|
|
->assertDontSee('wire:click="edit"')
|
|
->assertDontSee('wire:click="delete"')
|
|
->assertDontSee('wire:click="archive"')
|
|
->assertDontSee('wire:submit');
|
|
});
|
|
|
|
// Company client access test
|
|
test('company client can view own timelines', function () {
|
|
$company = User::factory()->company()->create();
|
|
Timeline::factory()->count(2)->create(['user_id' => $company->id]);
|
|
|
|
$this->actingAs($company)
|
|
->get(route('client.timelines.index'))
|
|
->assertOk();
|
|
});
|
|
|
|
// Pagination Tests
|
|
test('timeline list paginates active timelines', function () {
|
|
$client = User::factory()->individual()->create();
|
|
// Create 15 active timelines (more than page size of 10)
|
|
Timeline::factory()->count(15)->create([
|
|
'user_id' => $client->id,
|
|
'status' => 'active',
|
|
]);
|
|
|
|
$this->actingAs($client);
|
|
|
|
// First page should show 10 timelines
|
|
$response = $this->get(route('client.timelines.index'));
|
|
$response->assertOk();
|
|
|
|
// Navigate to second page
|
|
$response = $this->get(route('client.timelines.index', ['active' => 2]));
|
|
$response->assertOk();
|
|
});
|
|
|
|
test('timeline list paginates archived timelines separately', function () {
|
|
$client = User::factory()->individual()->create();
|
|
// Create 15 archived timelines
|
|
Timeline::factory()->count(15)->create([
|
|
'user_id' => $client->id,
|
|
'status' => 'archived',
|
|
]);
|
|
|
|
$this->actingAs($client);
|
|
|
|
// Navigate to second page of archived
|
|
$response = $this->get(route('client.timelines.index', ['archived' => 2]));
|
|
$response->assertOk();
|
|
});
|