/** * Unit tests for contactHtml (formatPhoneDisplay, buildContactLinksHtml). */ import { describe, it, expect } from "vitest"; import { formatPhoneDisplay, buildContactLinksHtml } from "./contactHtml.js"; describe("formatPhoneDisplay", () => { it("formats 11-digit number starting with 7", () => { expect(formatPhoneDisplay("79146522209")).toBe("+7 914 652-22-09"); expect(formatPhoneDisplay("+79146522209")).toBe("+7 914 652-22-09"); }); it("formats 11-digit number starting with 8", () => { expect(formatPhoneDisplay("89146522209")).toBe("+7 914 652-22-09"); }); it("formats 10-digit number as Russian", () => { expect(formatPhoneDisplay("9146522209")).toBe("+7 914 652-22-09"); }); it("returns empty string for null or empty", () => { expect(formatPhoneDisplay(null)).toBe(""); expect(formatPhoneDisplay("")).toBe(""); expect(formatPhoneDisplay(" ")).toBe(""); }); it("strips non-digits before formatting", () => { expect(formatPhoneDisplay("+7 (914) 652-22-09")).toBe("+7 914 652-22-09"); }); it("returns digits as-is for non-10/11 length", () => { expect(formatPhoneDisplay("123")).toBe("123"); expect(formatPhoneDisplay("12345678901")).toBe("12345678901"); }); }); describe("buildContactLinksHtml", () => { const baseOptions = { classPrefix: "test-contact", showLabels: true, separator: " " }; it("returns empty string when phone and username are missing", () => { expect(buildContactLinksHtml("en", null, null, baseOptions)).toBe(""); expect(buildContactLinksHtml("en", undefined, undefined, baseOptions)).toBe(""); expect(buildContactLinksHtml("en", "", "", baseOptions)).toBe(""); expect(buildContactLinksHtml("en", " ", " ", baseOptions)).toBe(""); }); it("renders phone only with label and tel: link", () => { const html = buildContactLinksHtml("en", "+79991234567", null, baseOptions); expect(html).toContain("test-contact-row"); expect(html).toContain('href="tel:'); expect(html).toContain("+79991234567"); expect(html).toContain("Phone"); expect(html).not.toContain("t.me"); }); it("displays phone formatted for Russian numbers", () => { const html = buildContactLinksHtml("en", "79146522209", null, baseOptions); expect(html).toContain("+7 914 652-22-09"); expect(html).toContain('href="tel:79146522209"'); }); it("renders username only with label and t.me link", () => { const html = buildContactLinksHtml("en", null, "alice_dev", baseOptions); expect(html).toContain("test-contact-row"); expect(html).toContain("https://t.me/"); expect(html).toContain("alice_dev"); expect(html).toContain("@alice_dev"); expect(html).toContain("Telegram"); expect(html).not.toContain("tel:"); }); it("renders both phone and username with labels", () => { const html = buildContactLinksHtml("en", "+79001112233", "bob", baseOptions); expect(html).toContain("test-contact-row"); expect(html).toContain("tel:"); expect(html).toContain("+79001112233"); expect(html).toContain("+7 900 111-22-33"); expect(html).toContain("t.me"); expect(html).toContain("@bob"); expect(html).toContain("Phone"); expect(html).toContain("Telegram"); }); it("strips leading @ from username and displays with @", () => { const html = buildContactLinksHtml("en", null, "@alice", baseOptions); expect(html).toContain("https://t.me/alice"); expect(html).toContain("@alice"); expect(html).not.toContain("@@"); }); it("handles multiple leading @ in username", () => { const html = buildContactLinksHtml("en", null, "@@@user", baseOptions); expect(html).toContain("https://t.me/user"); expect(html).toContain("@user"); }); it("escapes special characters in phone href; display uses formatted digits only", () => { const html = buildContactLinksHtml("en", '+7 999 "1" <2>', null, baseOptions); expect(html).toContain("""); expect(html).toContain("<"); expect(html).toContain("tel:"); expect(html).toContain("799912"); expect(html).not.toContain("<2>"); expect(html).not.toContain('"1"'); }); it("uses custom separator when showLabels is false", () => { const html = buildContactLinksHtml("en", "+7999", "u1", { classPrefix: "duty-contact", showLabels: false, separator: " · " }); expect(html).toContain(" · "); expect(html).not.toContain("Phone"); expect(html).not.toContain("Telegram"); expect(html).toContain("duty-contact-row"); expect(html).toContain("duty-contact-link"); }); it("uses Russian labels when lang is ru", () => { const html = buildContactLinksHtml("ru", "+7999", null, baseOptions); expect(html).toContain("Телефон"); const htmlTg = buildContactLinksHtml("ru", null, "u", baseOptions); expect(htmlTg).toContain("Telegram"); }); it("uses default showLabels true and separator space when options omit them", () => { const html = buildContactLinksHtml("en", "+7999", "u", { classPrefix: "minimal", }); expect(html).toContain("Phone"); expect(html).toContain("Telegram"); expect(html).toContain("minimal-row"); expect(html).not.toContain(" · "); }); describe("layout: block", () => { it("renders phone as block with icon and formatted number", () => { const html = buildContactLinksHtml("en", "79146522209", null, { classPrefix: "current-duty-contact", layout: "block", }); expect(html).toContain("current-duty-contact-row--blocks"); expect(html).toContain("current-duty-contact-block"); expect(html).toContain("current-duty-contact-block--phone"); expect(html).toContain("+7 914 652-22-09"); expect(html).toContain("tel:"); expect(html).toContain(" { const html = buildContactLinksHtml("en", null, "alice_dev", { classPrefix: "current-duty-contact", layout: "block", }); expect(html).toContain("current-duty-contact-block--telegram"); expect(html).toContain("https://t.me/"); expect(html).toContain("@alice_dev"); expect(html).toContain(" { const html = buildContactLinksHtml("en", "+79001112233", "bob", { classPrefix: "current-duty-contact", layout: "block", }); expect(html).toContain("current-duty-contact-block--phone"); expect(html).toContain("current-duty-contact-block--telegram"); expect(html).toContain("+7 900 111-22-33"); expect(html).toContain("@bob"); }); }); });