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

Settings › Spend speaks the home page's language, no boxed card #10024

Merged opened this

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

Merged

mason/forge:mason/9997-settings-spend-speaks-the-home-page-s-la → main 2 commits fork

  • Merged. mason/9997-settings-spend-speaks-the-home-page-s-la was merged into main as 3fa2ce8.

Review

Sign in to review this change.
2 files changed +46 −5
src/web/pages/spend-tab.ts +1 −5
@@ -9,7 +9,6 @@ import { notePhase, takeSessionTime, timePhase } from "../../core/route_timing.t
99 import type { Ctx } from "../../http/context.ts";
1010 import { notFoundPage, signInFirst } from "../chrome.ts";
1111 import { html } from "../html.ts";
12 import { card, icon } from "../ui.ts";
1312 import { weekLine } from "../studio/week_line.ts";
1413 import { spendView } from "./spend.ts";
1514 import { usageShell } from "./usage-tabs.ts";
@@ -21,10 +20,7 @@ export function spendPage(ctx: Ctx): Response {
2120 notePhase(ctx.request, "session", takeSessionTime(ctx.request));
2221 const spend = timePhase(ctx.request, "spend", () => readSpend(ctx.app, new Date()));
2322 const rendering = performance.now();
24 const body = html`${weekLine(ctx.app)}<div id="spend" data-live="run.queued,run.started,run.finished,usage.*">${card(
25 spendView(spend),
26 { head: html`${icon("clock")}<h2>Spend</h2>` },
27 )}</div>`;
23 const body = html`${weekLine(ctx.app)}<div id="spend" data-live="run.queued,run.started,run.finished,usage.*"><section class="settings-block"><h2>Spend</h2>${spendView(spend)}</section></div>`;
2824 const response = usageShell(ctx, "spend", body);
2925 notePhase(ctx.request, "render", performance.now() - rendering);
3026 return response;
test/spend-language.test.ts added +45
@@ -0,0 +1,45 @@
1 /** Settings › Spend speaks the home page's language: a block, not a card (#9997). */
2 import { afterAll, beforeAll, expect, test } from "bun:test";
3 import { mkdtemp, rm } from "node:fs/promises";
4 import { tmpdir } from "node:os";
5 import { join } from "node:path";
6 import { createApp, type App } from "../src/app.ts";
7 import { createUser, getUserByName } from "../src/core/users.ts";
8 import { createSession } from "../src/core/sessions.ts";
9 import { serve, type Servers } from "../src/http/server.ts";
10 import { seedAdmin } from "./helpers/admin.ts";
11
12 let dataDir = "";
13 let app: App, servers: Servers;
14 let admin = "", plain = "";
15
16 beforeAll(async () => {
17 dataDir = await mkdtemp(join(tmpdir(), "forge-spend-lang-"));
18 app = createApp({ dataDir, port: 0 });
19 servers = await serve(app);
20 const a = await seedAdmin(app, { username: "alice", email: "[email protected]", password: "correct-horse-battery" });
21 if (!a.ok) throw new Error(a.error);
22 const b = await createUser(app.db, { origin: "seed", trusted: true, username: "bobby", email: "[email protected]", password: "correct-horse-battery" });
23 if (!b.ok) throw new Error(b.error);
24 admin = `forge_session=${createSession(app.db, getUserByName(app.db, "alice")!.id).token}`;
25 plain = `forge_session=${createSession(app.db, getUserByName(app.db, "bobby")!.id).token}`;
26 });
27 afterAll(async () => {
28 servers.stop();
29 app.close();
30 await rm(dataDir, { recursive: true, force: true });
31 });
32
33 const main = (page: string) => page.slice(page.indexOf("<main"), page.indexOf("</main>"));
34
35 test("the spend view is one settings-block under an h2, no card", async () => {
36 const m = main(await (await fetch(`${servers.url}/settings/spend`, { headers: { cookie: admin } })).text());
37 expect(m).not.toContain('class="card');
38 expect(m).toMatch(/<section class="settings-block">\s*<h2>Spend<\/h2>/);
39 expect(m).toContain('id="spend" data-live="run.queued,run.started,run.finished,usage.*"');
40 });
41
42 test("a non-admin gets the one 404", async () => {
43 const r = await fetch(`${servers.url}/settings/spend`, { headers: { cookie: plain } });
44 expect(r.status).toBe(404);
45 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs