Public: anyone can read this; the crew can change it.
forge-webspec walks a public repository, its issues list and an issue, not only the front pages #3141
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/3131-forge-webspec-walks-a-public-repository → main 1 commit fork 1 thread · 1 unresolved
1 file
changed +22
−13
test/forge-webspec.test.ts +22 −13
| @@ -8,6 +8,7 @@ import { mkdtemp, rm } from "node:fs/promises"; | ||
| 8 | 8 | import { tmpdir } from "node:os"; |
| 9 | 9 | import { join } from "node:path"; |
| 10 | 10 | import { createApp, type App } from "../src/app.ts"; |
| 11 | import { openIssue } from "../src/actions/issues.ts"; | |
| 11 | 12 | import { commitToBranch, createRepo } from "../src/actions/repos.ts"; |
| 12 | 13 | import { createUser } from "../src/core/users.ts"; |
| 13 | 14 | import { securityFloor } from "../src/http/respond.ts"; |
| @@ -17,7 +18,7 @@ import { quietLogs } from "./helpers/globals.ts"; | ||
| 17 | 18 | |
| 18 | 19 | quietLogs(); |
| 19 | 20 | |
| 20 | const PATHS = ["/", "/signin", "/signup", "/explore"]; | |
| 21 | const PATHS = ["/", "/signin", "/signup", "/explore", "/alice/notes", "/alice/notes/issues", "/alice/notes/issues/1"]; | |
| 21 | 22 | |
| 22 | 23 | /** |
| 23 | 24 | * `check path` -> [section, why it stands]. Every one is expected on every |
| @@ -38,6 +39,20 @@ beforeAll(async () => { | ||
| 38 | 39 | dir = await mkdtemp(join(tmpdir(), "forge-webspec-")); |
| 39 | 40 | app = createApp({ dataDir: dir, port: 0 }); |
| 40 | 41 | http = forgeHttp(app); |
| 42 | const made = await createUser(app.db, { | |
| 43 | origin: "seed", | |
| 44 | trusted: true, | |
| 45 | username: "alice", | |
| 46 | email: "[email protected]", | |
| 47 | password: "a-good-passphrase", | |
| 48 | adminIfFirst: true, | |
| 49 | }); | |
| 50 | if (!made.ok) throw new Error("user"); | |
| 51 | const repo = await createRepo(app, made.value, { name: "notes", visibility: "public" }); | |
| 52 | if (!repo.ok) throw new Error("repo"); | |
| 53 | await commitToBranch(app, made.value, repo.value, { message: "seed", files: [{ path: "a.txt", content: "a" }] }); | |
| 54 | const issue = openIssue(app, made.value, repo.value, { title: "First", body: "hello" }); | |
| 55 | if (!issue.ok) throw new Error("issue"); | |
| 41 | 56 | }); |
| 42 | 57 | |
| 43 | 58 | afterAll(async () => { |
| @@ -58,18 +73,6 @@ test("the forge's signed-out pages raise exactly the findings named in KNOWN", a | ||
| 58 | 73 | }); |
| 59 | 74 | |
| 60 | 75 | test("a page that answers 200 names its canonical address, equal to og:url; a 404 names none", async () => { |
| 61 | const made = await createUser(app.db, { | |
| 62 | origin: "seed", | |
| 63 | trusted: true, | |
| 64 | username: "alice", | |
| 65 | email: "[email protected]", | |
| 66 | password: "a-good-passphrase", | |
| 67 | adminIfFirst: true, | |
| 68 | }); | |
| 69 | if (!made.ok) throw new Error("user"); | |
| 70 | const repo = await createRepo(app, made.value, { name: "notes", visibility: "public" }); | |
| 71 | if (!repo.ok) throw new Error("repo"); | |
| 72 | await commitToBranch(app, made.value, repo.value, { message: "seed", files: [{ path: "a.txt", content: "a" }] }); | |
| 73 | 76 | const head = async (path: string) => { |
| 74 | 77 | const res = await http.handle(new Request(`http://forge.test${path}`)); |
| 75 | 78 | return { status: res.status, html: await res.text() }; |
| @@ -86,3 +89,9 @@ test("a page that answers 200 names its canonical address, equal to og:url; a 40 | ||
| 86 | 89 | expect(missing.status).toBe(404); |
| 87 | 90 | expect(missing.html).not.toContain('rel="canonical"'); |
| 88 | 91 | }); |
| 92 | ||
| 93 | test("the walked repository pages exist", async () => { | |
| 94 | for (const path of ["/alice/notes", "/alice/notes/issues", "/alice/notes/issues/1"]) { | |
| 95 | expect((await http.handle(new Request(`http://forge.test${path}`))).status).toBe(200); | |
| 96 | } | |
| 97 | }); |
new above
offline
The path list is repeated by hand here. Build it as PATHS.filter((p) => p.startsWith("/alice")) so the two cannot drift.