Something went wrong. Try again.
Web frontend and supporting services for lance.blue
Something went wrong. Try again.
2.9 kB · 79 lines
JavaScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980/** * The sitemap and robots.txt, read out of the build. * * Both are fetched by software somewhere else, and every way they go wrong is * silent from here: a relative loc resolves against the crawler, a page the * sitemap names but the build did not write is a soft error a search console * reports weeks later, and a robots.txt that names a sitemap that is not * there is just ignored. * * Read out of dist/ rather than out of the source, because the source is a * function and the thing crawlers get is its output. `npm test` builds first. * * Run with `npm test`. */import { test } from "node:test";import assert from "node:assert/strict";import { existsSync, readFileSync } from "node:fs";import { join } from "node:path";import { fileURLToPath } from "node:url";
const web = fileURLToPath(new URL("../", import.meta.url));const dist = join(web, "dist");
const SITE = "https://lance.blue";
const sitemapPath = join(dist, "sitemap.xml");const sitemap = existsSync(sitemapPath) ? readFileSync(sitemapPath, "utf8") : null;
/** Every <loc>, in document order. */function locs() { return [...sitemap.matchAll(/<loc>([^<]*)<\/loc>/g)].map((m) => m[1]);}
test("the build writes the sitemap robots.txt points at", () => { assert.ok(sitemap, `no ${sitemapPath}. The endpoint did not build.`);
const robotsPath = join(dist, "robots.txt"); assert.ok(existsSync(robotsPath), `no ${robotsPath}`); const robots = readFileSync(robotsPath, "utf8");
const named = /^Sitemap:\s*(\S+)$/m.exec(robots); assert.ok(named, "robots.txt names no sitemap"); assert.equal(named[1], `${SITE}/sitemap.xml`);});
test("every loc is absolute and behind a file the build wrote", () => { for (const loc of locs()) { assert.ok(loc.startsWith(`${SITE}/`) || loc === `${SITE}/`, loc);
// The key a loc is served from: "/" is index.html at the root, and every // other page is a directory holding one - trailingSlash "never" means the // extensionless copy push.sh writes comes from the same file. const path = loc.slice(SITE.length); const file = path === "/" ? "index.html" : join(path.slice(1), "index.html"); assert.ok(existsSync(join(dist, file)), `${loc} names no ${file}`); }});
test("the pages are there and 404.html is not", () => { const all = locs(); assert.ok(all.includes(`${SITE}/`), "no home page"); assert.ok(all.includes(`${SITE}/blog`), "no blog index"); assert.ok(!all.some((loc) => loc.includes("404")), "404 is not a page");});
test("posts carry a lastmod and the indexes do not", () => { const urls = [...sitemap.matchAll(/<url>([\s\S]*?)<\/url>/g)].map( (m) => m[1], ); for (const url of urls) { const loc = /<loc>([^<]*)<\/loc>/.exec(url)[1]; const hasLastmod = /<lastmod>\d{4}-\d{2}-\d{2}<\/lastmod>/.test(url); const isPost = loc.startsWith(`${SITE}/blog/`); assert.equal(hasLastmod, isPost, loc); }});