feat: create SanitizeBlogBodiesCommand to clean existing blog bodies according to current HTML sanitization policies test: add AppointmentTreatmentSessionLinkTest to ensure appointment booking functionality works correctly with treatment session links
101 lines
4.0 KiB
PHP
101 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Appointment;
|
|
|
|
use App\Auth\Entity\User;
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Tests\ApiTestCase;
|
|
|
|
/**
|
|
* اتصال نوبت به جلسهٔ درمان در `POST /api/v1/my/appointment`.
|
|
*
|
|
* تا ۲۰۲۶-۰۸-۰۸ این شاخه هیچ تستی نداشت و به همین دلیل شکسته بود: کنترلر
|
|
* `$this->branches->pair($user)` را صدا میزد ولی `AddressResolver` هرگز تزریق
|
|
* نشده بود، پس هر درخواستِ دارای `treatment_session_uuid` روی «Undefined
|
|
* property» ۵۰۰ میگرفت. phpstan همان را گزارش میکرد، اما بین ۱۶ خطای بیاثر
|
|
* دیگر گم شده بود.
|
|
*/
|
|
class AppointmentTreatmentSessionLinkTest extends ApiTestCase
|
|
{
|
|
/**
|
|
* این تست چند درخواستِ کرنل پشتسرهم میزند و هر کدام `$this->em` را کهنه
|
|
* میکند. بدون ریست، همان نمونه به تست بعدی ارث میرسد و آنجا — نه اینجا —
|
|
* با «Multiple non-persisted new entities» میشکند. همان دامی که
|
|
* ApiLeastPrivilegeTest قبلاً برایش همین tearDown را گذاشت.
|
|
*/
|
|
protected function tearDown(): void
|
|
{
|
|
static::getContainer()->get('doctrine')->resetManager();
|
|
|
|
parent::tearDown();
|
|
}
|
|
|
|
/** @return array{0: User, 1: Doctor} */
|
|
private function doctor(): array
|
|
{
|
|
$owner = $this->createUser(['ROLE_DOCTOR']);
|
|
$doctor = new Doctor($owner, 'دکتر تست');
|
|
$this->em->persist($doctor);
|
|
$this->em->flush();
|
|
|
|
return [$owner, $doctor];
|
|
}
|
|
|
|
private function body(string $doctorUuid, array $extra = []): array
|
|
{
|
|
$start = time() + 86_400 + random_int(0, 3_600) * 100;
|
|
|
|
return $extra + [
|
|
'doctor_uuid' => $doctorUuid,
|
|
'slot_start' => $start,
|
|
'slot_end' => $start + 1_800,
|
|
'patient_mobile' => '09' . str_pad((string) random_int(0, 999_999_999), 9, '0', STR_PAD_LEFT),
|
|
'patient_name' => 'بیمار تست',
|
|
'patient_national_code' => '00' . str_pad((string) random_int(0, 99_999_999), 8, '0', STR_PAD_LEFT),
|
|
];
|
|
}
|
|
|
|
/** موفق: مسیر عادی بدون اتصال، دستنخورده. */
|
|
public function testBookingWithoutSessionLinkStillWorks(): void
|
|
{
|
|
[$owner, $doctor] = $this->doctor();
|
|
|
|
$this->authJson('POST', '/api/v1/my/appointment', $owner, $this->body($doctor->getUuid()));
|
|
|
|
self::assertSame(201, $this->responseCode());
|
|
}
|
|
|
|
/**
|
|
* خطا: uuidِ ناموجود باید ۴۰۴ـی بگیرد که از `SessionBookingLink` میآید.
|
|
*
|
|
* ۵۰۰ گرفتن یعنی اجرا اصلاً به آن سرویس نرسیده — همان رگرسیونی که این تست
|
|
* برایش نوشته شده.
|
|
*/
|
|
public function testBookingWithUnknownSessionUuidIsRejectedNotCrashed(): void
|
|
{
|
|
[$owner, $doctor] = $this->doctor();
|
|
|
|
$body = $this->authJson('POST', '/api/v1/my/appointment', $owner, $this->body(
|
|
$doctor->getUuid(),
|
|
['treatment_session_uuid' => '00000000-0000-0000-0000-000000000000'],
|
|
));
|
|
|
|
self::assertSame(404, $this->responseCode(), json_encode($body, JSON_UNESCAPED_UNICODE));
|
|
self::assertSame('ERR_NOT_FOUND_001', $body['errors'][0]['code']);
|
|
self::assertSame('treatment_session_uuid', $body['errors'][0]['field'] ?? null);
|
|
}
|
|
|
|
/** مرزی: رشتهٔ خالی یعنی «اتصالی در کار نیست»، نه uuidِ نامعتبر. */
|
|
public function testEmptySessionUuidIsTreatedAsNoLink(): void
|
|
{
|
|
[$owner, $doctor] = $this->doctor();
|
|
|
|
$this->authJson('POST', '/api/v1/my/appointment', $owner, $this->body(
|
|
$doctor->getUuid(),
|
|
['treatment_session_uuid' => ' '],
|
|
));
|
|
|
|
self::assertSame(201, $this->responseCode());
|
|
}
|
|
}
|