libra/tests/Feature/Admin/TimelineArchivingTest.php

209 lines
6.9 KiB
PHP

<?php
use App\Enums\TimelineStatus;
use App\Models\AdminLog;
use App\Models\Timeline;
use App\Models\User;
use Livewire\Volt\Volt;
beforeEach(function () {
$this->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);
});