import { describe, it, beforeEach } from "node:test"; import assert from "node:assert/strict"; import "/js/components/moderation-warning.js"; describe("moderation-warning", () => { beforeEach(() => { document.body.innerHTML = ""; }); describe("ModerationWarning - rendering", () => { it("should render top-bar element", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const topBar = element.querySelector(".top-bar"); assert(topBar !== null); }); it("should render toggle-content element", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const content = element.querySelector(".toggle-content"); assert(content !== null); }); it("should display label text", () => { const element = document.createElement("moderation-warning"); element.setAttribute("label", "Adult content"); document.body.appendChild(element); const topBar = element.querySelector(".top-bar"); assert(topBar.textContent.includes("Adult content")); }); it("should display show/hide label", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const label = element.querySelector(".show-hide-label"); assert(label !== null); assert.deepEqual(label.textContent.trim(), "Show"); }); it("should preserve children in toggle-content", () => { const element = document.createElement("moderation-warning"); element.innerHTML = "
Hidden content
"; document.body.appendChild(element); const child = element.querySelector(".toggle-content .test-child"); assert(child !== null); assert.deepEqual(child.textContent, "Hidden content"); }); }); describe("ModerationWarning - labeler info", () => { it("should display labeler name when provided", () => { const element = document.createElement("moderation-warning"); element.setAttribute("labelerName", "Bluesky Moderation"); document.body.appendChild(element); const description = element.querySelector( ".post-moderation-warning-description", ); assert(description !== null); assert(description.textContent.includes("Bluesky Moderation")); }); it("should display labeler link when provided", () => { const element = document.createElement("moderation-warning"); element.setAttribute("labelerName", "Bluesky"); element.setAttribute( "labelerLink", "https://bsky.app/profile/moderation.bsky.app", ); document.body.appendChild(element); const link = element.querySelector( ".post-moderation-warning-description a", ); assert(link !== null); assert.deepEqual(link.textContent, "Bluesky"); assert.deepEqual( link.href, "https://bsky.app/profile/moderation.bsky.app", ); }); it("should not render link if only name is provided", () => { const element = document.createElement("moderation-warning"); element.setAttribute("labelerName", "Test Labeler"); document.body.appendChild(element); const link = element.querySelector( ".post-moderation-warning-description a", ); assert.deepEqual(link, null); const description = element.querySelector( ".post-moderation-warning-description", ); assert(description.textContent.includes("Test Labeler")); }); it("should hide labeler description when expanded", () => { const element = document.createElement("moderation-warning"); element.setAttribute("labelerName", "Test Labeler"); document.body.appendChild(element); element.toggle(); const description = element.querySelector( ".post-moderation-warning-description", ); assert(description.hidden); }); }); describe("ModerationWarning - initial state", () => { it("should start with expanded set to false", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); assert.deepEqual(element.expanded, false); }); it("should have aria-expanded set to false initially", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const topBar = element.querySelector(".top-bar"); assert.deepEqual(topBar.getAttribute("aria-expanded"), "false"); }); it("should hide toggle-content initially", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const content = element.querySelector(".toggle-content"); assert(content.hidden); }); it("should display 'Show' label initially", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const label = element.querySelector(".show-hide-label"); assert.deepEqual(label.textContent.trim(), "Show"); }); }); describe("ModerationWarning - toggle", () => { it("should set expanded to true when toggle() is called", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); element.toggle(); assert.deepEqual(element.expanded, true); }); it("should update aria-expanded when toggled", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); element.toggle(); const topBar = element.querySelector(".top-bar"); assert.deepEqual(topBar.getAttribute("aria-expanded"), "true"); }); it("should show toggle-content when expanded", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); element.toggle(); const content = element.querySelector(".toggle-content"); assert(!content.hidden); }); it("should display 'Hide' label when expanded", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); element.toggle(); const label = element.querySelector(".show-hide-label"); assert.deepEqual(label.textContent.trim(), "Hide"); }); it("should toggle back to collapsed state", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); element.toggle(); element.toggle(); assert.deepEqual(element.expanded, false); const label = element.querySelector(".show-hide-label"); assert.deepEqual(label.textContent.trim(), "Show"); }); }); describe("ModerationWarning - click interaction", () => { it("should toggle when top-bar is clicked", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const topBar = element.querySelector(".top-bar"); topBar.click(); assert.deepEqual(element.expanded, true); }); }); describe("ModerationWarning - keyboard interaction", () => { it("should toggle when Enter is pressed on top-bar", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const topBar = element.querySelector(".top-bar"); const event = new window.KeyboardEvent("keydown", { key: "Enter" }); topBar.dispatchEvent(event); assert.deepEqual(element.expanded, true); }); it("should toggle when Space is pressed on top-bar", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const topBar = element.querySelector(".top-bar"); const event = new window.KeyboardEvent("keydown", { key: " " }); topBar.dispatchEvent(event); assert.deepEqual(element.expanded, true); }); }); describe("ModerationWarning - accessibility", () => { it("should have tabindex on top-bar", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const topBar = element.querySelector(".top-bar"); assert.deepEqual(topBar.getAttribute("tabindex"), "0"); }); it("should have role button on top-bar", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); const topBar = element.querySelector(".top-bar"); assert.deepEqual(topBar.getAttribute("role"), "button"); }); }); describe("ModerationWarning - icon style", () => { it("should render info icon by default", () => { const element = document.createElement("moderation-warning"); document.body.appendChild(element); assert( element.querySelector("app-icon[icon='info-circle-line']") !== null, ); assert.deepEqual( element.querySelector("app-icon[icon='eye-off-line']"), null, ); }); it("should render info icon when icon-style is 'info'", () => { const element = document.createElement("moderation-warning"); element.setAttribute("icon-style", "info"); document.body.appendChild(element); assert( element.querySelector("app-icon[icon='info-circle-line']") !== null, ); assert.deepEqual( element.querySelector("app-icon[icon='eye-off-line']"), null, ); }); it("should render eye-slash icon when icon-style is 'closed-eye'", () => { const element = document.createElement("moderation-warning"); element.setAttribute("icon-style", "closed-eye"); document.body.appendChild(element); assert(element.querySelector("app-icon[icon='eye-off-line']") !== null); assert.deepEqual( element.querySelector("app-icon[icon='info-circle-line']"), null, ); }); it("should render icon inside the top-bar label", () => { const element = document.createElement("moderation-warning"); element.setAttribute("label", "Hidden"); document.body.appendChild(element); const labelEl = element.querySelector( ".top-bar .moderation-warning-label", ); assert(labelEl !== null); assert(labelEl.querySelector("app-icon") !== null); assert(labelEl.textContent.includes("Hidden")); }); }); describe("ModerationWarning - reinitialization protection", () => { it("should not reinitialize when connectedCallback is called multiple times", () => { const element = document.createElement("moderation-warning"); element.innerHTML = "Original"; document.body.appendChild(element); element.connectedCallback(); const child = element.querySelector(".toggle-content .test"); assert(child !== null); assert.deepEqual(child.textContent, "Original"); }); }); });