Files
radicall/tests/Feature/Http/Admin/DocumentControllerTest.php

166 lines
7.5 KiB
PHP

<?php
namespace Tests\Feature\Http\Admin;
use App\Enums\DocumentPriorityEnum;
use App\Enums\DocumentStatusEnum;
use App\Enums\MediaDiskEnum;
use App\Models\Document;
use App\Models\Medium;
use App\Models\Pet;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Inertia\Testing\AssertableInertia as Assert;
use Maatwebsite\Excel\Facades\Excel;
use Tests\Concerns\InteractsWithAdmin;
use Tests\TestCase;
class DocumentControllerTest extends TestCase
{
use InteractsWithAdmin, RefreshDatabase;
protected function payload(array $overrides = []): array
{
return array_merge([
'pet_id' => Pet::factory()->create()->id,
'status' => DocumentStatusEnum::Registered->name,
'priority' => DocumentPriorityEnum::High->name,
'modality' => 'mri',
], $overrides);
}
public function test_guest_is_redirected(): void
{
$this->get(route('admin.documents.index'))->assertRedirect(route('login'));
}
public function test_admin_without_permission_is_forbidden(): void
{
$admin = $this->adminWithoutPermissions();
$document = Document::factory()->create();
$this->actingAs($admin)->get(route('admin.documents.index'))->assertForbidden();
$this->actingAs($admin)->get(route('admin.documents.create'))->assertForbidden();
$this->actingAs($admin)->post(route('admin.documents.store'), $this->payload())->assertForbidden();
$this->actingAs($admin)->get(route('admin.documents.edit', $document))->assertForbidden();
$this->actingAs($admin)->put(route('admin.documents.update', $document), $this->payload())->assertForbidden();
$this->actingAs($admin)->delete(route('admin.documents.destroy', $document))->assertForbidden();
$this->actingAs($admin)->post('/admin/documents-upload')->assertForbidden();
$this->actingAs($admin)->get('/admin/documents-options')->assertForbidden();
}
public function test_index_renders_with_filters(): void
{
$admin = $this->adminWithAllPermissions();
$pet = Pet::factory()->create();
Document::factory()->registered()->high()->create(['code' => '111111', 'pet_id' => $pet->id]);
Document::factory()->completed()->medium()->create(['code' => '222222']);
$this->actingAs($admin)->get(route('admin.documents.index'))->assertOk()->assertInertia(fn (Assert $page) => $page->component('Documents/index')->has('documents.data', 2));
$this->actingAs($admin)->get(route('admin.documents.index', ['status' => DocumentStatusEnum::Completed->name]))->assertInertia(fn (Assert $page) => $page->has('documents.data', 1));
$this->actingAs($admin)->get(route('admin.documents.index', ['priority' => DocumentPriorityEnum::High->name]))->assertInertia(fn (Assert $page) => $page->has('documents.data', 1));
$this->actingAs($admin)->get(route('admin.documents.index', ['pet' => $pet->id]))->assertInertia(fn (Assert $page) => $page->has('documents.data', 1));
$this->actingAs($admin)->get(route('admin.documents.index', ['search' => '2222']))->assertInertia(fn (Assert $page) => $page->has('documents.data', 1));
}
public function test_create_and_edit_pages_render(): void
{
$admin = $this->adminWithAllPermissions();
$document = Document::factory()->create();
$this->actingAs($admin)->get(route('admin.documents.create'))->assertInertia(fn (Assert $page) => $page->component('Documents/create_and_edit')->has('pets'));
$this->actingAs($admin)->get(route('admin.documents.edit', $document))->assertInertia(fn (Assert $page) => $page->component('Documents/create_and_edit')->where('is_edit', true)->where('document.id', $document->id));
}
public function test_store_creates_document_with_files_attached_by_collection(): void
{
$admin = $this->adminWithAllPermissions();
$primary = Medium::factory()->create();
$history = Medium::factory()->create();
$this->actingAs($admin)->post(route('admin.documents.store'), $this->payload([
'primary_files' => [$primary->id],
'history_files' => [$history->id],
]))->assertOk()->assertSessionHas('success');
$document = Document::first();
$this->assertSame(DocumentStatusEnum::Registered, $document->status);
$this->assertSame(DocumentPriorityEnum::High, $document->priority);
$this->assertSame($admin->id, $document->requester_id);
$this->assertSame([$primary->id], $document->primaryFiles->pluck('id')->all());
$this->assertSame([$history->id], $document->historyFiles->pluck('id')->all());
}
public function test_store_validates_pet(): void
{
$this->actingAs($this->adminWithAllPermissions())->postJson(route('admin.documents.store'), ['pet_id' => 999])->assertUnprocessable()->assertJsonValidationErrors('pet_id');
}
public function test_update_replaces_file_collections(): void
{
$admin = $this->adminWithAllPermissions();
$document = Document::factory()->create();
$old = Medium::factory()->create();
$new = Medium::factory()->create();
$document->media()->attach($old->id, ['collection' => 'primary']);
$this->actingAs($admin)->put(route('admin.documents.update', $document), $this->payload([
'status' => DocumentStatusEnum::InProgress->name,
'primary_files' => [$new->id],
]))->assertOk();
$document->refresh();
$this->assertSame(DocumentStatusEnum::InProgress, $document->status);
$this->assertSame([$new->id], $document->primaryFiles->pluck('id')->all());
}
public function test_destroy_deletes_document(): void
{
$document = Document::factory()->create();
$this->actingAs($this->adminWithAllPermissions())->delete(route('admin.documents.destroy', $document))->assertOk();
$this->assertDatabaseMissing('documents', ['id' => $document->id]);
}
public function test_upload_file_stores_private_medium(): void
{
Storage::fake('private');
$this->actingAs($this->adminWithAllPermissions())->postJson('/admin/documents-upload', ['file' => UploadedFile::fake()->create('scan.pdf', 10, 'application/pdf')])
->assertOk()
->assertJsonPath('disk', MediaDiskEnum::Private->value);
$medium = Medium::first();
$this->assertStringStartsWith('documents/', $medium->path);
Storage::disk('private')->assertExists($medium->path);
}
public function test_upload_file_validates_presence(): void
{
$this->actingAs($this->adminWithAllPermissions())->postJson('/admin/documents-upload', [])->assertUnprocessable()->assertJsonValidationErrors('file');
}
public function test_get_options_returns_matching_documents(): void
{
$document = Document::factory()->create(['code' => '123456', 'modality' => 'mri']);
Document::factory()->create(['code' => '999999']);
$this->actingAs($this->adminWithAllPermissions())->getJson('/admin/documents-options?search=1234')
->assertOk()
->assertJsonCount(1, 'data')
->assertJsonPath('data.0.value', $document->id)
->assertJsonPath('data.0.label', 'پرونده 123456 - mri');
}
public function test_export_data_downloads_excel(): void
{
Excel::fake();
$this->actingAs($this->adminWithAllPermissions())->get('/admin/documents-export-data')->assertOk();
Excel::assertDownloaded('documents.xlsx');
}
}