Skip to content

Commit 2e7d285

Browse files
committed
Pin reservation Esc drain and stale release epoch
1 parent 9c67b94 commit 2e7d285

1 file changed

Lines changed: 50 additions & 5 deletions

File tree

src/tui/slash-popup-gate.test.ts

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ describe("slash/palette accept holds the host until dispatch settles", () => {
387387
closeInsetOverlay(shell);
388388
await Promise.resolve();
389389
expect(shell.overlayKind).toBe("help");
390-
expect(resolved).not.toBeUndefined();
390+
expect(resolved).toEqual({ allow: false });
391391
} finally {
392392
dispose();
393393
}
@@ -428,7 +428,7 @@ describe("slash/palette accept holds the host until dispatch settles", () => {
428428
acceptOverlaySelection(shell);
429429
await Promise.resolve();
430430
expect(shell.overlayKind).toBe("help");
431-
expect(liveResolved).not.toBeUndefined();
431+
expect(liveResolved).toEqual({ allow: false });
432432
expect(queuedResolved).toBeUndefined();
433433

434434
await Bun.sleep(20);
@@ -588,7 +588,7 @@ describe("slash/palette accept holds the host until dispatch settles", () => {
588588
closeInsetOverlay(shell);
589589
await Promise.resolve();
590590
expect(shell.overlayKind).toBe("settings");
591-
expect(resolved).not.toBeUndefined();
591+
expect(resolved).toEqual({ allow: false });
592592
} finally {
593593
dispose();
594594
}
@@ -649,7 +649,7 @@ describe("slash/palette accept holds the host until dispatch settles", () => {
649649
closeInsetOverlay(shell);
650650
await Promise.resolve();
651651
expect(shell.overlayKind).toBe("mcp");
652-
expect(resolved).not.toBeUndefined();
652+
expect(resolved).toEqual({ allow: false });
653653
} finally {
654654
dispose();
655655
}
@@ -1061,7 +1061,7 @@ describe("overlay host occupancy and opt-in deferral", () => {
10611061
closeInsetOverlay(shell);
10621062
await Promise.resolve();
10631063
expect(shell.overlayKind).toBe("add_provider");
1064-
expect(resolved).not.toBeUndefined();
1064+
expect(resolved).toEqual({ allow: false });
10651065
} finally {
10661066
dispose();
10671067
}
@@ -1083,4 +1083,49 @@ describe("overlay host occupancy and opt-in deferral", () => {
10831083
expect(isOverlayHostIdle(shell)).toBe(true);
10841084
});
10851085
});
1086+
1087+
test("Esc during a reservation drains a queued gate without denying it", async () => {
1088+
await withShell(async ({ shell, press, render }) => {
1089+
const emitter = new EventEmitter();
1090+
const dispose = wireGates(emitter, shell);
1091+
try {
1092+
reserveOverlayHost(shell);
1093+
let resolved: unknown;
1094+
emitPermissionGate(emitter, (outcome) => {
1095+
resolved = outcome;
1096+
});
1097+
expect(shell.overlayKind).not.toBe("permissions");
1098+
expect(resolved).toBeUndefined();
1099+
1100+
press("Escape");
1101+
await render();
1102+
await Bun.sleep(60);
1103+
expect(shell.overlayKind).toBe("permissions");
1104+
expect(resolved).toBeUndefined();
1105+
} finally {
1106+
dispose();
1107+
}
1108+
});
1109+
});
1110+
1111+
test("stale reservation release does not drop a later hold", async () => {
1112+
await withShell(async ({ shell, press, render }) => {
1113+
const first = reserveOverlayHost(shell);
1114+
expect(isOverlayHostIdle(shell)).toBe(false);
1115+
1116+
press("Escape");
1117+
await render();
1118+
await Bun.sleep(60);
1119+
expect(isOverlayHostIdle(shell)).toBe(true);
1120+
1121+
const second = reserveOverlayHost(shell);
1122+
expect(isOverlayHostIdle(shell)).toBe(false);
1123+
1124+
first();
1125+
expect(isOverlayHostIdle(shell)).toBe(false);
1126+
1127+
second();
1128+
expect(isOverlayHostIdle(shell)).toBe(true);
1129+
});
1130+
});
10861131
});

0 commit comments

Comments
 (0)