feat(appointment): enhance booking window functionality with day/week/month options and update defaults
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<?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']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user