- Updated date handling in BlogSeoFields and ScheduleSection to use Tehran timezone utilities for consistency. - Introduced `toTehranClockTime`, `tehranWallClockToUnix`, and `todayIso` functions for accurate date representation. - Modified various components to utilize these new utilities, ensuring that date strings are correctly formatted and timestamps are accurately converted. - Enhanced API documentation to clarify the handling of date fields, emphasizing the importance of server-local midnight. - Added tests to verify that date overrides and holidays maintain the correct day without shifting due to timezone discrepancies.
113 lines
4.3 KiB
PHP
113 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Appointment;
|
|
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Tests\ApiTestCase;
|
|
|
|
/**
|
|
* تاریخ خاص و تعطیلات باید دقیقاً همان روزِ ارسالی را نگه دارند: timestamp روی
|
|
* نیمهشبِ محلی و یک رشتهٔ `Y-m-d` کانونی در پاسخ، تا کلاینت مجبور به تبدیل
|
|
* timestamp (و جابهجایی یکروزه بهخاطر UTC) نباشد.
|
|
*/
|
|
class SpecialDateBoundaryTest extends ApiTestCase
|
|
{
|
|
private function makeDoctor(): Doctor
|
|
{
|
|
$owner = $this->createUser(['ROLE_DOCTOR']);
|
|
$doctor = new Doctor($owner, 'دکتر تاریخ');
|
|
$this->em->persist($doctor);
|
|
$this->em->flush();
|
|
|
|
return $doctor;
|
|
}
|
|
|
|
public function testOverrideKeepsExactDayAndReturnsDateString(): void
|
|
{
|
|
$doctor = $this->makeDoctor();
|
|
$date = date('Y-m-d', strtotime('+9 days'));
|
|
|
|
$body = $this->authJson('POST', '/api/v1/appointment-settings/date-override', $doctor->getUser(), [
|
|
'doctor_uuid' => $doctor->getUuid(),
|
|
'date' => $date,
|
|
'active' => false,
|
|
]);
|
|
|
|
self::assertSame(201, $this->responseCode());
|
|
self::assertSame($date, $body['data']['data']['date_string']);
|
|
self::assertSame((int) strtotime($date . ' 00:00:00'), $body['data']['data']['date']);
|
|
self::assertSame($date, date('Y-m-d', $body['data']['data']['date']));
|
|
}
|
|
|
|
public function testOverrideNormalizesTimestampWithTimeToLocalMidnight(): void
|
|
{
|
|
$doctor = $this->makeDoctor();
|
|
$date = date('Y-m-d', strtotime('+10 days'));
|
|
|
|
// ورودی ISO با ساعت (مثل چیزی که toISOString مرورگر میسازد) نباید روز را جابهجا کند.
|
|
$body = $this->authJson('POST', '/api/v1/appointment-settings/date-override', $doctor->getUser(), [
|
|
'doctor_uuid' => $doctor->getUuid(),
|
|
'date' => $date . ' 23:45:00',
|
|
'active' => false,
|
|
]);
|
|
|
|
self::assertSame(201, $this->responseCode());
|
|
self::assertSame($date, $body['data']['data']['date_string']);
|
|
self::assertSame((int) strtotime($date . ' 00:00:00'), $body['data']['data']['date']);
|
|
}
|
|
|
|
public function testOverridePatchKeepsExactDay(): void
|
|
{
|
|
$doctor = $this->makeDoctor();
|
|
$first = date('Y-m-d', strtotime('+11 days'));
|
|
$second = date('Y-m-d', strtotime('+12 days'));
|
|
|
|
$created = $this->authJson('POST', '/api/v1/appointment-settings/date-override', $doctor->getUser(), [
|
|
'doctor_uuid' => $doctor->getUuid(),
|
|
'date' => $first,
|
|
'active' => false,
|
|
]);
|
|
$uuid = $created['data']['data']['uuid'];
|
|
|
|
$patched = $this->authJson('PATCH', "/api/v1/appointment-settings/date-override/{$uuid}", $doctor->getUser(), [
|
|
'date' => $second,
|
|
]);
|
|
|
|
self::assertSame(200, $this->responseCode());
|
|
self::assertSame($second, $patched['data']['data']['date_string']);
|
|
}
|
|
|
|
public function testHolidayKeepsExactDaysAndReturnsDateStrings(): void
|
|
{
|
|
$doctor = $this->makeDoctor();
|
|
$start = date('Y-m-d', strtotime('+13 days'));
|
|
$end = date('Y-m-d', strtotime('+15 days'));
|
|
|
|
$body = $this->authJson('POST', '/api/v1/appointment-settings/holidays', $doctor->getUser(), [
|
|
'doctor_uuid' => $doctor->getUuid(),
|
|
'start_date' => $start,
|
|
'end_date' => $end,
|
|
'reason' => 'سفر',
|
|
]);
|
|
|
|
self::assertSame(201, $this->responseCode());
|
|
self::assertSame($start, $body['data']['data']['start_date_string']);
|
|
self::assertSame($end, $body['data']['data']['end_date_string']);
|
|
self::assertSame((int) strtotime($start . ' 00:00:00'), $body['data']['data']['start_date']);
|
|
self::assertSame((int) strtotime($end . ' 00:00:00'), $body['data']['data']['end_date']);
|
|
}
|
|
|
|
public function testInvalidDateIsRejected(): void
|
|
{
|
|
$doctor = $this->makeDoctor();
|
|
|
|
$this->authJson('POST', '/api/v1/appointment-settings/date-override', $doctor->getUser(), [
|
|
'doctor_uuid' => $doctor->getUuid(),
|
|
'date' => 'not-a-date',
|
|
'active' => false,
|
|
]);
|
|
|
|
self::assertSame(422, $this->responseCode());
|
|
}
|
|
}
|