/** * Unit tests for auth: getTgWebAppDataFromHash, getInitData, isLocalhost. */ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { getTgWebAppDataFromHash, getInitData, isLocalhost, hasTelegramHashButNoInitData, } from "./auth.js"; describe("getTgWebAppDataFromHash", () => { it("returns empty string when tgWebAppData= not present", () => { expect(getTgWebAppDataFromHash("foo=bar")).toBe(""); }); it("returns value from tgWebAppData= to next &tgWebApp or end", () => { expect(getTgWebAppDataFromHash("tgWebAppData=encoded%3Ddata")).toBe( "encoded=data" ); }); it("stops at &tgWebApp", () => { const hash = "tgWebAppData=value&tgWebAppVersion=6"; expect(getTgWebAppDataFromHash(hash)).toBe("value"); }); it("decodes URI component", () => { expect(getTgWebAppDataFromHash("tgWebAppData=hello%20world")).toBe( "hello world" ); }); }); describe("getInitData", () => { const origLocation = window.location; const origTelegram = window.Telegram; afterEach(() => { window.location = origLocation; window.Telegram = origTelegram; }); it("returns initData from Telegram.WebApp when set", () => { window.Telegram = { WebApp: { initData: "sdk-init-data" } }; delete window.location; window.location = { ...origLocation, hash: "", search: "" }; expect(getInitData()).toBe("sdk-init-data"); }); it("returns data from hash tgWebAppData when SDK empty", () => { window.Telegram = { WebApp: { initData: "" } }; delete window.location; window.location = { ...origLocation, hash: "#tgWebAppData=hash%20data", search: "", }; expect(getInitData()).toBe("hash data"); }); it("returns empty string when no source", () => { window.Telegram = { WebApp: { initData: "" } }; delete window.location; window.location = { ...origLocation, hash: "", search: "" }; expect(getInitData()).toBe(""); }); it("returns data from hash query param without double-decoding", () => { window.Telegram = { WebApp: { initData: "" } }; delete window.location; window.location = { ...origLocation, hash: "#tgWebAppVersion=6&tgWebAppData=user%3Dname%26hash%3Dabc", search: "", }; expect(getInitData()).toBe("user=name&hash=abc"); }); it("returns data from search query param without double-decoding", () => { window.Telegram = { WebApp: { initData: "" } }; delete window.location; window.location = { ...origLocation, hash: "", search: "?tgWebAppData=user%3Dname%26hash%3Dabc", }; expect(getInitData()).toBe("user=name&hash=abc"); }); }); describe("isLocalhost", () => { const origLocation = window.location; afterEach(() => { window.location = origLocation; }); it("returns true for localhost", () => { delete window.location; window.location = { ...origLocation, hostname: "localhost" }; expect(isLocalhost()).toBe(true); }); it("returns true for 127.0.0.1", () => { delete window.location; window.location = { ...origLocation, hostname: "127.0.0.1" }; expect(isLocalhost()).toBe(true); }); it("returns true for empty hostname", () => { delete window.location; window.location = { ...origLocation, hostname: "" }; expect(isLocalhost()).toBe(true); }); it("returns false for other hostnames", () => { delete window.location; window.location = { ...origLocation, hostname: "example.com" }; expect(isLocalhost()).toBe(false); }); }); describe("hasTelegramHashButNoInitData", () => { const origLocation = window.location; afterEach(() => { window.location = origLocation; }); it("returns false when hash is empty", () => { delete window.location; window.location = { ...origLocation, hash: "", search: "" }; expect(hasTelegramHashButNoInitData()).toBe(false); }); it("returns true when hash has tgWebAppVersion but no tgWebAppData", () => { delete window.location; window.location = { ...origLocation, hash: "#tgWebAppVersion=6", search: "", }; expect(hasTelegramHashButNoInitData()).toBe(true); }); it("returns false when hash has both tgWebAppVersion and tgWebAppData", () => { delete window.location; window.location = { ...origLocation, hash: "#tgWebAppVersion=6&tgWebAppData=some%3Ddata", search: "", }; expect(hasTelegramHashButNoInitData()).toBe(false); }); it("returns false when hash has tgWebAppData in unencoded form (with & and =)", () => { delete window.location; window.location = { ...origLocation, hash: "#tgWebAppData=value&tgWebAppVersion=6", search: "", }; expect(hasTelegramHashButNoInitData()).toBe(false); }); it("returns false when hash has no Telegram params", () => { delete window.location; window.location = { ...origLocation, hash: "#other=param", search: "", }; expect(hasTelegramHashButNoInitData()).toBe(false); }); });