- M2 GET /insurance/{id}: was unguarded; now owner-or-admin (403 otherwise) —
stops reading another doctor's negotiated price by id enumeration.
- M3 GET /clinic-pro/doctor-address/{id}: add the same owner/admin check the
sibling PATCH/DELETE already had.
- M4 POST/PATCH /service-item: staff_uuid must belong to the caller's tenant
(entity_type/entity_id) → 422; stops binding another tenant's staff.
- M5 appointment-settings list endpoints (date-override/holidays/
available-locations): add the per-doctor ownership check the sibling
single-record endpoints already enforce.
Regressions (6 negative cases fail without the fixes):
DoctorInsuranceOwnershipTest, DoctorAddressOwnershipTest,
ServiceItemStaffOwnershipTest, AppointmentSettingsListOwnershipTest.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53 lines
1.6 KiB
PHP
53 lines
1.6 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Appointment;
|
|
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Tests\ApiTestCase;
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
|
|
/**
|
|
* The appointment-settings list endpoints (date-overrides, holidays,
|
|
* available-locations) must not leak another doctor's configuration.
|
|
*/
|
|
class AppointmentSettingsListOwnershipTest extends ApiTestCase
|
|
{
|
|
private function makeDoctor(): Doctor
|
|
{
|
|
$doctor = new Doctor($this->createUser(['ROLE_DOCTOR']), 'دکتر');
|
|
$this->em->persist($doctor);
|
|
$this->em->flush();
|
|
|
|
return $doctor;
|
|
}
|
|
|
|
/** @return iterable<string, array{0: string}> */
|
|
public static function endpoints(): iterable
|
|
{
|
|
yield 'date-override list' => ['/api/v1/appointment-settings/date-override/list/'];
|
|
yield 'holidays list' => ['/api/v1/appointment-settings/holidays/list/'];
|
|
yield 'available-locations' => ['/api/v1/appointment-settings/available-locations/'];
|
|
}
|
|
|
|
#[DataProvider('endpoints')]
|
|
public function testStrangerForbidden(string $prefix): void
|
|
{
|
|
$doctor = $this->makeDoctor();
|
|
$stranger = $this->createUser(['ROLE_DOCTOR']);
|
|
|
|
$this->authJson('GET', $prefix . $doctor->getUuid(), $stranger);
|
|
|
|
$this->assertSame(403, $this->responseCode());
|
|
}
|
|
|
|
#[DataProvider('endpoints')]
|
|
public function testOwnerAllowed(string $prefix): void
|
|
{
|
|
$doctor = $this->makeDoctor();
|
|
|
|
$this->authJson('GET', $prefix . $doctor->getUuid(), $doctor->getUser());
|
|
|
|
$this->assertSame(200, $this->responseCode());
|
|
}
|
|
}
|