admin = User::factory()->admin()->create(); $this->client = User::factory()->individual()->create(); $this->timeline = Timeline::factory()->create(['user_id' => $this->client->id]); }); // =========================================== // Archive Timeline Tests // =========================================== test('admin can archive active timeline', function () { $this->actingAs($this->admin); Volt::test('admin.timelines.show', ['timeline' => $this->timeline]) ->call('archive') ->assertHasNoErrors(); expect($this->timeline->fresh()->isArchived())->toBeTrue(); }); test('admin can unarchive archived timeline', function () { $archivedTimeline = Timeline::factory()->archived()->create(['user_id' => $this->client->id]); $this->actingAs($this->admin); Volt::test('admin.timelines.show', ['timeline' => $archivedTimeline]) ->call('unarchive') ->assertHasNoErrors(); expect($archivedTimeline->fresh()->isActive())->toBeTrue(); }); test('archiving archived timeline is noop', function () { $archivedTimeline = Timeline::factory()->archived()->create(['user_id' => $this->client->id]); $this->actingAs($this->admin); $initialLogCount = AdminLog::count(); Volt::test('admin.timelines.show', ['timeline' => $archivedTimeline]) ->call('archive') ->assertHasNoErrors(); // Status should remain archived expect($archivedTimeline->fresh()->isArchived())->toBeTrue(); // No additional log entry should be created expect(AdminLog::count())->toBe($initialLogCount); }); test('unarchiving active timeline is noop', function () { $this->actingAs($this->admin); $initialLogCount = AdminLog::count(); Volt::test('admin.timelines.show', ['timeline' => $this->timeline]) ->call('unarchive') ->assertHasNoErrors(); // Status should remain active expect($this->timeline->fresh()->isActive())->toBeTrue(); // No additional log entry should be created expect(AdminLog::count())->toBe($initialLogCount); }); test('cannot add update to archived timeline', function () { $archivedTimeline = Timeline::factory()->archived()->create(['user_id' => $this->client->id]); $this->actingAs($this->admin); Volt::test('admin.timelines.show', ['timeline' => $archivedTimeline]) ->set('updateText', 'This should not be added to archived timeline.') ->call('addUpdate'); expect($archivedTimeline->updates()->count())->toBe(0); }); // =========================================== // Audit Log Tests // =========================================== test('audit log created on archive', function () { $this->actingAs($this->admin); Volt::test('admin.timelines.show', ['timeline' => $this->timeline]) ->call('archive') ->assertHasNoErrors(); expect(AdminLog::where('action', 'archive') ->where('target_type', 'timeline') ->where('target_id', $this->timeline->id) ->where('admin_id', $this->admin->id) ->exists())->toBeTrue(); }); test('audit log created on unarchive', function () { $archivedTimeline = Timeline::factory()->archived()->create(['user_id' => $this->client->id]); $this->actingAs($this->admin); Volt::test('admin.timelines.show', ['timeline' => $archivedTimeline]) ->call('unarchive') ->assertHasNoErrors(); expect(AdminLog::where('action', 'unarchive') ->where('target_type', 'timeline') ->where('target_id', $archivedTimeline->id) ->where('admin_id', $this->admin->id) ->exists())->toBeTrue(); }); // =========================================== // Authorization Tests // =========================================== test('guest cannot archive timeline', function () { $this->get(route('admin.timelines.show', $this->timeline)) ->assertRedirect(route('login')); }); test('client cannot archive timeline', function () { $this->actingAs($this->client) ->get(route('admin.timelines.show', $this->timeline)) ->assertForbidden(); }); // =========================================== // Visual Indicator Tests // =========================================== test('archived timeline shows visual indicator', function () { $archivedTimeline = Timeline::factory()->archived()->create(['user_id' => $this->client->id]); $this->actingAs($this->admin); Volt::test('admin.timelines.show', ['timeline' => $archivedTimeline]) ->assertSee(__('enums.timeline_status.archived')); }); test('update form disabled on archived timeline', function () { $archivedTimeline = Timeline::factory()->archived()->create(['user_id' => $this->client->id]); $this->actingAs($this->admin); Volt::test('admin.timelines.show', ['timeline' => $archivedTimeline]) ->assertSee(__('timelines.archived_notice')); }); // =========================================== // Model Method Tests // =========================================== test('timeline isArchived returns true for archived timeline', function () { $archivedTimeline = Timeline::factory()->archived()->create(['user_id' => $this->client->id]); expect($archivedTimeline->isArchived())->toBeTrue(); expect($archivedTimeline->isActive())->toBeFalse(); }); test('timeline isActive returns true for active timeline', function () { expect($this->timeline->isActive())->toBeTrue(); expect($this->timeline->isArchived())->toBeFalse(); }); test('scopeActive returns only active timelines', function () { Timeline::factory()->archived()->create(['user_id' => $this->client->id]); Timeline::factory()->archived()->create(['user_id' => $this->client->id]); $activeTimelines = Timeline::active()->get(); expect($activeTimelines->count())->toBe(1); expect($activeTimelines->first()->id)->toBe($this->timeline->id); }); test('scopeArchived returns only archived timelines', function () { $archived1 = Timeline::factory()->archived()->create(['user_id' => $this->client->id]); $archived2 = Timeline::factory()->archived()->create(['user_id' => $this->client->id]); $archivedTimelines = Timeline::archived()->get(); expect($archivedTimelines->count())->toBe(2); expect($archivedTimelines->pluck('id')->toArray())->toContain($archived1->id, $archived2->id); }); test('archive method changes status to archived', function () { expect($this->timeline->status)->toBe(TimelineStatus::Active); $this->timeline->archive(); expect($this->timeline->fresh()->status)->toBe(TimelineStatus::Archived); }); test('unarchive method changes status to active', function () { $archivedTimeline = Timeline::factory()->archived()->create(['user_id' => $this->client->id]); expect($archivedTimeline->status)->toBe(TimelineStatus::Archived); $archivedTimeline->unarchive(); expect($archivedTimeline->fresh()->status)->toBe(TimelineStatus::Active); });