feat(dashboard): implement Jalali month start calculation and add related tests
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Dashboard;
|
||||
|
||||
use App\Auth\Entity\User;
|
||||
use App\Clinic\Entity\Clinic;
|
||||
use App\Doctor\Entity\Doctor;
|
||||
use App\Tests\ApiTestCase;
|
||||
|
||||
/**
|
||||
* `this_month_appointments` باید سر ماه **شمسی** صفر شود، نه سر ماه گرگوری.
|
||||
*
|
||||
* قبلاً مرزش `strtotime('first day of this month')` بود؛ یعنی آمار داشبورد وسط
|
||||
* مرداد یا آبان ریست میشد — مرزی که هیچجای این محصولِ شمسی دیده نمیشود.
|
||||
*
|
||||
* تست به تاریخِ اجرا وابسته نیست: دو نوبت درست در دو طرفِ مرزِ ماه شمسی ساخته
|
||||
* میشوند. چون آغاز ماه شمسی و آغاز ماه گرگوری هیچوقت بر هم منطبق نیستند، کدِ
|
||||
* گرگوری همیشه دستکم یکی از این دو را اشتباه میشمارد.
|
||||
*/
|
||||
class DashboardJalaliMonthTest extends ApiTestCase
|
||||
{
|
||||
/** آغاز ماه شمسی جاری به یونیکس — همان محاسبهای که کنترلر باید بکند. */
|
||||
private function jalaliMonthStart(): int
|
||||
{
|
||||
$cal = \IntlCalendar::createInstance(new \DateTimeZone('Asia/Tehran'), 'fa_IR@calendar=persian');
|
||||
$cal->set(\IntlCalendar::FIELD_DAY_OF_MONTH, 1);
|
||||
$cal->set(\IntlCalendar::FIELD_HOUR_OF_DAY, 0);
|
||||
$cal->set(\IntlCalendar::FIELD_MINUTE, 0);
|
||||
$cal->set(\IntlCalendar::FIELD_SECOND, 0);
|
||||
$cal->set(\IntlCalendar::FIELD_MILLISECOND, 0);
|
||||
|
||||
return (int) ($cal->getTime() / 1000);
|
||||
}
|
||||
|
||||
/** یک نوبت در لحظهٔ دادهشده. */
|
||||
private function appointmentAt(Doctor $doctor, User $patient, int $start): void
|
||||
{
|
||||
$this->em->persist($this->newAppointment($doctor, $patient, $start, $start + 1_800));
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
public function testDoctorMonthCounterResetsOnTheJalaliMonthBoundary(): void
|
||||
{
|
||||
$owner = $this->createUser(['ROLE_DOCTOR']);
|
||||
$doctor = new Doctor($owner, 'حمیدی');
|
||||
$this->em->persist($doctor);
|
||||
$this->em->flush();
|
||||
|
||||
$start = $this->jalaliMonthStart();
|
||||
|
||||
// یکی داخل ماه شمسی جاری، یکی درست پیش از آغازش.
|
||||
$this->appointmentAt($doctor, $this->createUser(['ROLE_USER']), $start + 3_600);
|
||||
$this->appointmentAt($doctor, $this->createUser(['ROLE_USER']), $start - 3_600);
|
||||
|
||||
$res = $this->authJson('GET', '/api/v1/dashboard/doctor', $owner);
|
||||
|
||||
self::assertSame(200, $this->responseCode());
|
||||
self::assertSame(
|
||||
1,
|
||||
$res['data']['stats']['this_month_appointments'],
|
||||
'فقط نوبتِ پس از آغاز ماه شمسی باید شمرده شود',
|
||||
);
|
||||
}
|
||||
|
||||
public function testClinicMonthCounterResetsOnTheJalaliMonthBoundary(): void
|
||||
{
|
||||
$clinicOwner = $this->createUser(['ROLE_CLINIC']);
|
||||
$clinic = new Clinic($clinicOwner);
|
||||
$clinic->setName('کلینیک نمونه');
|
||||
|
||||
$docOwner = $this->createUser(['ROLE_DOCTOR']);
|
||||
$doctor = new Doctor($docOwner, 'حمیدی');
|
||||
$clinic->getDoctors()->add($doctor);
|
||||
|
||||
$this->em->persist($doctor);
|
||||
$this->em->persist($clinic);
|
||||
$this->em->flush();
|
||||
|
||||
$start = $this->jalaliMonthStart();
|
||||
|
||||
$this->appointmentAt($doctor, $this->createUser(['ROLE_USER']), $start + 3_600);
|
||||
$this->appointmentAt($doctor, $this->createUser(['ROLE_USER']), $start - 3_600);
|
||||
|
||||
$res = $this->authJson('GET', '/api/v1/dashboard/clinic', $clinicOwner);
|
||||
|
||||
self::assertSame(200, $this->responseCode());
|
||||
self::assertSame(
|
||||
1,
|
||||
$res['data']['stats']['this_month_appointments'],
|
||||
'فقط نوبتِ پس از آغاز ماه شمسی باید شمرده شود',
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user