Files
clinicpro/tests/Appointment/ResourceBlockTest.php
T
hamed c4f1f25c80 Refactor booking system: Remove unused policies, packages, and related entities
- Removed package consumption flags and related properties from PriceQuote.
- Eliminated unused domain event publishing for policies and waitlist in Schedule.
- Cleaned up BookingEngineSeeder by removing package and policy related logic.
- Updated SeedScenariosCommand to reflect removal of policies from output.
- Dropped policy, package, treatment course, cancellation, waitlist, and domain event tables in migration.
- Removed domain event assertions from tests related to resource blocking.
2026-08-01 20:50:47 +03:30

166 lines
5.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Tests\Appointment;
use App\Appointment\Availability\Entity\ResourceOccupancy;
use App\Auth\Entity\User;
use App\Clinic\Entity\Clinic;
use App\Doctor\Entity\DoctorAddress;
use App\Resource\Entity\ClinicResource;
use App\Resource\Entity\ResourceType;
use App\Tests\ApiTestCase;
use Doctrine\ORM\EntityManagerInterface;
/**
* مسدودسازی موردی منبع — «این بعدازظهر دستگاه سرویس دارد».
*
* با استثنای تقویم فرق دارد: آن الگوی کاری را عوض می‌کند، این یک بازهٔ مشخص را
* می‌بندد. مرز بینشان همان چیزی است که این تست‌ها نگه می‌دارند.
*/
class ResourceBlockTest extends ApiTestCase
{
/** @return array{0: User, 1: ClinicResource} */
private function clinicWithResource(): array
{
$user = $this->createUser(['ROLE_USER', 'ROLE_CLINIC']);
$clinic = new Clinic($user);
$clinic->setName('کلینیک مسدودسازی');
$this->em->persist($clinic);
$this->em->flush();
$address = DoctorAddress::forClinic($clinic->getId());
$address->setName('شعبه');
$this->em->persist($address);
$type = new ResourceType('clinic', (int) $clinic->getId(), 'device', 'دستگاه');
$this->em->persist($type);
$this->em->flush();
$resource = new ClinicResource($address, $type, 'لیزر ۱');
$this->em->persist($resource);
$this->em->flush();
return [$user, $resource];
}
public function testBlockingAFreeRangeSucceedsAndIsListed(): void
{
[$user, $resource] = $this->clinicWithResource();
$start = time() + 86400;
$body = $this->authJson('POST', "/api/v1/resource/{$resource->getUuid()}/blocks", $user, [
'starts_at' => $start,
'ends_at' => $start + 4 * 3600,
'reason' => 'سرویس دوره‌ای دستگاه',
]);
self::assertSame(201, $this->responseCode(), json_encode($body, JSON_UNESCAPED_UNICODE));
self::assertSame('سرویس دوره‌ای دستگاه', $body['data']['segment_name']);
$list = $this->authJson(
'GET',
sprintf('/api/v1/resource/%s/blocks?from=%d&to=%d', $resource->getUuid(), $start - 3600, $start + 86400),
$user,
);
self::assertCount(1, $list['data']);
}
public function testAnInvertedRangeIsRejected(): void
{
[$user, $resource] = $this->clinicWithResource();
$start = time() + 86400;
$this->authJson('POST', "/api/v1/resource/{$resource->getUuid()}/blocks", $user, [
'starts_at' => $start,
'ends_at' => $start - 3600,
]);
self::assertSame(422, $this->responseCode());
}
/** ⭐ مسدودسازی روی بازه‌ای که نوبت دارد، ظرفیت را پس نمی‌گیرد. */
public function testBlockingOverABookedRangeIsRejected(): void
{
[$user, $resource] = $this->clinicWithResource();
$start = time() + 2 * 86400;
$em = static::getContainer()->get(EntityManagerInterface::class);
$reloaded = $em->getRepository(ClinicResource::class)->find($resource->getId());
$booked = new ResourceOccupancy($reloaded, $start, $start + 3600);
$booked->setAppointmentId(4242);
$em->persist($booked);
$em->flush();
$this->authJson('POST', "/api/v1/resource/{$resource->getUuid()}/blocks", $user, [
'starts_at' => $start,
'ends_at' => $start + 7200,
]);
self::assertSame(409, $this->responseCode());
}
/** ⭐ اشغالِ یک نوبت واقعی از این مسیر حذف نمی‌شود. */
public function testAnAppointmentOccupancyCannotBeDeletedAsABlock(): void
{
[$user, $resource] = $this->clinicWithResource();
$start = time() + 3 * 86400;
$em = static::getContainer()->get(EntityManagerInterface::class);
$reloaded = $em->getRepository(ClinicResource::class)->find($resource->getId());
$booked = new ResourceOccupancy($reloaded, $start, $start + 3600);
$booked->setAppointmentId(777);
$em->persist($booked);
$em->flush();
$this->authJson('DELETE', "/api/v1/resource-block/{$booked->getUuid()}", $user);
self::assertSame(422, $this->responseCode());
}
public function testAManualBlockCanBeDeleted(): void
{
[$user, $resource] = $this->clinicWithResource();
$start = time() + 86400;
$created = $this->authJson('POST', "/api/v1/resource/{$resource->getUuid()}/blocks", $user, [
'starts_at' => $start,
'ends_at' => $start + 3600,
]);
$this->authJson('DELETE', "/api/v1/resource-block/{$created['data']['uuid']}", $user);
self::assertSame(200, $this->responseCode());
$list = $this->authJson(
'GET',
sprintf('/api/v1/resource/%s/blocks?from=%d&to=%d', $resource->getUuid(), $start - 3600, $start + 86400),
$user,
);
self::assertCount(0, $list['data']);
}
public function testAnotherClinicCannotBlockTheResource(): void
{
[, $resource] = $this->clinicWithResource();
[$other] = $this->clinicWithResource();
$start = time() + 86400;
$this->authJson('POST', "/api/v1/resource/{$resource->getUuid()}/blocks", $other, [
'starts_at' => $start,
'ends_at' => $start + 3600,
]);
self::assertSame(404, $this->responseCode());
}
}