import test from "node:test"; import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; const server = await readFile(new URL("../src/server.js", import.meta.url), "utf8"); const desktopHtml = await readFile(new URL("../public/index.html", import.meta.url), "utf8"); const desktopJs = await readFile(new URL("../public/app.js", import.meta.url), "utf8"); const desktopCss = await readFile(new URL("../public/styles.css", import.meta.url), "utf8"); const mobileHtml = await readFile(new URL("../public/mobile.html", import.meta.url), "utf8"); const mobileJs = await readFile(new URL("../public/mobile.js", import.meta.url), "utf8"); const mobileCss = await readFile(new URL("../public/mobile.css", import.meta.url), "utf8"); const rankingsJs = await readFile(new URL("../public/rankings.js", import.meta.url), "utf8"); test("server supports optional shared access password authentication", () => { assert.match(server, /HOTNESS_ACCESS_PASSWORD/); assert.match(server, /\/api\/auth\/status/); assert.match(server, /\/api\/auth\/login/); assert.match(server, /\/auth\/login/); assert.match(server, /sendLoginPage/); assert.match(server, /isProtectedAppPage/); assert.match(server, /readFormBody/); assert.match(server, /sendRedirect/); assert.match(server, /isAuthorizedRequest/); assert.match(server, /sendAuthRequired/); assert.match(server, /x-hotness-auth-token/i); }); test("server renders a standalone password page before protected app pages", () => { assert.match(server, /isProtectedAppPage\(url\.pathname\)/); assert.match(server, /!isAuthorizedRequest\(request, url\)/); assert.match(server, /sendLoginPage\(response, url\)/); assert.match(server, /name="next"/); assert.match(server, /输入访问密码/); }); test("desktop app page has no embedded password overlay after server-side auth", () => { assert.doesNotMatch(desktopHtml, /id="auth-gate"/); assert.doesNotMatch(desktopHtml, /id="auth-form"/); assert.doesNotMatch(desktopHtml, /id="auth-password"/); assert.match(desktopHtml, /id="collect-form"/); assert.match(desktopHtml, /采集一次/); assert.match(desktopJs, /HOTNESS_AUTH_TOKEN_KEY/); assert.match(desktopJs, /ensureAccessAuth/); assert.match(desktopJs, /authHeaders/); assert.match(desktopJs, /redirectToLogin/); assert.match(desktopJs, /x-hotness-auth-token/i); }); test("desktop login form is not blocked by JavaScript", () => { assert.doesNotMatch(desktopJs, /authForm\?\.addEventListener\("submit"/); assert.doesNotMatch(desktopJs, /authSubmit\?\.addEventListener\("click"/); assert.doesNotMatch(desktopJs, /async function submitAccessPassword/); }); test("desktop can finish login from a redirected access token", () => { assert.match(server, /buildAuthRedirectLocation/); assert.match(server, /access_token/); assert.match(desktopJs, /consumeRedirectedAccessToken/); assert.match(desktopJs, /URLSearchParams/); assert.match(desktopJs, /history\.replaceState/); }); test("mobile app page has no embedded password overlay after server-side auth", () => { assert.doesNotMatch(mobileHtml, /id="auth-gate"/); assert.doesNotMatch(mobileHtml, /id="auth-form"/); assert.doesNotMatch(mobileHtml, /id="auth-password"/); assert.match(mobileHtml, /id="collect-form"/); assert.match(mobileJs, /HOTNESS_AUTH_TOKEN_KEY/); assert.match(mobileJs, /ensureAccessAuth/); assert.match(mobileJs, /authHeaders/); assert.match(mobileJs, /redirectToLogin/); assert.match(mobileJs, /x-hotness-auth-token/i); }); test("mobile login form is not blocked by JavaScript", () => { assert.doesNotMatch(mobileJs, /authForm\?\.addEventListener\("submit"/); assert.doesNotMatch(mobileJs, /authSubmit\?\.addEventListener\("click"/); assert.doesNotMatch(mobileJs, /async function submitAccessPassword/); }); test("mobile can finish login from a redirected access token", () => { assert.match(mobileJs, /consumeRedirectedAccessToken/); assert.match(mobileJs, /URLSearchParams/); assert.match(mobileJs, /history\.replaceState/); }); test("ranking radar requests respect the shared cloud login token", () => { assert.match(rankingsJs, /HOTNESS_AUTH_TOKEN_KEY/); assert.match(rankingsJs, /authHeaders/); assert.match(rankingsJs, /x-hotness-auth-token/i); assert.match(rankingsJs, /requires_auth/); assert.match(rankingsJs, /hotness:auth-updated/); });