/* Copyright 2026 Lotus Guild SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ import { afterEach, describe, expect, test, vi } from "vitest"; vi.mock("../widget", () => ({ widget: null })); import { lotusFlag, lotusParam, lotusSendToHost } from "./lotusWidget"; import { LotusWidgetActions } from "./lotusActions"; /** * Point `window.location` at a URL for the duration of one assertion. Uses a * path relative to the current origin — `pushState` throws a `SecurityError` * on a cross-origin URL, and jsdom's default test origin doesn't match a * hard-coded `http://localhost/`. */ function setLocation(path: string): void { window.history.pushState({}, "", path); } describe("lotusParam / lotusFlag", () => { afterEach(() => { setLocation("/"); }); test("reads a param from the query string", () => { setLocation("/?lotusTheme=1"); expect(lotusParam("lotusTheme")).toBe("1"); }); test("reads a param from the hash fragment's query portion", () => { setLocation("/#/room?lotusTransparent=1"); expect(lotusParam("lotusTransparent")).toBe("1"); }); test("the hash fragment wins over the query string for the same key", () => { setLocation("/?lotusTheme=fromQuery#/room?lotusTheme=fromHash"); expect(lotusParam("lotusTheme")).toBe("fromHash"); }); test("falls back to the query string for keys absent from the hash", () => { setLocation("/?onlyInQuery=1#/room?lotusTheme=1"); expect(lotusParam("onlyInQuery")).toBe("1"); }); test("returns null when the param is present nowhere", () => { setLocation("/#/room"); expect(lotusParam("missing")).toBeNull(); }); test.each([ ["1", true], ["true", true], ["0", false], ["false", false], [null, false], ])("lotusFlag treats %s as %s", (value, expected) => { setLocation(value === null ? "/" : `/?f=${value}`); expect(lotusFlag("f")).toBe(expected); }); // [lotus #33] lotusParam must re-derive from window.location on every call // rather than caching the first read, so a later navigation (e.g. lobby -> // in-call) that rewrites the URL is picked up. test("re-reads window.location on every call instead of caching the first result", () => { setLocation("/?lotusTheme=1"); expect(lotusParam("lotusTheme")).toBe("1"); setLocation("/?lotusTheme=0"); expect(lotusParam("lotusTheme")).toBe("0"); setLocation("/"); expect(lotusParam("lotusTheme")).toBeNull(); }); }); describe("lotusSendToHost", () => { test("returns false when no widget transport is available", () => { expect(lotusSendToHost(LotusWidgetActions.CallState, {})).toBe(false); }); });