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

Sentinel: shared:01m23vygyffx5hg2f5vm8r74sr:2ycx19qxfm was degraded 113 minutes today: trevato/forge: "verify an email from the People screen > an admin verifies the person under the cursor and the row chan… #7812

Merged opened this

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

Merged

mason/forge:mason/7768-sentinel-shared-01m23vygyffx5hg2f5vm8r74 → main 2 commits fork 1 thread · 1 unresolved

  • Merged. mason/7768-sentinel-shared-01m23vygyffx5hg2f5vm8r74 was merged into main as 049afa1.

Review

Sign in to review this change.
3 files changed +26 −3
src/tui/app/app.ts +3 −1
@@ -263,6 +263,8 @@ export interface AppOpts extends SessionOpts {
263263 graphics: GraphicsSetting;
264264 icons: IconSetting;
265265 }) => void;
266 /** How long a toast stays up. @default 4000 */
267 readonly toastMs?: number;
266268 readonly root: (ctx: Ctx) => Screen;
267269 readonly commands?: (ctx: Ctx) => Command[];
268270 /** Turns the palette into the global search box. */
@@ -554,7 +556,7 @@ export class App {
554556 }
555557
556558 toast(text: string, tone: Tone = "default"): void {
557 this.toastState = { text, tone, until: Date.now() + TOAST_MS };
559 this.toastState = { text, tone, until: Date.now() + (this.opts.toastMs ?? TOAST_MS) };
558560 this.invalidate();
559561 }
560562
src/tui/forge.ts +2
@@ -623,6 +623,8 @@ function askFor(
623623
624624 export interface ForgeAppOptions extends SessionOpts {
625625 readonly terminal: Terminal;
626 /** How long a toast stays up; a test that reads one after a settle makes it long. */
627 readonly toastMs?: number;
626628 }
627629
628630 /** Assemble the terminal app for one identity, theme persistence included. */
test/tui-people-verify.test.ts +21 −2
@@ -42,9 +42,12 @@ describe("verify an email from the People screen", () => {
4242 await rm(dataDir, { recursive: true, force: true });
4343 });
4444
45 async function open(user: User) {
45 // A toast lives four wall-clock seconds by default, and a loaded check
46 // machine can take longer than that to settle after the key that raised it.
47 // These tests read toasts after a settle, so the toast outlasts the test.
48 async function open(user: User, toastMs = 10 * 60_000) {
4649 const terminal = headlessTerminal(120, 40);
47 const { app } = createForgeApp(forge, { sshUsername: "alice", remoteAddress: "127.0.0.1", fingerprint: "SHA256:test", user }, { terminal, exitHooks: false });
50 const { app } = createForgeApp(forge, { sshUsername: "alice", remoteAddress: "127.0.0.1", fingerprint: "SHA256:test", user }, { terminal, exitHooks: false, toastMs });
4851 app.start();
4952 const press = async (...keys: string[]): Promise<void> => {
5053 for (const key of keys) app.dispatch({ type: "key", key, ctrl: false, alt: false, shift: false });
@@ -88,6 +91,22 @@ describe("verify an email from the People screen", () => {
8891 }
8992 }, 30_000);
9093
94 test("a toast is gone once its time has passed, which is why the tests above hold it up", async () => {
95 const fred = await createUser(forge.db, { username: "fred", email: "[email protected]", password: "a-long-passphrase", origin: "seed" });
96 if (!fred.ok) throw new Error("signup failed");
97 markUnproven(forge.db, fred.value.id);
98 const h = await open({ ...alice }, 1);
99 try {
100 await h.press("v", "y");
101 expect(emailVerified(forge.db, fred.value.id)).toBe(true);
102 await Bun.sleep(20);
103 await settleApp(h.app);
104 expect(h.text()).not.toContain("fred's email is verified.");
105 } finally {
106 h.app.stop();
107 }
108 }, 30_000);
109
91110 test("`r` still changes a role on the list", async () => {
92111 const h = await open({ ...alice });
93112 try {

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs