feat(doctors): enhance doctor listing with bookable sorting and filtering, add JSON_EXTRACT DQL function
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Doctor;
|
||||
|
||||
use App\Appointment\Entity\WeeklySchedule;
|
||||
use App\Doctor\Entity\Doctor;
|
||||
use App\Specialty\Entity\Specialty;
|
||||
use App\Tests\ApiTestCase;
|
||||
|
||||
/**
|
||||
* Public doctors list: bookable doctors (appointment flag on + weekly schedule
|
||||
* with online booking enabled) must rank above non-bookable ones, and the
|
||||
* active=1 filter must return only truly bookable doctors — matching the
|
||||
* `active` field of the list payload.
|
||||
*/
|
||||
class DoctorListBookableSortFilterTest extends ApiTestCase
|
||||
{
|
||||
private Specialty $specialty;
|
||||
private Doctor $bookable;
|
||||
private Doctor $noSchedule;
|
||||
private Doctor $flagOff;
|
||||
private Doctor $bookingDisabled;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->client->catchExceptions(false);
|
||||
|
||||
// db_test is shared across runs — scope every request to a fresh
|
||||
// specialty so only this test's doctors are visible.
|
||||
$this->specialty = new Specialty('تخصص تست نوبت', 'sp-' . bin2hex(random_bytes(6)));
|
||||
$this->em->persist($this->specialty);
|
||||
|
||||
$this->bookable = $this->makeDoctor('دکتر نوبتدار');
|
||||
$this->noSchedule = $this->makeDoctor('دکتر بدون برنامه');
|
||||
$this->flagOff = $this->makeDoctor('دکتر غیرفعال');
|
||||
$this->bookingDisabled = $this->makeDoctor('دکتر رزرو خاموش');
|
||||
|
||||
$this->flagOff->setActiveDoctorAppointment(false);
|
||||
|
||||
$days = [['sessions' => [['active' => true, 'start_time' => '09:00', 'end_time' => '13:00']]]];
|
||||
$this->em->persist(new WeeklySchedule($this->bookable, $days));
|
||||
$this->em->persist(new WeeklySchedule($this->flagOff, $days));
|
||||
|
||||
$disabled = new WeeklySchedule($this->bookingDisabled, $days);
|
||||
$disabled->setMeta(['online_booking_enabled' => false]);
|
||||
$this->em->persist($disabled);
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
private function makeDoctor(string $name): Doctor
|
||||
{
|
||||
$doctor = new Doctor($this->createUser(['ROLE_DOCTOR']), $name);
|
||||
$doctor->getSpecialties()->add($this->specialty);
|
||||
$this->em->persist($doctor);
|
||||
|
||||
return $doctor;
|
||||
}
|
||||
|
||||
/** @return array<int, array<string, mixed>> */
|
||||
private function listDoctors(string $extraQuery = ''): array
|
||||
{
|
||||
$this->client->request(
|
||||
'GET',
|
||||
'/api/v1/doctors?specialty_id=' . $this->specialty->getId() . '&limit=50' . $extraQuery
|
||||
);
|
||||
$this->assertSame(200, $this->responseCode(), substr($this->client->getResponse()->getContent(), 0, 1500));
|
||||
$body = json_decode($this->client->getResponse()->getContent(), true);
|
||||
|
||||
return $body['data'];
|
||||
}
|
||||
|
||||
public function testDefaultListShowsAllDoctorsBookableFirst(): void
|
||||
{
|
||||
$items = $this->listDoctors();
|
||||
|
||||
$this->assertCount(4, $items);
|
||||
$this->assertSame($this->bookable->getUuid(), $items[0]['uuid']);
|
||||
$this->assertTrue($items[0]['active']);
|
||||
|
||||
$rest = array_column(array_slice($items, 1), 'uuid');
|
||||
sort($rest);
|
||||
$expected = [$this->noSchedule->getUuid(), $this->flagOff->getUuid(), $this->bookingDisabled->getUuid()];
|
||||
sort($expected);
|
||||
$this->assertSame($expected, $rest);
|
||||
foreach (array_slice($items, 1) as $item) {
|
||||
$this->assertFalse($item['active'], $item['name'] . ' must not be bookable');
|
||||
}
|
||||
}
|
||||
|
||||
public function testActiveFilterReturnsOnlyBookableDoctors(): void
|
||||
{
|
||||
$items = $this->listDoctors('&active=1');
|
||||
|
||||
$this->assertCount(1, $items);
|
||||
$this->assertSame($this->bookable->getUuid(), $items[0]['uuid']);
|
||||
$this->assertTrue($items[0]['active']);
|
||||
}
|
||||
|
||||
public function testActiveZeroReturnsOnlyFlagOffDoctors(): void
|
||||
{
|
||||
$items = $this->listDoctors('&active=0');
|
||||
|
||||
$this->assertCount(1, $items);
|
||||
$this->assertSame($this->flagOff->getUuid(), $items[0]['uuid']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user