import { describe, expect, it } from "vitest"; import { absoluteUrl, buildBreadcrumbJsonLd, normalizeBreadcrumb, } from "@/lib/breadcrumb"; const ORIGIN = "https://nobat724.com"; describe("normalizeBreadcrumb", () => { it("رشته را به {name} تبدیل می‌کند", () => { expect(normalizeBreadcrumb(["خانه"])).toEqual([{ name: "خانه" }]); }); it("آیتم بی‌نام یا خالی حذف می‌شود", () => { expect(normalizeBreadcrumb([{ name: "" }, { name: " " }, { href: "/x" }, null])).toEqual([]); }); it("ورودی نامعتبر → آرایهٔ خالی", () => { expect(normalizeBreadcrumb(undefined)).toEqual([]); expect(normalizeBreadcrumb("nope")).toEqual([]); }); }); describe("absoluteUrl", () => { it("origin و href را می‌چسباند", () => { expect(absoluteUrl(ORIGIN, "/clinics")).toBe("https://nobat724.com/clinics"); expect(absoluteUrl(`${ORIGIN}/`, "clinics")).toBe("https://nobat724.com/clinics"); expect(absoluteUrl(ORIGIN, "/")).toBe("https://nobat724.com"); }); it("URL مطلق را دست‌نخورده برمی‌گرداند", () => { expect(absoluteUrl(ORIGIN, "https://yazd-nobat.ir/x")).toBe("https://yazd-nobat.ir/x"); }); it("بدون origin یا href → null", () => { expect(absoluteUrl(undefined, "/clinics")).toBeNull(); expect(absoluteUrl(ORIGIN, undefined)).toBeNull(); expect(absoluteUrl(ORIGIN, "")).toBeNull(); }); }); describe("buildBreadcrumbJsonLd", () => { const LIST = [ { name: "خانه", href: "/" }, { name: "کلینیک ها", href: "/clinics" }, { name: "یزد", href: "/clinics" }, ]; it("همهٔ عنصرها item مطلق دارند (خطای سرچ‌کنسول)", () => { const jsonLd = buildBreadcrumbJsonLd(LIST, ORIGIN); expect(jsonLd["@type"]).toBe("BreadcrumbList"); expect(jsonLd.itemListElement).toHaveLength(3); for (const el of jsonLd.itemListElement) { expect(el.item, `missing item: ${JSON.stringify(el)}`).toMatch(/^https:\/\//); expect(el.name).toBeTruthy(); } expect(jsonLd.itemListElement.map((e) => e.position)).toEqual([1, 2, 3]); }); it("آیتم آخر هم item دارد — همان چیزی که گوگل نبودش را خطای بحرانی می‌داند", () => { const jsonLd = buildBreadcrumbJsonLd(LIST, ORIGIN); expect(jsonLd.itemListElement.at(-1).item).toBe("https://nobat724.com/clinics"); }); it("بدون origin هیچ اسکیمایی منتشر نمی‌شود (به‌جای اسکیمای ناقص)", () => { expect(buildBreadcrumbJsonLd(LIST, undefined)).toBeNull(); }); it("اگر حتی یک آیتم href نداشته باشد، اسکیما تولید نمی‌شود", () => { const partial = [{ name: "خانه", href: "/" }, { name: "صفحهٔ جاری" }]; expect(buildBreadcrumbJsonLd(partial, ORIGIN)).toBeNull(); }); it("لیست خالی → null", () => { expect(buildBreadcrumbJsonLd([], ORIGIN)).toBeNull(); expect(buildBreadcrumbJsonLd([{ name: "" }], ORIGIN)).toBeNull(); }); it("روی دامنهٔ شهری همان دامنه در item می‌نشیند", () => { const jsonLd = buildBreadcrumbJsonLd(LIST, "https://yazd-nobat.ir"); expect(jsonLd.itemListElement[1].item).toBe("https://yazd-nobat.ir/clinics"); }); });