Files
clinicpro/tests/Category/AdminCategorySearchTest.php
T

195 lines
7.9 KiB
PHP

<?php
namespace App\Tests\Category;
use App\Tests\ApiTestCase;
/**
* search=… on the admin category lists must reach the parent, not just the row's
* own name — operators look a child up by the name of the thing that owns it
* ("all services under Dermatology"), and by slug when they paste one from a URL.
*
* Covers: /admin/specialties (parent specialty), /admin/doctor-services
* (specialty), /admin/cities (province).
*/
class AdminCategorySearchTest extends ApiTestCase
{
/** @return list<int> */
private function idsOf(array $body): array
{
return array_map(static fn(array $r) => (int) $r['id'], $body['data']);
}
private function createdId(array $body): int
{
return (int) $body['data']['data']['id'];
}
// ── specialties ───────────────────────────────────────────────────────────
public function testSpecialtySearchByParentNameReturnsChildren(): void
{
$admin = $this->createUser(['ROLE_ADMIN']);
$marker = 'پوستآزمون' . uniqid();
$parentId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/specialty', $admin, ['name' => $marker])
);
$childId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/specialty', $admin, ['name' => 'لیزر درمانی ' . uniqid(), 'parent_id' => $parentId])
);
$unrelatedId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/specialty', $admin, ['name' => 'قلب' . uniqid()])
);
$body = $this->authJson('GET', '/api/v1/admin/specialties?limit=100&search=' . urlencode($marker), $admin);
self::assertSame(200, $this->responseCode());
$ids = $this->idsOf($body);
self::assertContains($childId, $ids, 'فرزند باید با نام والد پیدا شود');
self::assertContains($parentId, $ids, 'خودِ والد هم باید بماند');
self::assertNotContains($unrelatedId, $ids);
}
public function testSpecialtyRowCarriesParentName(): void
{
$admin = $this->createUser(['ROLE_ADMIN']);
$marker = 'والدآزمون' . uniqid();
$parentId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/specialty', $admin, ['name' => $marker])
);
$this->authJson('POST', '/api/v1/admin/specialty', $admin, ['name' => 'زیرشاخه ' . uniqid(), 'parent_id' => $parentId]);
$body = $this->authJson('GET', '/api/v1/admin/specialties?limit=100&search=' . urlencode($marker), $admin);
$child = null;
foreach ($body['data'] as $row) {
if ((int) ($row['parent_id'] ?? 0) === $parentId) $child = $row;
}
self::assertNotNull($child);
self::assertSame($marker, $child['parent_name']);
}
public function testSpecialtySearchBySlugStillMatches(): void
{
$admin = $this->createUser(['ROLE_ADMIN']);
$slug = 'slug-test-' . uniqid();
$id = $this->createdId(
$this->authJson('POST', '/api/v1/admin/specialty', $admin, ['name' => 'نام دلخواه ' . uniqid(), 'slug' => $slug])
);
$body = $this->authJson('GET', '/api/v1/admin/specialties?limit=100&search=' . urlencode($slug), $admin);
self::assertContains($id, $this->idsOf($body));
}
// ── doctor services ───────────────────────────────────────────────────────
public function testDoctorServiceSearchBySpecialtyName(): void
{
$admin = $this->createUser(['ROLE_ADMIN']);
$marker = 'تخصصآزمون' . uniqid();
$specialtyId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/specialty', $admin, ['name' => $marker])
);
$serviceId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/doctor-service', $admin, ['name' => 'بوتاکس ' . uniqid(), 'specialty_id' => $specialtyId])
);
$unrelatedId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/doctor-service', $admin, ['name' => 'اکو' . uniqid()])
);
$body = $this->authJson('GET', '/api/v1/admin/doctor-services?limit=100&search=' . urlencode($marker), $admin);
self::assertSame(200, $this->responseCode());
$ids = $this->idsOf($body);
self::assertContains($serviceId, $ids);
self::assertNotContains($unrelatedId, $ids);
$row = null;
foreach ($body['data'] as $r) {
if ((int) $r['id'] === $serviceId) $row = $r;
}
self::assertSame($marker, $row['specialty_name']);
}
public function testDoctorServiceWithoutSpecialtyIsStillListed(): void
{
$admin = $this->createUser(['ROLE_ADMIN']);
$marker = 'خدمتتنها' . uniqid();
$id = $this->createdId(
$this->authJson('POST', '/api/v1/admin/doctor-service', $admin, ['name' => $marker])
);
$body = $this->authJson('GET', '/api/v1/admin/doctor-services?limit=100&search=' . urlencode($marker), $admin);
$ids = $this->idsOf($body);
self::assertContains($id, $ids, 'LEFT JOIN نباید ردیفِ بدون تخصص را حذف کند');
self::assertSame(1, $body['meta']['totalRecords']);
}
// ── cities ────────────────────────────────────────────────────────────────
public function testCitySearchByProvinceName(): void
{
$admin = $this->createUser(['ROLE_ADMIN']);
$marker = 'استانآزمون' . uniqid();
$provinceId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/province', $admin, ['name' => $marker])
);
$cityId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/city', $admin, ['name' => 'شهر یک ' . uniqid(), 'province_id' => $provinceId])
);
$unrelatedId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/city', $admin, ['name' => 'شهر دو' . uniqid()])
);
$body = $this->authJson('GET', '/api/v1/admin/cities?limit=100&search=' . urlencode($marker), $admin);
self::assertSame(200, $this->responseCode());
$ids = $this->idsOf($body);
self::assertContains($cityId, $ids);
self::assertNotContains($unrelatedId, $ids);
}
public function testCitySearchByDomain(): void
{
$admin = $this->createUser(['ROLE_ADMIN']);
$domain = 'search-test-' . uniqid() . '.example';
$cityId = $this->createdId(
$this->authJson('POST', '/api/v1/admin/city', $admin, ['name' => 'شهر دامنه‌دار ' . uniqid(), 'domain' => $domain])
);
$body = $this->authJson('GET', '/api/v1/admin/cities?limit=100&search=' . urlencode($domain), $admin);
self::assertContains($cityId, $this->idsOf($body));
}
// ── boundaries ────────────────────────────────────────────────────────────
public function testUnknownTermReturnsEmptyList(): void
{
$admin = $this->createUser(['ROLE_ADMIN']);
$body = $this->authJson('GET', '/api/v1/admin/specialties?search=' . urlencode('چنینچیزینیست' . uniqid()), $admin);
self::assertSame(200, $this->responseCode());
self::assertSame([], $body['data']);
self::assertSame(0, $body['meta']['totalRecords']);
}
public function testNonAdminForbidden(): void
{
$user = $this->createUser(['ROLE_USER']);
$this->authJson('GET', '/api/v1/admin/specialties?search=x', $user);
self::assertSame(403, $this->responseCode());
}
}