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

Fast test/apps-token.test.ts: chop and rewrite under the budget (1 s a test, 10 s a file) #12065

Merged opened this

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

Merged

scout/forge:scout/1255-fast-test-apps-token-test-ts-chop-and-re → main 2 commits fork

  • Merged. scout/1255-fast-test-apps-token-test-ts-chop-and-re was merged into main as 51fb249.

Review

Sign in to review this change.
1 file changed +28 −15
test/apps-token.test.ts +28 −15
@@ -185,6 +185,7 @@ describe("app tokens: live, end to end", () => {
185185 let bob: User;
186186 let repo: Repo;
187187 let record: AppRecord;
188 let skew = 0;
188189 const DOMAIN = "apps.test";
189190 const HOST = `live.${DOMAIN}`;
190191
@@ -202,7 +203,7 @@ describe("app tokens: live, end to end", () => {
202203 (r) => where(r) && (r.state === "ok" || r.state === "failed"),
203204 );
204205 if (run) return run;
205 await Bun.sleep(100);
206 await Bun.sleep(10); // real-timer: polls a deploy worker running in the background
206207 }
207208 throw new Error("run did not settle in time");
208209 }
@@ -231,7 +232,8 @@ describe("app tokens: live, end to end", () => {
231232 scheme: "http",
232233 publicPort: servers.port,
233234 forgeUrl: servers.url,
234 sweepEveryMs: 200,
235 sweepEveryMs: 20,
236 clock: () => Date.now() + skew,
235237 });
236238 await runtime.start();
237239 alice = await user(app, "alice");
@@ -298,16 +300,15 @@ describe("app tokens: live, end to end", () => {
298300 const [hers, his] = await Promise.all([listen(aliceRo), listen(bobRo)]);
299301 expect(hers.status).toBe(200);
300302 expect(hers.headers.get("content-type")).toContain("text/event-stream");
301 const opened = openIssue(app, alice, secret.value, {
302 title: "the private plan",
303 });
304 expect(opened.ok).toBe(true);
303 // The private issue first, then a public one both may read: events
304 // arrive in order, so by the time bob hears the public one he would
305 // have heard the private one. No waiting for silence.
306 expect(openIssue(app, alice, secret.value, { title: "the private plan" }).ok).toBe(true);
307 expect(openIssue(app, alice, repo, { title: "the public plan" }).ok).toBe(true);
305308 const heard = await readUntil(hers, (t) => t.includes("alice/secret"));
306309 expect(heard).toContain("event: forge");
307 // Bob cannot read alice/secret: his stream stays quiet about it.
308 await expect(
309 readUntil(his, (t) => t.includes("alice/secret"), 1_000),
310 ).rejects.toThrow("did not say it");
310 const bobHeard = await readUntil(his, (t) => t.includes("alice/live"));
311 expect(bobHeard).not.toContain("alice/secret");
311312 });
312313
313314 test("acceptance: the sample page lists `now`, offers `say`, and goes live on /events", async () => {
@@ -348,17 +349,29 @@ describe("app tokens: live, end to end", () => {
348349 });
349350 expect(stream.status).toBe(200);
350351 const said = readUntil(stream, (t) => t.includes("event: changed"));
351 await Bun.sleep(300); // let the relay open its upstream
352 openIssue(app, alice, repo, { title: "Another thing" });
353 expect(await said).toContain("data: {}");
352 // The relay opens its upstream a moment after it answers: say
353 // something until it hears.
354 const poke = setInterval(
355 () => openIssue(app, alice, repo, { title: "Another thing" }),
356 15,
357 );
358 try {
359 expect(await said).toContain("data: {}");
360 } finally {
361 clearInterval(poke);
362 }
354363 // And the fragment the page refetches lists the same runs.
355364 expect(await (await viaHost("/now")).text()).toContain("bob");
356365 }, 30_000);
357366
358367 test("the sweep renews a running environment's token", async () => {
359368 const before = appTokens("production")[0]!;
360 await Bun.sleep(1_100);
361 const after = appTokens("production")[0]!;
369 skew += 60_000; // the sweep's clock moves a minute; no waiting for it
370 let after = appTokens("production")[0]!;
371 for (let i = 0; i < 500 && after.expiresAt === before.expiresAt; i++) {
372 await Bun.sleep(5); // real-timer: the sweep runs on its own 20 ms interval; its clock is already faked
373 after = appTokens("production")[0]!;
374 }
362375 expect(after.id).toBe(before.id);
363376 expect(Date.parse(after.expiresAt!)).toBeGreaterThan(
364377 Date.parse(before.expiresAt!),

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs