The service page could not say which category a service belongs to, so the
containment edges defined in settings had nothing to match against.
A Categories tab now selects one — and only selects. Creating, renaming and
deleting stay in Settings > Categories: if every page could create one,
"whole body" would exist three times with three spellings and the
includes edge would stop catching anything.
PATCH /api/v1/service-item/{uuid} carries the choice as
catalog_category_uuid. Absent field leaves the current category alone, null
clears it, and a category from another environment is refused with 422 —
the uuid arrives in the request body where TenantFilter does not reach.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
102 lines
4.3 KiB
PHP
102 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\ClinicService;
|
|
|
|
use App\Auth\Entity\User;
|
|
use App\ClinicService\Entity\ServiceItem;
|
|
use App\ClinicService\Entity\ServiceSection;
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Tests\ApiTestCase;
|
|
|
|
/**
|
|
* تب «دستهبندیها»ی صفحهٔ سرویس فقط **انتخاب** میکند و همین `PATCH` پشتش است.
|
|
*
|
|
* دسته ساخته نمیشود؛ ساختش فقط از «تنظیمات ← دستهبندیها» است. اینجا اثبات میشود که
|
|
* انتخاب مینشیند، پاک میشود، و دستهٔ محیط دیگر رد میشود.
|
|
*/
|
|
class ServiceItemCatalogCategoryTest extends ApiTestCase
|
|
{
|
|
/** @return array{0: User, 1: ServiceItem} */
|
|
private function doctorWithItem(): array
|
|
{
|
|
$owner = $this->createUser(['ROLE_DOCTOR']);
|
|
$doctor = new Doctor($owner, 'دکتر دستهبندی');
|
|
$this->em->persist($doctor);
|
|
$this->em->flush();
|
|
|
|
$section = new ServiceSection('doctor', $doctor->getId(), 'لیزر');
|
|
$item = new ServiceItem($section, 'لیزر دست');
|
|
$item->setPriceRials(5_000_000);
|
|
$this->em->persist($section);
|
|
$this->em->persist($item);
|
|
$this->em->flush();
|
|
|
|
return [$owner, $item];
|
|
}
|
|
|
|
private function category(User $user, string $name): string
|
|
{
|
|
$body = $this->authJson('POST', '/api/v1/service-category', $user, ['name' => $name]);
|
|
self::assertSame(201, $this->responseCode(), json_encode($body, JSON_UNESCAPED_UNICODE));
|
|
|
|
return $body['data']['uuid'];
|
|
}
|
|
|
|
// ── ✅ موفق ──────────────────────────────────────────────────────────────
|
|
|
|
public function testAServiceTakesAGlobalCategory(): void
|
|
{
|
|
[$owner, $item] = $this->doctorWithItem();
|
|
$hand = $this->category($owner, 'دست');
|
|
|
|
$body = $this->authJson('PATCH', '/api/v1/service-item/' . $item->getUuid(), $owner, [
|
|
'catalog_category_uuid' => $hand,
|
|
]);
|
|
|
|
self::assertSame(200, $this->responseCode(), json_encode($body, JSON_UNESCAPED_UNICODE));
|
|
self::assertSame($hand, $body['data']['catalog_category_uuid']);
|
|
}
|
|
|
|
public function testNullClearsTheCategory(): void
|
|
{
|
|
[$owner, $item] = $this->doctorWithItem();
|
|
$hand = $this->category($owner, 'دست');
|
|
|
|
$this->authJson('PATCH', '/api/v1/service-item/' . $item->getUuid(), $owner, ['catalog_category_uuid' => $hand]);
|
|
$body = $this->authJson('PATCH', '/api/v1/service-item/' . $item->getUuid(), $owner, ['catalog_category_uuid' => null]);
|
|
|
|
self::assertSame(200, $this->responseCode());
|
|
self::assertNull($body['data']['catalog_category_uuid']);
|
|
}
|
|
|
|
// ── ⚠️ مرزی ─────────────────────────────────────────────────────────────
|
|
|
|
public function testNotSendingTheFieldLeavesTheCategoryAlone(): void
|
|
{
|
|
[$owner, $item] = $this->doctorWithItem();
|
|
$hand = $this->category($owner, 'دست');
|
|
|
|
$this->authJson('PATCH', '/api/v1/service-item/' . $item->getUuid(), $owner, ['catalog_category_uuid' => $hand]);
|
|
// فیلد در بدنه نیست: ویرایش نام نباید دسته را پاک کند.
|
|
$body = $this->authJson('PATCH', '/api/v1/service-item/' . $item->getUuid(), $owner, ['name' => 'لیزر دست کامل']);
|
|
|
|
self::assertSame($hand, $body['data']['catalog_category_uuid']);
|
|
}
|
|
|
|
// ── ❌ خطا ───────────────────────────────────────────────────────────────
|
|
|
|
public function testACategoryFromAnotherEnvironmentIsRefused(): void
|
|
{
|
|
[$owner, $item] = $this->doctorWithItem();
|
|
[$stranger] = $this->doctorWithItem();
|
|
|
|
$foreign = $this->category($stranger, 'دستهٔ پزشک دیگر');
|
|
|
|
$this->authJson('PATCH', '/api/v1/service-item/' . $item->getUuid(), $owner, [
|
|
'catalog_category_uuid' => $foreign,
|
|
]);
|
|
|
|
self::assertSame(422, $this->responseCode());
|
|
}
|
|
}
|