Files

113 lines
4.4 KiB
PHP

<?php
namespace Tests\Feature\Http\Client\Doctor;
use App\Enums\DocumentStatusEnum;
use App\Enums\InvoiceStatusEnum;
use App\Enums\UserEnum;
use App\Models\Document;
use App\Models\DocumentAssignment;
use App\Models\Invoice;
use App\Models\User;
use App\Models\Wallet;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Inertia\Testing\AssertableInertia as Assert;
use Tests\TestCase;
class CaseControllerTest extends TestCase
{
use RefreshDatabase;
protected function doctor(): User
{
return User::factory()->create(['level' => UserEnum::Doctor->value]);
}
protected function assign(Document $document, User $doctor): void
{
DocumentAssignment::factory()->create(['document_id' => $document->id, 'user_id' => $doctor->id]);
}
public function test_routes_require_authentication(): void
{
$document = Document::factory()->create();
$this->get(route('dashboard.cases.index'))->assertRedirect(route('login'));
$this->get(route('dashboard.cases.show', $document))->assertRedirect(route('login'));
$this->post(route('dashboard.cases.reject', $document))->assertRedirect(route('login'));
}
public function test_index_paginates_pending_cases_of_user(): void
{
$user = User::factory()->create();
Document::factory()->count(12)->registered()->create(['requester_id' => $user->id]);
Document::factory()->completed()->create(['requester_id' => $user->id]);
$this->actingAs($user)->get(route('dashboard.cases.index'))
->assertOk()
->assertInertia(fn (Assert $page) => $page->component('Dashboard/Cases/Index')->has('cases.data', 10)->where('cases.meta.total', 12));
}
public function test_show_renders_case_for_requester_without_report_permission(): void
{
$document = Document::factory()->inProgress()->create();
$this->actingAs($document->requester)->get(route('dashboard.cases.show', $document))
->assertOk()
->assertInertia(fn (Assert $page) => $page->component('Dashboard/Cases/show')->where('case.id', $document->id)->where('canReport', false));
}
public function test_show_allows_assigned_doctor_to_report(): void
{
$doctor = $this->doctor();
$document = Document::factory()->inProgress()->create();
$this->assign($document, $doctor);
$this->actingAs($doctor)->get(route('dashboard.cases.show', $document))
->assertOk()
->assertInertia(fn (Assert $page) => $page->where('canReport', true));
}
public function test_show_forbids_unrelated_user(): void
{
$document = Document::factory()->create();
$this->actingAs(User::factory()->create())->get(route('dashboard.cases.show', $document))->assertForbidden();
}
public function test_reject_by_assigned_doctor_rejects_case_and_refunds(): void
{
$doctor = $this->doctor();
$document = Document::factory()->inProgress()->create();
$this->assign($document, $doctor);
$wallet = Wallet::factory()->create(['user_id' => $document->requester_id, 'balance' => 0]);
Invoice::factory()->paid()->create(['document_id' => $document->id, 'user_id' => $document->requester_id, 'amount' => 300000]);
$this->actingAs($doctor)->post(route('dashboard.cases.reject', $document), ['reason' => 'ناخوانا'])
->assertRedirect(route('dashboard.cases.index'))
->assertSessionHas('success');
$this->assertSame(DocumentStatusEnum::Rejected, $document->fresh()->status);
$this->assertSame(300000, $wallet->fresh()->balance);
$this->assertDatabaseHas('invoices', ['document_id' => $document->id, 'status' => InvoiceStatusEnum::Canceled->value]);
}
public function test_reject_validates_reason(): void
{
$doctor = $this->doctor();
$document = Document::factory()->inProgress()->create();
$this->assign($document, $doctor);
$this->actingAs($doctor)->post(route('dashboard.cases.reject', $document), [])->assertSessionHasErrors('reason');
}
public function test_reject_by_unassigned_user_returns_validation_error(): void
{
$document = Document::factory()->inProgress()->create();
$this->actingAs($this->doctor())->post(route('dashboard.cases.reject', $document), ['reason' => 'x'])->assertSessionHasErrors('document');
$this->assertSame(DocumentStatusEnum::InProgress, $document->fresh()->status);
}
}