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

The "following" card on a repository is built with card(), not hand-rolled markup #2898

Merged opened this

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

Merged

scout/forge:scout/2891-the-following-card-on-a-repository-is-bu → main 1 commit fork

  • Merged. scout/2891-the-following-card-on-a-repository-is-bu was merged into main as 4bab707.

Review

Sign in to review this change.
2 files changed +72 −6
src/web/pages/following.ts +3 −6
@@ -325,9 +325,7 @@ export function followingCard(
325325 >; say there what to do.`
326326 : null;
327327
328 return html`<section class="card following" id="following">
329 <div class="card-body">
330 <div class="following-head">
328 const body = html`<div class="following-head">
331329 <span class="following-eyebrow"
332330 >${icon("fork")} following
333331 <a href="/${parent.ownerName}/${parent.name}">${parentName}</a></span
@@ -366,9 +364,8 @@ export function followingCard(
366364 this one.</a
367365 >
368366 </p>`,
369 )}
370 </div>
371 </section>`;
367 )}`;
368 return card(body, { id: "following", extra: "following" });
372369 }
373370
374371 /**
test/following-card.test.ts added +69
@@ -0,0 +1,69 @@
1 /**
2 * The "following" card on a fork's page is built by card() (#2891): one
3 * `div.card.following#following` with its badge and sentence, not hand-rolled
4 * markup.
5 */
6 import { afterAll, beforeAll, expect, test } from "bun:test";
7 import { mkdtemp, rm } from "node:fs/promises";
8 import { tmpdir } from "node:os";
9 import { join } from "node:path";
10 import { commitToBranch, createRepo, forkRepo } from "../src/actions/repos.ts";
11 import { createApp, type App } from "../src/app.ts";
12 import { createUser } from "../src/core/users.ts";
13 import { serve, type Servers } from "../src/http/server.ts";
14 import { promote } from "./helpers/members.ts";
15
16 let dataDir: string;
17 let app: App;
18 let servers: Servers;
19
20 beforeAll(async () => {
21 dataDir = await mkdtemp(join(tmpdir(), "forge-following-card-"));
22 app = createApp({ dataDir, port: 0 });
23 servers = await serve(app);
24 const alice = await createUser(app.db, {
25 origin: "seed",
26 trusted: true,
27 username: "alice",
28 email: "[email protected]",
29 password: "a-good-passphrase",
30 adminIfFirst: true,
31 });
32 if (!alice.ok) throw new Error(alice.error);
33 const lib = await createRepo(app, alice.value, { name: "lib", visibility: "public" });
34 if (!lib.ok) throw new Error(String(lib.error));
35 const seeded = await commitToBranch(app, alice.value, lib.value, {
36 message: "Start",
37 files: [{ path: "README.md", content: "# lib\n" }],
38 });
39 if (!seeded.ok) throw new Error(JSON.stringify(seeded.error));
40 const bob = await createUser(app.db, {
41 origin: "seed",
42 trusted: true,
43 username: "bob",
44 email: "[email protected]",
45 password: "a-good-passphrase",
46 });
47 if (!bob.ok) throw new Error(bob.error);
48 promote(app.db, bob.value);
49 const forked = await forkRepo(app, bob.value, lib.value);
50 if (!forked.ok) throw new Error(String(forked.error));
51 }, 60_000);
52
53 afterAll(async () => {
54 servers.stop();
55 app.close();
56 await rm(dataDir, { recursive: true, force: true });
57 });
58
59 test("a fork's page has the following card, built by card()", async () => {
60 const path = "/bob/lib";
61 const res = await fetch(`${servers.url}${path}`, { headers: { cookie: "forge_mode=dev" } });
62 const page = await res.text();
63 const m = page.match(/<div\s+class="card following"\s+id="following"[^>]*>[\s\S]*?<div class="card-body">([\s\S]*?)<\/div>\s*<\/div>/);
64 expect(page).not.toContain("<section class=\"card following\"");
65 expect(m).not.toBeNull();
66 expect(m![0]).toContain("following-eyebrow");
67 expect(m![0]).toContain('class="badge');
68 expect(m![0]).toContain("following-sentence");
69 }, 30_000);

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs