// 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"); } function locations(path) { return [...read(path).matchAll(/([^<]+)<\/loc>/g)].map((match) => match[1]); } test("every site publishes exactly its own pages in its sitemap", () => { assert.deepEqual(locations("public/sitemap.xml"), [ "https://tala.run/", "https://tala.run/docs/overview", "https://tala.run/docs/getting-started", "https://tala.run/docs/syntax", ]); assert.deepEqual(locations("public/hosts/talac/sitemap.xml"), [ "https://talac.tala.run/", "https://talac.tala.run/docs/command-line", "https://talac.tala.run/docs/outputs", ]); assert.deepEqual(locations("public/hosts/tazel/sitemap.xml"), [ "https://tazel.tala.run/", "https://tazel.tala.run/docs/commands", "https://tazel.tala.run/docs/project-file", ]); assert.deepEqual(locations("public/hosts/talafmt/sitemap.xml"), [ "https://talafmt.tala.run/", "https://talafmt.tala.run/docs/command-line", "https://talafmt.tala.run/docs/layout", ]); assert.deepEqual(locations("public/hosts/talalint/sitemap.xml"), [ "https://talalint.tala.run/", "https://talalint.tala.run/docs/command-line", "https://talalint.tala.run/docs/checks", ]); assert.doesNotMatch(read("public/sitemap.xml"), /forum\.tala\.run/); for (const [path, host] of [ ["public/robots.txt", "tala.run"], ["public/hosts/talac/robots.txt", "talac.tala.run"], ["public/hosts/tazel/robots.txt", "tazel.tala.run"], ["public/hosts/talafmt/robots.txt", "talafmt.tala.run"], ["public/hosts/talalint/robots.txt", "talalint.tala.run"], ]) { assert.match( read(path), new RegExp(`Sitemap: https://${host.replaceAll(".", "\\.")}/sitemap\\.xml`), ); } }); 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, /