feat: refactor clinic management into a dedicated settings tab
- Removed MyClinicPage and redirected its functionality to a new ClinicDoctorsPage. - Created ClinicDoctorsManager component for managing doctors and invitations within the settings layout. - Updated backend permissions to allow clinic owners to detach doctors, alongside admins. - Adjusted API documentation to reflect new permission structure. - Updated tests to cover new functionality and permissions. - Modified sidebar and settings menu to reflect the new structure and role-based visibility.
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Clinic;
|
||||
|
||||
use App\Clinic\Entity\Clinic;
|
||||
use App\Doctor\Entity\Doctor;
|
||||
use App\Tests\ApiTestCase;
|
||||
|
||||
/**
|
||||
* Detaching a doctor from a clinic is allowed for an admin OR the clinic owner.
|
||||
* Any other authenticated user (incl. a foreign clinic owner or a plain doctor)
|
||||
* must be rejected with 403.
|
||||
*/
|
||||
class DetachDoctorPermissionTest extends ApiTestCase
|
||||
{
|
||||
/** @return array{0: Clinic, 1: Doctor} */
|
||||
private function makeClinicWithDoctor(): array
|
||||
{
|
||||
$clinic = new Clinic($this->createUser(['ROLE_CLINIC']));
|
||||
$this->em->persist($clinic);
|
||||
|
||||
$doctor = new Doctor($this->createUser(['ROLE_DOCTOR']), 'دکتر آزمایشی');
|
||||
$this->em->persist($doctor);
|
||||
$clinic->getDoctors()->add($doctor);
|
||||
$this->em->flush();
|
||||
|
||||
return [$clinic, $doctor];
|
||||
}
|
||||
|
||||
private function detachUri(Clinic $clinic, Doctor $doctor): string
|
||||
{
|
||||
return '/api/v1/admin/clinic/' . $clinic->getUuid() . '/doctor/' . $doctor->getUuid();
|
||||
}
|
||||
|
||||
public function testClinicOwnerCanDetachOwnDoctor(): void
|
||||
{
|
||||
[$clinic, $doctor] = $this->makeClinicWithDoctor();
|
||||
$owner = $clinic->getUser();
|
||||
|
||||
$body = $this->authJson('DELETE', $this->detachUri($clinic, $doctor), $owner);
|
||||
|
||||
$this->assertSame(200, $this->responseCode());
|
||||
$this->assertTrue($body['success']);
|
||||
}
|
||||
|
||||
public function testAdminCanDetachAnyDoctor(): void
|
||||
{
|
||||
[$clinic, $doctor] = $this->makeClinicWithDoctor();
|
||||
$admin = $this->createUser(['ROLE_ADMIN']);
|
||||
|
||||
$body = $this->authJson('DELETE', $this->detachUri($clinic, $doctor), $admin);
|
||||
|
||||
$this->assertSame(200, $this->responseCode());
|
||||
$this->assertTrue($body['success']);
|
||||
}
|
||||
|
||||
public function testForeignClinicOwnerIsForbidden(): void
|
||||
{
|
||||
[$clinic, $doctor] = $this->makeClinicWithDoctor();
|
||||
$intruder = $this->createUser(['ROLE_CLINIC']);
|
||||
|
||||
$body = $this->authJson('DELETE', $this->detachUri($clinic, $doctor), $intruder);
|
||||
|
||||
$this->assertSame(403, $this->responseCode());
|
||||
$this->assertFalse($body['success']);
|
||||
$this->assertSame('ERR_ACCESS_DENIED', $body['errors'][0]['code']);
|
||||
}
|
||||
|
||||
public function testPlainDoctorIsForbidden(): void
|
||||
{
|
||||
[$clinic, $doctor] = $this->makeClinicWithDoctor();
|
||||
$otherDoctor = $this->createUser(['ROLE_DOCTOR']);
|
||||
|
||||
$this->authJson('DELETE', $this->detachUri($clinic, $doctor), $otherDoctor);
|
||||
|
||||
$this->assertSame(403, $this->responseCode());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user