fix(extension): dismiss overlay on borrow timeout

Send borrow-cancel when the confirmation timeout denies, and add a
timer fallback so auto-deny does not depend only on CSS transitionend.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
BB-fat
2026-07-18 22:31:27 +08:00
co-authored by Cursor
parent 9f82d89788
commit 11ec51dfb8
5 changed files with 95 additions and 34 deletions
@@ -38,9 +38,6 @@ describe("BorrowConfirmationOverlay", () => {
});
}
expect(screen.getByText("0 秒后自动拒绝")).toBeTruthy();
await act(async () => {
await vi.advanceTimersByTimeAsync(1000);
});
const progressCircle = container.querySelectorAll("svg circle")[1];
expect(progressCircle).toBeTruthy();
await act(() => {
@@ -58,6 +55,42 @@ describe("BorrowConfirmationOverlay", () => {
expect(onAllow).not.toHaveBeenCalled();
});
it("auto-denies via timer fallback when progress transitionend never fires", async () => {
const onAllow = vi.fn();
const onDeny = vi.fn();
render(
<BorrowConfirmationOverlay
requests={[
{
id: "req-fallback",
isActiveTab: true,
tabTitle: "Example",
timeoutMs: 5000,
onAllow,
onDeny,
},
]}
/>,
);
for (let i = 0; i < 5; i++) {
await act(async () => {
await vi.advanceTimersByTimeAsync(1000);
});
}
expect(screen.getByText("0 秒后自动拒绝")).toBeTruthy();
// No transitionend — the PROGRESS_TRANSITION_MS fallback must still deny.
await act(async () => {
await vi.advanceTimersByTimeAsync(1000);
});
await act(async () => {
await vi.advanceTimersByTimeAsync(150);
});
expect(onDeny).toHaveBeenCalledTimes(1);
expect(onAllow).not.toHaveBeenCalled();
});
it("only invokes onDeny once when deny is clicked repeatedly", async () => {
const onAllow = vi.fn();
const onDeny = vi.fn();