import { describe, expect, it } from "vitest"; import { posterSpecialtyLine, splitSpecialties } from "@/lib/specialtyDisplay"; const root = { id: "13", name: "جراحی عمومی", parent_id: null }; const gi = { id: "169", name: "جراح گوارش", parent_id: "13" }; const thyroid = { id: "168", name: "جراح تیروئید", parent_id: "13" }; describe("splitSpecialties", () => { it("ریشه اصلی است، حتی اگر اول آرایه نباشد", () => { const { primary, rest } = splitSpecialties([gi, root, thyroid]); expect(primary).toBe(root); expect(rest).toEqual([gi, thyroid]); }); it("بدون ریشه، اولین آیتم اصلی است", () => { const { primary, rest } = splitSpecialties([gi, thyroid]); expect(primary).toBe(gi); expect(rest).toEqual([thyroid]); }); it("تک‌تخصص، بقیه خالی", () => { const { primary, rest } = splitSpecialties([root]); expect(primary).toBe(root); expect(rest).toEqual([]); }); it("آرایهٔ خالی و ورودی تهی → primary تهی", () => { expect(splitSpecialties([])).toEqual({ primary: null, rest: [] }); expect(splitSpecialties(null)).toEqual({ primary: null, rest: [] }); expect(splitSpecialties(undefined)).toEqual({ primary: null, rest: [] }); }); it("آیتم بدون نام حذف می‌شود", () => { const { primary, rest } = splitSpecialties([{ id: "1" }, root, gi]); expect(primary).toBe(root); expect(rest).toEqual([gi]); }); it("parent_id تهیِ رشته‌ای هم ریشه شمرده می‌شود", () => { // بک‌اند parent_id را رشته می‌دهد؛ برابریِ سست عمدی است تا null و undefined // هر دو ریشه باشند و 0 نباشد. const { primary } = splitSpecialties([ { id: "9", name: "زیرشاخه", parent_id: "13" }, { id: "13", name: "ریشه", parent_id: undefined }, ]); expect(primary.name).toBe("ریشه"); }); it("دو ریشهٔ متفاوت → اولی اصلی، دومی در بقیه", () => { const internal = { id: "2", name: "داخلی", parent_id: null }; const { primary, rest } = splitSpecialties([root, internal, gi]); expect(primary).toBe(root); expect(rest).toEqual([internal, gi]); }); }); describe("posterSpecialtyLine", () => { it("نام‌ها را با جداکنندهٔ نقطه به هم می‌چسباند", () => { const { text, hidden } = posterSpecialtyLine([gi, thyroid], 90); expect(text).toBe("جراح گوارش · جراح تیروئید"); expect(hidden).toBe(0); }); it("از بودجه که گذشت، بقیه را می‌شمارد نه می‌برد", () => { const { text, hidden } = posterSpecialtyLine([gi, thyroid], 12); expect(text).toBe("جراح گوارش"); expect(hidden).toBe(1); }); it("برش روی مرز کلمه است، نه وسط نام", () => { const { text } = posterSpecialtyLine([gi, thyroid], 15); expect(text.endsWith("…")).toBe(false); expect(text).toBe("جراح گوارش"); }); it("یک نام بلندتر از کل بودجه، بریده نمی‌شود", () => { // خط خالی با «و ۱ تخصص دیگر» بدتر از یک نام کمی بلند است. const long = { name: "جراحی لاپاراسکوپی پیشرفتهٔ کبد و مجاری صفراوی" }; const { text, hidden } = posterSpecialtyLine([long], 10); expect(text).toBe(long.name); expect(hidden).toBe(0); }); it("آرایهٔ خالی و ورودی تهی → متن تهی و صفر پنهان", () => { expect(posterSpecialtyLine([])).toEqual({ text: "", hidden: 0 }); expect(posterSpecialtyLine(null)).toEqual({ text: "", hidden: 0 }); }); it("آیتم بدون نام نه نمایش داده می‌شود نه شمرده", () => { const { text, hidden } = posterSpecialtyLine([{ id: "1" }, gi], 90); expect(text).toBe("جراح گوارش"); expect(hidden).toBe(0); }); it("شش تخصصِ نمونهٔ واقعی از بودجهٔ پیش‌فرض نمی‌گذرد", () => { const real = [ { name: "جراحی پلاستیک و زیبایی" }, { name: "جراحی لاپاراسکوپی" }, { name: "جراح تیروئید" }, { name: "جراح گوارش" }, { name: "جراحی سرطانها" }, ]; const { text, hidden } = posterSpecialtyLine(real); expect(text.length).toBeLessThanOrEqual(90); expect(hidden).toBe(real.length - text.split(" · ").length); }); });