// SPDX-FileCopyrightText: 2026 Progmasoft // SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 import assert from "node:assert/strict"; import { existsSync, readFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; import { dirname, join } from "node:path"; import { test } from "node:test"; const root = join(dirname(fileURLToPath(import.meta.url)), ".."); const websiteRoot = join(root, ".."); function read(relativePath) { return readFileSync(join(root, relativePath), "utf8"); } test("the published sitemap lists exactly the three supported language routes", () => { const sitemap = read("public/sitemap.xml"); const routes = [...sitemap.matchAll(/([^<]+)<\/loc>/g)].map((match) => match[1]); assert.deepEqual(routes, [ "https://xsharp-lang.xyz/", "https://xsharp-lang.xyz/docs/overview", "https://xsharp-lang.xyz/docs/getting-started", ]); assert.doesNotMatch(sitemap, /forum\.xsharp-lang\.xyz/); }); test("the forum placeholder is explicitly non-indexable and not an account service", () => { const forum = readFileSync(join(websiteRoot, "forum/index.html"), "utf8"); const nginx = readFileSync(join(websiteRoot, "ops/nginx/forum.conf"), "utf8"); assert.match(forum, /name="robots" content="noindex, nofollow"/); assert.match(forum, /There are no accounts,/); assert.match(forum, /posts, or discussion service/); assert.match(nginx, /X-Robots-Tag "noindex, nofollow"/); assert.match(nginx, /script-src 'self'; style-src 'self'/); assert.doesNotMatch(nginx, /unsafe-inline/); assert.match(forum, /src="\/site\.js[?"]/); assert.match(forum, /href="\/site\.css[?"]/); const normalizedForum = forum.toLowerCase(); assert.equal(normalizedForum.split("").length - 1, 1); // The query string is a cache key for the edge cache. Nginx serves the // exact file path, so changing the value forces a fresh copy after a deploy. assert.match(normalizedForum, /