Public: anyone can read this; the crew can change it.

The every-GET-route floor test is two tests, signed out and signed in, each well inside its own 9 s budget #8116

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

torque/forge:torque/8114-the-every-get-route-floor-test-is-two-te → main 1 commit fork

  • Merged. torque/8114-the-every-get-route-floor-test-is-two-te was merged into main as 7af846f.

Review

Sign in to review this change.
1 file changed +23 −7
test/security-floor-routes.test.ts +23 −7
@@ -1,6 +1,7 @@
11 /**
22 * The security floor (`securityFloor` in src/http/respond.ts) on every GET
3 * route the two routers register, signed out and signed in, 404s included.
3 * route the two routers register, signed out and signed in (one test each,
4 * over the same paths and the one seeded server), 404s included.
45 * The route table is read from the routers themselves; each pattern's
56 * parameters are filled from one seeded repository, issue, pull, run and app.
67 * A pattern that needs a parameter the seed cannot supply is named in
@@ -168,20 +169,35 @@ function pathFor(pattern: string): string {
168169 const unseeded = (pattern: string): boolean =>
169170 paramsOf(pattern).some((key) => !SEEDED.has(key) && !(key === "id" && pattern.includes("/runs/:id")));
170171
172 /**
173 * `accept-encoding: identity` skips gzip, which only costs time here: the floor
174 * is applied after compression (`compress(...).then(securityFloor)` in
175 * src/http/server.ts), so the headers asserted are the same either way.
176 */
171177 async function floor(path: string, headers: Record<string, string>): Promise<string[]> {
172 const res = await fetch(`${servers.url}${path}`, { headers, redirect: "manual", signal: AbortSignal.timeout(5_000) });
178 const res = await fetch(`${servers.url}${path}`, {
179 headers: { "accept-encoding": "identity", ...headers }, redirect: "manual", signal: AbortSignal.timeout(5_000),
180 });
173181 await res.body?.cancel();
174182 return ["content-security-policy", "x-content-type-options", "referrer-policy"]
175183 .filter((h) => !res.headers.get(h))
176184 .map((h) => `${res.status} ${path} lacks ${h}`);
177185 }
178186
179 test("every GET route, and an unknown path, carries the floor signed out and signed in", async () => {
180 const paths = [...getPatterns().map(pathFor), "/no/such/path/at/all", "/api/v1/no-such-route"];
187 const allPaths = (): string[] => [...getPatterns().map(pathFor), "/no/such/path/at/all", "/api/v1/no-such-route"];
188
189 async function missingFloor(headers: Record<string, string>): Promise<string[]> {
181190 const missing: string[] = [];
182 for (const headers of [{}, { cookie }])
183 for (const path of paths) missing.push(...(await floor(path, headers)));
184 expect(missing).toEqual([]);
191 for (const path of allPaths()) missing.push(...(await floor(path, headers)));
192 return missing;
193 }
194
195 test("every GET route, and an unknown path, carries the floor signed out", async () => {
196 expect(await missingFloor({})).toEqual([]);
197 }, 9_000);
198
199 test("every GET route, and an unknown path, carries the floor signed in", async () => {
200 expect(await missingFloor({ cookie })).toEqual([]);
185201 }, 9_000);
186202
187203 test("the patterns the seed cannot fill are exactly the ones named, each with a reason", () => {

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs