106 lines
3.8 KiB
PHP
106 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Appointment;
|
|
|
|
use App\Appointment\Entity\WeeklySchedule;
|
|
use App\Appointment\Service\SlotCalculatorService;
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Tests\ApiTestCase;
|
|
|
|
/**
|
|
* بازهٔ مجاز رزرو آنلاین (booking_window) با سه واحد روز/هفته/ماه و پیشفرض «۳ ماه».
|
|
*/
|
|
class BookingWindowUnitTest extends ApiTestCase
|
|
{
|
|
/** پزشکی با شیفت فعال در هر هفت روز هفته، تا هر تاریخِ آزمون اسلات داشته باشد. */
|
|
private function makeAlwaysOpenDoctor(array $meta = []): Doctor
|
|
{
|
|
$owner = $this->createUser(['ROLE_DOCTOR']);
|
|
$doctor = new Doctor($owner, 'دکتر بازهٔ رزرو');
|
|
$this->em->persist($doctor);
|
|
|
|
$days = [];
|
|
foreach (range(0, 6) as $dayKey) {
|
|
$days[(string) $dayKey] = ['sessions' => [[
|
|
'active' => true,
|
|
'start_time' => '10:00',
|
|
'end_time' => '12:00',
|
|
'duration_per_patient' => 30,
|
|
'location_id' => 1,
|
|
]]];
|
|
}
|
|
|
|
$schedule = new WeeklySchedule($doctor, $days);
|
|
if ($meta !== []) {
|
|
$schedule->setMeta($meta);
|
|
}
|
|
$this->em->persist($schedule);
|
|
$this->em->flush();
|
|
|
|
return $doctor;
|
|
}
|
|
|
|
private function assertBookable(Doctor $doctor, string $relative): void
|
|
{
|
|
$calc = static::getContainer()->get(SlotCalculatorService::class);
|
|
$date = date('Y-m-d', strtotime($relative));
|
|
|
|
$this->assertNotSame([], $calc->getAllSlotsWithAvailability($doctor, $date), "باید داخل بازه باشد: {$relative}");
|
|
}
|
|
|
|
private function assertOutsideWindow(Doctor $doctor, string $relative): void
|
|
{
|
|
$calc = static::getContainer()->get(SlotCalculatorService::class);
|
|
$date = date('Y-m-d', strtotime($relative));
|
|
|
|
$this->assertSame([], $calc->getAllSlotsWithAvailability($doctor, $date), "باید بیرون بازه باشد: {$relative}");
|
|
$this->assertSame(SlotCalculatorService::EMPTY_OUTSIDE_WINDOW, $calc->explainEmptyDay($doctor, $date));
|
|
}
|
|
|
|
public function testDayUnitLimitsWindowToExactDays(): void
|
|
{
|
|
$doctor = $this->makeAlwaysOpenDoctor([
|
|
'booking_window_value' => 2,
|
|
'booking_window_unit' => 'day',
|
|
]);
|
|
|
|
$this->assertBookable($doctor, '+2 days');
|
|
$this->assertOutsideWindow($doctor, '+3 days');
|
|
}
|
|
|
|
public function testWeekUnitStillSupported(): void
|
|
{
|
|
$doctor = $this->makeAlwaysOpenDoctor([
|
|
'booking_window_value' => 1,
|
|
'booking_window_unit' => 'week',
|
|
]);
|
|
|
|
$this->assertBookable($doctor, '+7 days');
|
|
$this->assertOutsideWindow($doctor, '+8 days');
|
|
}
|
|
|
|
public function testDefaultWindowIsThreeMonths(): void
|
|
{
|
|
$this->assertSame(3, WeeklySchedule::DEFAULT_META['booking_window_value']);
|
|
$this->assertSame('month', WeeklySchedule::DEFAULT_META['booking_window_unit']);
|
|
|
|
$doctor = $this->makeAlwaysOpenDoctor();
|
|
|
|
$this->assertBookable($doctor, '+2 months');
|
|
$this->assertOutsideWindow($doctor, '+3 months +2 days');
|
|
}
|
|
|
|
public function testInvalidUnitKeepsCurrentValue(): void
|
|
{
|
|
$owner = $this->createUser(['ROLE_DOCTOR']);
|
|
$doctor = new Doctor($owner, 'دکتر واحد نامعتبر');
|
|
$schedule = new WeeklySchedule($doctor, []);
|
|
|
|
$schedule->setMeta(['booking_window_unit' => 'day', 'booking_window_value' => 10]);
|
|
$schedule->setMeta(['booking_window_unit' => 'year']);
|
|
|
|
$this->assertSame('day', $schedule->getMeta()['booking_window_unit']);
|
|
$this->assertSame(10, $schedule->getMeta()['booking_window_value']);
|
|
}
|
|
}
|