import assert from "node:assert/strict"; import { describe, it } from "node:test"; import { createOfficeScreenPanel } from "../media/officeScreenPanel.ts"; import type { MediaSurfaceDescriptor } from "../media/presentation.ts"; type Listener = (event: FakeEvent) => void; class FakeEvent { defaultPrevented = false; readonly type: string; readonly target: FakeElement; readonly key: string; readonly shiftKey: boolean; constructor( type: string, target: FakeElement, key = "", shiftKey = false, ) { this.type = type; this.target = target; this.key = key; this.shiftKey = shiftKey; } preventDefault(): void { this.defaultPrevented = true; } } class FakeElement { readonly children: FakeElement[] = []; readonly attributes = new Map(); readonly listeners = new Map(); parentElement: FakeElement | null = null; className = ""; textContent = ""; hidden = false; disabled = false; type = ""; id = ""; readonly ownerDocument: FakeDocument; readonly tagName: string; constructor(ownerDocument: FakeDocument, tagName: string) { this.ownerDocument = ownerDocument; this.tagName = tagName; } append(...nodes: FakeElement[]): void { for (const node of nodes) { node.parentElement = this; this.children.push(node); } } setAttribute(name: string, value: string): void { this.attributes.set(name, value); } getAttribute(name: string): string | null { return this.attributes.get(name) ?? null; } addEventListener(type: string, listener: Listener): void { const list = this.listeners.get(type); if (list) list.push(listener); else this.listeners.set(type, [listener]); } dispatch(type: string, init: { key?: string; shiftKey?: boolean } = {}): FakeEvent { const event = new FakeEvent(type, this, init.key, init.shiftKey); for (const listener of this.listeners.get(type) ?? []) listener(event); return event; } focus(): void { this.ownerDocument.activeElement = this; } remove(): void { if (!this.parentElement) return; const index = this.parentElement.children.indexOf(this); if (index >= 0) this.parentElement.children.splice(index, 1); this.parentElement = null; } find(attribute: string, value: string): FakeElement { if (this.attributes.get(attribute) === value) return this; for (const child of this.children) { try { return child.find(attribute, value); } catch { /* next */ } } throw new Error(`missing [${attribute}=${value}]`); } text(): string { return this.textContent + this.children.map((child) => child.text()).join(""); } } class FakeDocument { activeElement: FakeElement | null = null; createElement(tag: string): FakeElement { return new FakeElement(this, tag.toUpperCase()); } } const SURFACES: MediaSurfaceDescriptor[] = [ { screenId: "lobby-monitor", officeId: "hq", levelId: "level-1", roomId: "Lobby", kind: "tera:screen.monitor", bound: false }, { screenId: "commons-display", officeId: "hq", levelId: "level-2", roomId: "Commons", kind: "tera:screen.wall-display", bound: true }, ]; function setup() { const document = new FakeDocument(); const container = document.createElement("div"); const selected: string[] = []; const shares: string[] = []; const stops: string[] = []; const opts: [string, boolean][] = []; const panel = createOfficeScreenPanel({ container: container as unknown as HTMLElement, surfaces: SURFACES, onSelect: (surface) => selected.push(surface.screenId), onRequestShare: (surface) => shares.push(surface.screenId), onStopShare: (surface) => stops.push(surface.screenId), onViewerOptIn: (surface, value) => opts.push([surface.screenId, value]), }); return { document, container, panel, selected, shares, stops, opts }; } describe("office screen manager panel", () => { it("builds a closed labelled dialog with safe screen, room, and status text", () => { const { container, panel } = setup(); const root = panel.root as unknown as FakeElement; assert.equal(container.children.length, 1); assert.equal(root.hidden, true); assert.equal(root.getAttribute("role"), "dialog"); assert.equal(root.getAttribute("aria-modal"), "true"); assert.match(root.text(), /lobby-monitor/); assert.match(root.text(), /Lobby/); assert.match(root.text(), /Media off/); assert.match(root.text(), /Media active/); }); it("selects, explicitly opts in, and emits share/stop intent without capture", () => { const { panel, selected, shares, stops, opts } = setup(); panel.open(); const root = panel.root as unknown as FakeElement; root.find("data-screen-id", "commons-display").dispatch("click"); root.find("data-action", "opt-in").dispatch("click"); root.find("data-action", "share").dispatch("click"); root.find("data-action", "stop").dispatch("click"); assert.deepEqual(selected, ["commons-display"]); assert.deepEqual(opts, [["commons-display", true]]); assert.deepEqual(shares, ["commons-display"]); assert.deepEqual(stops, ["commons-display"]); assert.deepEqual(panel.state().optedInScreenIds, ["commons-display"]); assert.equal("mediaDevices" in panel, false); }); it("keeps presenting separate from viewer opt-in", () => { const { panel, shares, opts } = setup(); panel.open(); const root = panel.root as unknown as FakeElement; const share = root.find("data-action", "share"); assert.equal(share.disabled, false); share.dispatch("click"); assert.deepEqual(shares, ["lobby-monitor"]); assert.deepEqual(opts, []); assert.deepEqual(panel.state().optedInScreenIds, []); }); it("updates defensively, removes stale consent, and represents an empty office", () => { const { panel } = setup(); const root = panel.root as unknown as FakeElement; root.find("data-action", "opt-in").dispatch("click"); const next = [{ ...SURFACES[1]!, screenId: "safe-text-