import { describe, expect, it } from "vitest"; import specialtiesData from "@/data/specialties.json"; import { QueryForDoctorsFilter, QueryForDoctorsReq, filterList, nextSpecialtyFilter, } from "@/helper"; const byName = (name) => specialtiesData.find((s) => s.name === name); const GENERAL_SURGERY = byName("جراحی عمومی"); describe("filterList — گزینهٔ «همه تخصص‌های X»", () => { it("بدون گروه، فهرست زیرتخصص خالی است", () => { expect(filterList({}).childrenList).toEqual([]); expect(filterList(null).childrenList).toEqual([]); }); it("با گروه، «همه» اولین گزینه است و id گروه را ندارد", () => { const { childrenList } = filterList({ category: GENERAL_SURGERY }); expect(childrenList[0]).toMatchObject({ id: null, isAll: true, name: `همه تخصص‌های ${GENERAL_SURGERY.name}`, }); }); it("زیرتخصص‌های واقعی بعد از «همه» می‌آیند", () => { const { childrenList } = filterList({ category: GENERAL_SURGERY }); const real = childrenList.slice(1); expect(real.length).toBeGreaterThan(0); expect( real.every((s) => String(s.parent_id) === String(GENERAL_SURGERY.id)) ).toBe(true); }); it("زیرتخصص‌های تازهٔ همگام‌شده هم در فهرست هستند", () => { // این پنج تا در اسنپ‌شات دستیِ قبلی نبودند؛ اگر همگام‌سازی برگردد، اینجا قرمز می‌شود. const names = filterList({ category: GENERAL_SURGERY }).childrenList.map( (s) => s.name ); expect(names).toContain("جراح گوارش"); expect(names).toContain("جراح تیروئید"); }); it("گروهِ بدون زیرشاخه گزینهٔ «همه» نمی‌گیرد", () => { const leafRoot = specialtiesData.find( (s) => !s.parent_id && !specialtiesData.some((c) => String(c.parent_id) === String(s.id)) ); expect(filterList({ category: leafRoot }).childrenList).toEqual([]); }); it("فهرست گروه‌ها فقط ریشه‌هاست", () => { expect(filterList({}).parentList.every((s) => !s.parent_id)).toBe(true); }); }); describe("nextSpecialtyFilter — قاعدهٔ انتخاب", () => { it("انتخاب گروه، زیرتخصص را تهی می‌گذارد نه اولین فرزند", () => { const firstChild = filterList({ category: GENERAL_SURGERY }).childrenList[1]; const next = nextSpecialtyFilter({}, "category", GENERAL_SURGERY); expect(next.category).toBe(GENERAL_SURGERY); expect(next.specialty).toBeNull(); expect(next.specialty).not.toEqual(firstChild); }); it("عوض کردن گروه، زیرتخصصِ گروه قبلی را پاک می‌کند", () => { const child = filterList({ category: GENERAL_SURGERY }).childrenList[1]; const other = specialtiesData.find( (s) => !s.parent_id && s.id !== GENERAL_SURGERY.id ); const next = nextSpecialtyFilter( { category: GENERAL_SURGERY, specialty: child }, "category", other ); expect(next.specialty).toBeNull(); }); it("انتخاب «همه» زیرتخصص را تهی می‌کند", () => { const all = filterList({ category: GENERAL_SURGERY }).childrenList[0]; const next = nextSpecialtyFilter( { category: GENERAL_SURGERY }, "specialty", all ); expect(next.specialty).toBeNull(); }); it("انتخاب یک زیرتخصص واقعی همان را می‌نشاند", () => { const child = filterList({ category: GENERAL_SURGERY }).childrenList[1]; const next = nextSpecialtyFilter( { category: GENERAL_SURGERY }, "specialty", child ); expect(next.specialty).toBe(child); }); it("پاک کردن گروه هر دو را تهی می‌کند", () => { const next = nextSpecialtyFilter( { category: GENERAL_SURGERY, specialty: { id: 1 } }, "category", null ); expect(next.category).toBeNull(); expect(next.specialty).toBeNull(); }); it("فیلترهای دیگر دست‌نخورده می‌مانند", () => { const next = nextSpecialtyFilter( { city: { id: 7 }, gender: "زن" }, "category", GENERAL_SURGERY ); expect(next.city).toEqual({ id: 7 }); expect(next.gender).toBe("زن"); }); }); describe("انتخاب کل گروه — پارامترها", () => { it("بدون زیرتخصص، درخواست با شناسهٔ گروه می‌رود", () => { // بک‌اند specialty_id را به همهٔ زیرشاخه‌ها گسترش می‌دهد. const params = QueryForDoctorsReq({ category: GENERAL_SURGERY, specialty: null }); expect(params.specialty_id).toBe(GENERAL_SURGERY.id); }); it("با زیرتخصص، همان زیرتخصص بر گروه مقدم است", () => { const child = filterList({ category: GENERAL_SURGERY }).childrenList[1]; const params = QueryForDoctorsReq({ category: GENERAL_SURGERY, specialty: child }); expect(params.specialty_id).toBe(child.id); }); it("URL نام گروه را می‌گیرد، نه عنوان مصنوعیِ «همه …»", () => { // عنوان «همه تخصص‌های …» در specialties.json نیست؛ اگر در URL می‌نشست، // با رفرش یا اشتراک لینک بازسازی نمی‌شد. const query = QueryForDoctorsFilter({ category: GENERAL_SURGERY, specialty: null }); expect(query.specialty).toBe(GENERAL_SURGERY.name); expect(specialtiesData.some((s) => s.name === query.specialty)).toBe(true); }); it("نامِ رفته در URL همیشه در فایل تخصص‌ها پیدا می‌شود", () => { const child = filterList({ category: GENERAL_SURGERY }).childrenList[1]; const query = QueryForDoctorsFilter({ category: GENERAL_SURGERY, specialty: child }); expect(specialtiesData.some((s) => s.name === query.specialty)).toBe(true); }); });