195 lines
7.9 KiB
PHP
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());
|
|
}
|
|
}
|