/**
* What standard.site and feed readers read out of the built site, pinned at
* the seams where two files have to agree without anything connecting them:
*
* - sequoia computes a record's address as siteUrl + pathPrefix + "/" + slug
* from sequoia.json; Astro computes the canonical from its own `site`.
* If either moves, records point at pages that are not there — and because
* records are keyed by path, the next publish writes a second record
* beside the stale one instead of correcting it.
* - A post links its document record only once it has one: an href with
* nothing behind it is a claim a verifier follows.
* - Every page links the publication, and says what sequoia.json says: the
* tag and the well-known are one value, read from one file.
* - The well-known publication key, once it exists, must say what
* sequoia.json says, or the publication cannot be verified.
* - The atom feed and the built pages must agree about what was posted.
* - CloudFront serves one built object for every address the site does not
* have, and infra/main.tf names it by S3 key.
*
* Run with `npm --prefix web test`.
*/
import { test, after } from "node:test";
import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { existsSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
const web = fileURLToPath(new URL("../", import.meta.url));
const POSTS = join(web, "src/content/posts");
const WELL_KNOWN = join(web, "public/.well-known/site.standard.publication");
const sequoia = JSON.parse(readFileSync(join(web, "sequoia.json"), "utf8"));
const astro = (await import("../astro.config.mjs")).default;
// Nothing resolvable. A DID that looked real would be followed by the first
// person who copied it out of here.
const DOCUMENT = "at://did:plc:example/site.standard.document/fakerkey";
// Fixtures written for the build and taken away again: one published post
// (the tree may not have one on any given day; the & pins feed escaping),
// one draft that must not build. Under web/.astro, which is gitignored and
// already the build's scratch.
const fixture = join(POSTS, "fixture-mumpsimus.md");
const draftFixture = join(POSTS, "fixture-widdershins-draft.md");
const outDir = join(web, ".astro/standard-site");
writeFileSync(
fixture,
`---
title: Fixture mumpsimus & sons
description: Fixture for the standard.site tests. Removed when they finish.
publishDate: 2026-01-01
atUri: ${DOCUMENT}
---
Borborygmus quincunx widdershins.
`,
);
writeFileSync(
draftFixture,
`---
title: Fixture draft
description: Must not appear in a build.
publishDate: 2026-01-02
draft: true
---
Not yet.
`,
);
// Which posts claim a record, read while the fixtures are on disk. Slugs are
// filenames, which is what Astro's glob loader makes ids from. Sequoia
// writes the value quoted, so the quotes come off.
const published = new Map(
readdirSync(POSTS)
.filter((file) => file.endsWith(".md"))
.map((file) => [
file.replace(/\.md$/, ""),
/^atUri:\s*["']?(at:\/\/\S+?)["']?\s*$/m.exec(
readFileSync(join(POSTS, file), "utf8"),
)?.[1],
]),
);
try {
execFileSync(
join(web, "node_modules/.bin/astro"),
["build", "--outDir", outDir],
{ cwd: web, stdio: "pipe" },
);
} finally {
rmSync(fixture, { force: true });
rmSync(draftFixture, { force: true });
}
after(() => rmSync(outDir, { recursive: true, force: true }));
test("sequoia.json and astro.config.mjs agree on the site", () => {
assert.equal(sequoia.siteUrl, astro.site);
// A trailing slash would make Astro's canonical /posts/x/ while the
// record still claims /posts/x, and the two would stop being the same
// address.
assert.equal(astro.trailingSlash, "never");
assert.equal(sequoia.pathPrefix, "/posts");
});
test("every built post is canonical at the address its record claims, and links the record only if it has one", () => {
const built = readdirSync(join(outDir, "posts"), { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name);
assert.ok(built.length > 1, "the fixture and at least one post should build");
for (const slug of built) {
const html = readFileSync(join(outDir, "posts", slug, "index.html"), "utf8");
const claimed = `${sequoia.siteUrl}${sequoia.pathPrefix}/${slug}`;
assert.ok(
html.includes(`rel="canonical" href="${claimed}"`),
`${slug} is not canonical at ${claimed}`,
);
const atUri = published.get(slug);
if (atUri) {
assert.match(
html,
new RegExp(` {
assert.ok(!existsSync(join(outDir, "posts/fixture-widdershins-draft")));
});
test("the atom feed lists exactly the built posts, escaped and absolute", () => {
const feed = readFileSync(join(outDir, "atom.xml"), "utf8");
const built = readdirSync(join(outDir, "posts"), { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name);
const ids = [...feed.matchAll(/([^<]+)<\/id>/g)]
.map((m) => m[1])
.filter((id) => id.includes("/posts/"));
assert.deepEqual(
ids.sort(),
built.map((slug) => `${sequoia.siteUrl}/posts/${slug}`).sort(),
);
// The fixture's & must arrive as &, or the document ends at that byte
// for every reader at once.
assert.ok(feed.includes("Fixture mumpsimus & sons"));
assert.ok(!/& /.test(feed), "a bare ampersand survived into the feed");
});
test("the homepage previews the updates feed", () => {
const html = readFileSync(join(outDir, "index.html"), "utf8");
assert.ok(html.includes('href="/posts"'), "no link to the backlog");
assert.ok(html.includes('href="/atom.xml"'), "no link to the feed");
});
test("the homepage gallery ships every screenshot it renders", () => {
// The manifest is generated (scripts/sync-shots.mjs) and the page is
// hand-written, so the two can drift: an entry with no file on disk is a
// broken image on the frontpage, and a file the page never names is dead
// weight in the release tree.
const html = readFileSync(join(outDir, "index.html"), "utf8");
const shots = JSON.parse(readFileSync(join(web, "src/shots.json"), "utf8"));
assert.ok(shots.length > 0, "no screenshots to show");
for (const shot of shots) {
assert.ok(existsSync(join(outDir, "shots", `${shot.name}.png`)), `${shot.src} did not build`);
assert.match(
html,
new RegExp(` `${shot.name}.png`).sort(),
);
});
test("both origin error codes serve a 404 document the build actually emits", () => {
// The bucket is private behind an origin access control, so S3 answers an
// address the site does not have with 403, not 404; infra/main.tf maps both
// to one built object and rewrites the status to 404. Nothing connects that
// path to the build: Astro special-cases the status-code pages, so 404.astro
// is the one page that is not a directory, and a change to build.format or a
// renamed page would leave CloudFront fetching a key that is not there —
// back to raw AccessDenied XML for every stale link.
const tf = readFileSync(join(web, "../infra/main.tf"), "utf8");
const mapped = new Map(
[...tf.matchAll(/custom_error_response\s*{([^}]*)}/g)].map(([, block]) => [
Number(/\berror_code\s*=\s*(\d+)/.exec(block)?.[1]),
{
page: /\bresponse_page_path\s*=\s*"([^"]+)"/.exec(block)?.[1],
status: Number(/\bresponse_code\s*=\s*(\d+)/.exec(block)?.[1]),
},
]),
);
assert.deepEqual(
[...mapped.keys()].sort(),
[403, 404],
"infra/main.tf must map both the 403 S3 gives a missing key and a real 404",
);
for (const [code, { page, status }] of mapped) {
assert.equal(status, 404, `${code} from the origin is not answered as 404`);
assert.ok(
existsSync(join(outDir, page.replace(/^\//, ""))),
`${page} is what CloudFront serves for ${code}, and the build does not emit it`,
);
}
});
test("the publication key, once it exists, says what sequoia.json says", () => {
// `sequoia init` writes this file and the URI in sequoia.json in the same
// step, and nothing rewrites either afterwards. They drift when one is
// edited by hand, and the symptom is a publication nobody can verify.
if (!existsSync(WELL_KNOWN)) {
assert.match(
sequoia.publicationUri,
/PLACEHOLDER/,
"sequoia.json has a real publication but public/.well-known does not serve it",
);
return;
}
const body = readFileSync(WELL_KNOWN, "utf8").trim();
assert.match(
body,
/^at:\/\/did:\S+\/site\.standard\.publication\/\S+$/,
"the key must be one AT-URI and nothing else",
);
assert.equal(body, sequoia.publicationUri);
assert.ok(
existsSync(join(outDir, ".well-known/site.standard.publication")),
"public/.well-known did not survive the build",
);
});
test("every page links the publication it belongs to", () => {
// The well-known is what verifies a publication; the link tag is what a
// reader that already has the page resolves without probing. Both come from
// publicationUri in sequoia.json — the test above pins the well-known to it,
// this pins the pages — so there is one value to keep right. Every page, not
// just posts: a reader can arrive anywhere on the site.
const pages = readdirSync(outDir, { recursive: true }).filter((entry) =>
entry.endsWith(".html"),
);
assert.ok(pages.length > 3, "the build should emit more pages than this");
const placeholder = sequoia.publicationUri.includes("PLACEHOLDER");
for (const page of pages) {
const html = readFileSync(join(outDir, page), "utf8");
const linked = [
...html.matchAll(/ match[1]);
if (placeholder) {
assert.deepEqual(linked, [], `${page} links a publication that does not exist yet`);
continue;
}
assert.deepEqual(
linked,
[sequoia.publicationUri],
`${page} should link the publication exactly once`,
);
}
});