- Implemented PATCH endpoints for changing the login mobile number of doctors and clinics. - Added ChangeLoginMobileModal component for handling mobile number updates in the UI. - Updated ClinicsPage and DoctorsPage to include buttons for changing mobile numbers. - Enhanced AdminApiController to manage mobile number changes with validation. - Created tests to ensure proper functionality and validation for mobile number changes. - Updated API documentation to reflect new endpoints and their usage.
162 lines
5.5 KiB
PHP
162 lines
5.5 KiB
PHP
<?php
|
||
|
||
namespace App\Tests\Admin;
|
||
|
||
use App\Auth\Entity\User;
|
||
use App\Clinic\Entity\Clinic;
|
||
use App\Doctor\Entity\Doctor;
|
||
use App\Tests\ApiTestCase;
|
||
|
||
/**
|
||
* مدیر کل میتواند شمارهٔ **ورود** پزشک/کلینیک را عوض کند. شماره هویتِ ورود است، پس
|
||
* یکتا بودنش کنترل میشود و شمارهٔ نمایشیِ پزشک هم با آن همگام میماند.
|
||
*/
|
||
class AdminChangeLoginMobileTest extends ApiTestCase
|
||
{
|
||
private function newMobile(): string
|
||
{
|
||
return '09' . str_pad((string) random_int(0, 999_999_999), 9, '0', STR_PAD_LEFT);
|
||
}
|
||
|
||
private function makeDoctor(): Doctor
|
||
{
|
||
$user = $this->createUser(['ROLE_USER', 'ROLE_DOCTOR']);
|
||
$doctor = new Doctor($user, 'دکتر تغییر شماره');
|
||
$doctor->setMobileNumber($user->getMobileNumber());
|
||
$this->em->persist($doctor);
|
||
$this->em->flush();
|
||
|
||
return $doctor;
|
||
}
|
||
|
||
private function makeClinic(): Clinic
|
||
{
|
||
$clinic = new Clinic($this->createUser(['ROLE_USER', 'ROLE_CLINIC']));
|
||
$clinic->setName('کلینیک تغییر شماره');
|
||
$this->em->persist($clinic);
|
||
$this->em->flush();
|
||
|
||
return $clinic;
|
||
}
|
||
|
||
private function reloadUser(int $id): User
|
||
{
|
||
$this->em->clear();
|
||
|
||
return $this->em->getRepository(User::class)->find($id);
|
||
}
|
||
|
||
public function testAdminChangesDoctorLoginMobile(): void
|
||
{
|
||
$admin = $this->createUser(['ROLE_ADMIN']);
|
||
$doctor = $this->makeDoctor();
|
||
$userId = $doctor->getUser()->getId();
|
||
$mobile = $this->newMobile();
|
||
|
||
$body = $this->authJson('PATCH', '/api/v1/admin/doctors/' . $doctor->getUuid() . '/mobile', $admin, [
|
||
'mobile_number' => $mobile,
|
||
]);
|
||
|
||
self::assertSame(200, $this->responseCode());
|
||
self::assertSame($mobile, $body['data']['data']['mobile_number']);
|
||
self::assertSame($mobile, $this->reloadUser($userId)->getMobileNumber());
|
||
}
|
||
|
||
/** شمارهٔ نمایشیِ پزشک وقتی با شمارهٔ ورود یکی بوده باید همراهش بهروز شود. */
|
||
public function testDoctorDisplayMobileFollowsTheLoginMobile(): void
|
||
{
|
||
$admin = $this->createUser(['ROLE_ADMIN']);
|
||
$doctor = $this->makeDoctor();
|
||
$id = $doctor->getId();
|
||
$mobile = $this->newMobile();
|
||
|
||
$this->authJson('PATCH', '/api/v1/admin/doctors/' . $doctor->getUuid() . '/mobile', $admin, [
|
||
'mobile_number' => $mobile,
|
||
]);
|
||
$this->em->clear();
|
||
|
||
self::assertSame($mobile, $this->em->getRepository(Doctor::class)->find($id)->getMobileNumber());
|
||
}
|
||
|
||
public function testAdminChangesClinicLoginMobile(): void
|
||
{
|
||
$admin = $this->createUser(['ROLE_ADMIN']);
|
||
$clinic = $this->makeClinic();
|
||
$userId = $clinic->getUser()->getId();
|
||
$mobile = $this->newMobile();
|
||
|
||
$this->authJson('PATCH', '/api/v1/admin/clinic/' . $clinic->getUuid() . '/mobile', $admin, [
|
||
'mobile_number' => $mobile,
|
||
]);
|
||
|
||
self::assertSame(200, $this->responseCode());
|
||
self::assertSame($mobile, $this->reloadUser($userId)->getMobileNumber());
|
||
}
|
||
|
||
public function testDuplicateMobileIsRejected(): void
|
||
{
|
||
$admin = $this->createUser(['ROLE_ADMIN']);
|
||
$doctor = $this->makeDoctor();
|
||
$taken = $this->createUser(['ROLE_USER'])->getMobileNumber();
|
||
|
||
$this->authJson('PATCH', '/api/v1/admin/doctors/' . $doctor->getUuid() . '/mobile', $admin, [
|
||
'mobile_number' => $taken,
|
||
]);
|
||
|
||
self::assertSame(409, $this->responseCode());
|
||
}
|
||
|
||
public function testInvalidMobileIsRejected(): void
|
||
{
|
||
$admin = $this->createUser(['ROLE_ADMIN']);
|
||
$doctor = $this->makeDoctor();
|
||
|
||
$this->authJson('PATCH', '/api/v1/admin/doctors/' . $doctor->getUuid() . '/mobile', $admin, [
|
||
'mobile_number' => '12345',
|
||
]);
|
||
|
||
self::assertSame(422, $this->responseCode());
|
||
}
|
||
|
||
public function testPersianDigitsAreAccepted(): void
|
||
{
|
||
$admin = $this->createUser(['ROLE_ADMIN']);
|
||
$doctor = $this->makeDoctor();
|
||
$userId = $doctor->getUser()->getId();
|
||
|
||
// db_test بین اجراها پاک نمیشود؛ شمارهٔ ثابت در اجرای دوم تکراری میشد.
|
||
$latin = $this->newMobile();
|
||
$persian = strtr($latin, ['0' => '۰', '1' => '۱', '2' => '۲', '3' => '۳', '4' => '۴',
|
||
'5' => '۵', '6' => '۶', '7' => '۷', '8' => '۸', '9' => '۹']);
|
||
|
||
$this->authJson('PATCH', '/api/v1/admin/doctors/' . $doctor->getUuid() . '/mobile', $admin, [
|
||
'mobile_number' => $persian,
|
||
]);
|
||
|
||
self::assertSame(200, $this->responseCode());
|
||
self::assertSame($latin, $this->reloadUser($userId)->getMobileNumber());
|
||
}
|
||
|
||
public function testNonAdminCannotChangeIt(): void
|
||
{
|
||
$doctor = $this->makeDoctor();
|
||
|
||
$this->authJson('PATCH', '/api/v1/admin/doctors/' . $doctor->getUuid() . '/mobile', $doctor->getUser(), [
|
||
'mobile_number' => $this->newMobile(),
|
||
]);
|
||
|
||
self::assertSame(403, $this->responseCode());
|
||
}
|
||
|
||
public function testUnknownDoctorIsNotFound(): void
|
||
{
|
||
$admin = $this->createUser(['ROLE_ADMIN']);
|
||
|
||
$this->authJson('PATCH', '/api/v1/admin/doctors/00000000-0000-4000-8000-000000000000/mobile', $admin, [
|
||
'mobile_number' => $this->newMobile(),
|
||
]);
|
||
|
||
self::assertSame(404, $this->responseCode());
|
||
}
|
||
}
|