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

A client's first screen leaves archived apps out #3486

Merged opened this

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

Merged

scout/forge:scout/3479-a-client-s-first-screen-leaves-archived → main 1 commit fork

  • Merged. scout/3479-a-client-s-first-screen-leaves-archived was merged into main as 1eb6c7e.

Review

Sign in to review this change.
2 files changed +29 −3
src/core/client-apps.ts +3 −3
@@ -6,7 +6,7 @@
66
77 import type { App } from "../app.ts";
88 import { spawnedRepos } from "./next-steps.ts";
9 import type { Repo } from "./repos.ts";
9 import { withoutArchived, type Repo } from "./repos.ts";
1010 import type { User } from "./users.ts";
1111
1212 export interface ClientApp {
@@ -17,12 +17,12 @@ export interface ClientApp {
1717 readonly queued: number;
1818 }
1919
20 /** The apps `user` can see on a spawned forge, each with its agent counts. */
20 /** The apps `user` can see on a spawned forge, each with its agent counts; archived ones are put away, not shown. */
2121 export async function clientAppRows(
2222 app: App,
2323 user: User,
2424 ): Promise<readonly ClientApp[]> {
25 const repos = await spawnedRepos(app, user);
25 const repos = withoutArchived(await spawnedRepos(app, user));
2626 if (repos.length === 0) return [];
2727 const rows = app.db
2828 .query<{ repo_id: string; state: string; n: number }, string[]>(
test/client-home.test.ts +26
@@ -12,7 +12,9 @@ import { join } from "node:path";
1212 import { createRepo } from "../src/actions/repos.ts";
1313 import { childDirOf, spawnForge } from "../src/actions/spawn.ts";
1414 import { createApp, type App } from "../src/app.ts";
15 import { clientAppRows } from "../src/core/client-apps.ts";
1516 import { addCrew, createAgentRow, setCrewRole } from "../src/core/agents.ts";
17 import { moveArchived } from "../src/core/repos.ts";
1618 import { createSession } from "../src/core/sessions.ts";
1719 import { linkEveryday } from "../src/core/everyday.ts";
1820 import { createUser, getUserByName } from "../src/core/users.ts";
@@ -291,4 +293,28 @@ describe("a client's first screen", () => {
291293 expect(app.screen.toText()).not.toContain("Shipped per hour");
292294 app.stop();
293295 });
296
297 test("an archived app leaves the first screen and comes back when woken", async () => {
298 const maria = getUserByName(child.db, "maria")!;
299 const second = await createRepo(child, maria, { name: "cafe", owner: "marias" });
300 if (!second.ok) throw new Error(JSON.stringify(second.error));
301 const bakery = child.db
302 .query<{ id: string }, []>("SELECT id FROM repo WHERE name = 'bakery'")
303 .get()!;
304 const names = async () =>
305 (await clientAppRows(child, maria)).map((r) => r.repo.name).sort();
306 expect(await names()).toEqual(["bakery", "cafe"]);
307 expect(moveArchived(child.db, bakery.id, true)).toBe(true);
308 expect(await names()).toEqual(["cafe"]);
309 const apps = async () => {
310 const home = main(await page(owner));
311 return home.slice(home.indexOf('id="client-apps"'));
312 };
313 expect(await apps()).not.toContain('href="/marias/bakery"');
314 expect(await apps()).toContain('href="/marias/cafe"');
315 expect((await fetch(url("/marias/bakery"), { headers: { cookie: owner } })).status).toBe(200);
316 expect(moveArchived(child.db, bakery.id, false)).toBe(true);
317 expect(await names()).toEqual(["bakery", "cafe"]);
318 expect(await apps()).toContain('href="/marias/bakery"');
319 });
294320 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs