205 lines
7.2 KiB
PHP
205 lines
7.2 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Services\Document;
|
|
|
|
use App\Enums\DocumentModalityEnum;
|
|
use App\Enums\DocumentPriorityEnum;
|
|
use App\Enums\DocumentStatusEnum;
|
|
use App\Enums\InvoiceStatusEnum;
|
|
use App\Enums\PetGenderEnum;
|
|
use App\Enums\PetTypeEnum;
|
|
use App\Enums\UserEnum;
|
|
use App\Jobs\SendPatternSms;
|
|
use App\Models\Pet;
|
|
use App\Models\Shift;
|
|
use App\Models\User;
|
|
use App\Services\Document\FastRequestService;
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Tests\TestCase;
|
|
|
|
class FastRequestServiceTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected FastRequestService $service;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
Queue::fake();
|
|
Storage::fake('public');
|
|
$this->service = app(FastRequestService::class);
|
|
}
|
|
|
|
protected function payload(array $overrides = []): array
|
|
{
|
|
return array_merge([
|
|
'modality' => DocumentModalityEnum::Mri->value,
|
|
'priority' => DocumentPriorityEnum::High->name,
|
|
'pet' => ['name' => 'Rex', 'type' => PetTypeEnum::Dog->name],
|
|
], $overrides);
|
|
}
|
|
|
|
public function test_create_stores_document_with_generated_code_and_registered_status(): void
|
|
{
|
|
Carbon::setTestNow('2026-09-21 10:00:00');
|
|
$requester = User::factory()->create();
|
|
|
|
$document = $this->service->create($requester, $this->payload(['note' => 'یادداشت']));
|
|
|
|
$this->assertMatchesRegularExpression('/^\d{6}$/', $document->code);
|
|
$this->assertSame(DocumentStatusEnum::Registered, $document->fresh()->status);
|
|
$this->assertSame(DocumentPriorityEnum::High, $document->priority);
|
|
$this->assertTrue($document->submitted_at->eq(Carbon::parse('2026-09-21 10:00:00')));
|
|
$this->assertDatabaseHas('documents', [
|
|
'id' => $document->id,
|
|
'modality' => DocumentModalityEnum::Mri->value,
|
|
'note' => 'یادداشت',
|
|
'requester_id' => $requester->id,
|
|
]);
|
|
}
|
|
|
|
public function test_create_creates_pending_invoice_priced_by_modality(): void
|
|
{
|
|
$document = $this->service->create(User::factory()->create(), $this->payload());
|
|
|
|
$this->assertDatabaseHas('invoices', [
|
|
'document_id' => $document->id,
|
|
'user_id' => $document->requester_id,
|
|
'amount' => DocumentModalityEnum::Mri->price(),
|
|
'status' => InvoiceStatusEnum::Pending->value,
|
|
]);
|
|
}
|
|
|
|
public function test_create_creates_pet_for_requester_from_payload(): void
|
|
{
|
|
Carbon::setTestNow('2026-09-21 10:00:00');
|
|
$requester = User::factory()->create();
|
|
|
|
$document = $this->service->create($requester, $this->payload(['pet' => [
|
|
'name' => 'Rex',
|
|
'type' => PetTypeEnum::Dog->name,
|
|
'gender' => PetGenderEnum::Male->name,
|
|
'breed' => 'ژرمن',
|
|
'weight' => 20,
|
|
'sterilized' => true,
|
|
'age' => 3,
|
|
]]));
|
|
|
|
$this->assertDatabaseHas('pets', [
|
|
'id' => $document->pet_id,
|
|
'name' => 'Rex',
|
|
'type' => PetTypeEnum::Dog->value,
|
|
'gender' => PetGenderEnum::Male->value,
|
|
'breed' => 'ژرمن',
|
|
'weight' => 20,
|
|
'sterilized' => 1,
|
|
'owner_id' => $requester->id,
|
|
]);
|
|
$this->assertTrue(Pet::find($document->pet_id)->birthday->isSameDay(Carbon::parse('2023-09-21')));
|
|
}
|
|
|
|
public function test_create_defaults_pet_gender_to_unknown(): void
|
|
{
|
|
$document = $this->service->create(User::factory()->create(), $this->payload());
|
|
|
|
$this->assertSame(PetGenderEnum::Unknown, Pet::find($document->pet_id)->gender);
|
|
}
|
|
|
|
public function test_create_uses_existing_pet_of_requester(): void
|
|
{
|
|
$requester = User::factory()->create();
|
|
$pet = Pet::factory()->create(['owner_id' => $requester->id]);
|
|
|
|
$document = $this->service->create($requester, $this->payload(['pet_id' => $pet->id, 'pet' => null]));
|
|
|
|
$this->assertSame($pet->id, $document->pet_id);
|
|
$this->assertDatabaseCount('pets', 1);
|
|
}
|
|
|
|
public function test_create_rejects_pet_of_another_user(): void
|
|
{
|
|
$pet = Pet::factory()->create();
|
|
|
|
$this->expectException(ModelNotFoundException::class);
|
|
|
|
$this->service->create(User::factory()->create(), $this->payload(['pet_id' => $pet->id, 'pet' => null]));
|
|
}
|
|
|
|
public function test_create_attaches_history_and_scan_files_to_their_collections(): void
|
|
{
|
|
$document = $this->service->create(
|
|
User::factory()->create(),
|
|
$this->payload(),
|
|
[UploadedFile::fake()->create('history.pdf', 10, 'application/pdf')],
|
|
[UploadedFile::fake()->image('scan1.jpg'), UploadedFile::fake()->image('scan2.jpg')]
|
|
);
|
|
|
|
$this->assertCount(1, $document->historyFiles);
|
|
$this->assertCount(2, $document->primaryFiles);
|
|
$this->assertDatabaseCount('media', 3);
|
|
Storage::disk('public')->assertExists($document->primaryFiles->first()->path);
|
|
}
|
|
|
|
public function test_create_assigns_given_doctor_as_radiologist(): void
|
|
{
|
|
$doctor = User::factory()->create(['level' => UserEnum::Doctor->value]);
|
|
|
|
$document = $this->service->create(User::factory()->create(), $this->payload(['doctor_id' => $doctor->id]));
|
|
|
|
$this->assertDatabaseHas('document_assignments', [
|
|
'document_id' => $document->id,
|
|
'user_id' => $doctor->id,
|
|
'role' => 'رادیولوژیست',
|
|
]);
|
|
}
|
|
|
|
public function test_create_auto_selects_on_shift_doctor_when_none_given(): void
|
|
{
|
|
Carbon::setTestNow('2026-09-21 10:00:00');
|
|
$doctor = User::factory()->create(['level' => UserEnum::Doctor->value]);
|
|
Shift::factory()->onDate('2026-09-21')->between('08:00', '16:00')->forDoctor($doctor)->create();
|
|
|
|
$document = $this->service->create(User::factory()->create(), $this->payload());
|
|
|
|
$this->assertDatabaseHas('document_assignments', ['document_id' => $document->id, 'user_id' => $doctor->id]);
|
|
}
|
|
|
|
public function test_create_leaves_document_unassigned_when_no_doctor_is_available(): void
|
|
{
|
|
$document = $this->service->create(User::factory()->create(), $this->payload());
|
|
|
|
$this->assertDatabaseCount('document_assignments', 0);
|
|
$this->assertSame($document->id, $document->fresh()->id);
|
|
}
|
|
|
|
public function test_create_dispatches_request_registered_sms(): void
|
|
{
|
|
config(['services.iranpayamak.patterns.request_registered' => 'pattern-code']);
|
|
|
|
$this->service->create(User::factory()->create(), $this->payload());
|
|
|
|
Queue::assertPushed(SendPatternSms::class, 1);
|
|
}
|
|
|
|
public function test_create_rolls_back_everything_when_pet_lookup_fails(): void
|
|
{
|
|
$requester = User::factory()->create();
|
|
|
|
try {
|
|
$this->service->create($requester, $this->payload(['pet_id' => 999, 'pet' => null]));
|
|
} catch (ModelNotFoundException) {
|
|
}
|
|
|
|
$this->assertDatabaseCount('documents', 0);
|
|
$this->assertDatabaseCount('invoices', 0);
|
|
Queue::assertNothingPushed();
|
|
}
|
|
}
|