mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-03 05:45:04 +03:00
fix(agent-bridge-ui): remove double-write of risk-accepted localStorage (M5)
AgentCard.handleRiskAccept was calling markRiskAccepted() before opening the RiskNoticeModal, which itself writes the same key via dontShowAgainKey on accept. Remove the redundant markRiskAccepted call and delete the now-unused helper so RiskNoticeModal (D16) is the sole canonical persistence owner. Add a spy-based test asserting the key is written exactly once per accept.
This commit is contained in:
@@ -21,13 +21,6 @@ function hasAcceptedRisk(agentId: string): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
function markRiskAccepted(agentId: string): void {
|
||||
try {
|
||||
localStorage.setItem(RISK_STORAGE_KEY_PREFIX + agentId, "true");
|
||||
} catch {
|
||||
// ignore storage errors
|
||||
}
|
||||
}
|
||||
|
||||
interface AgentCardProps {
|
||||
target: MitmTarget;
|
||||
@@ -112,7 +105,6 @@ export function AgentCard({
|
||||
};
|
||||
|
||||
const handleRiskAccept = async () => {
|
||||
markRiskAccepted(target.id);
|
||||
setRiskModalOpen(false);
|
||||
await reallyToggleDns(true);
|
||||
};
|
||||
|
||||
@@ -204,6 +204,61 @@ describe("AgentCard RiskNoticeModal", { timeout: 30000 }, () => {
|
||||
expect(stored).toBe("true");
|
||||
}, 30000);
|
||||
|
||||
it("accepting risk writes localStorage exactly once (RiskNoticeModal is sole writer)", async () => {
|
||||
const { AgentCard } = await import(
|
||||
"../../../src/app/(dashboard)/dashboard/tools/agent-bridge/components/AgentCard"
|
||||
);
|
||||
|
||||
const setItemSpy = vi.spyOn(Storage.prototype, "setItem");
|
||||
|
||||
const onDnsToggle = vi.fn().mockResolvedValue(undefined);
|
||||
const container = makeContainer();
|
||||
|
||||
await act(async () => {
|
||||
const root = createRoot(container);
|
||||
root.render(
|
||||
React.createElement(AgentCard, {
|
||||
target: mockTarget,
|
||||
agentState: baseAgentState,
|
||||
serverRunning: true,
|
||||
mappings: [],
|
||||
onDnsToggle,
|
||||
onMappingsSave: vi.fn(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// Expand card
|
||||
const header = container.querySelector("button[aria-expanded]");
|
||||
await act(async () => {
|
||||
header?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||
});
|
||||
|
||||
// Click DNS toggle to open modal
|
||||
const dnsBtn = Array.from(container.querySelectorAll("button")).find((b) =>
|
||||
b.textContent?.includes("startDns")
|
||||
);
|
||||
await act(async () => {
|
||||
dnsBtn?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||
});
|
||||
|
||||
// Accept modal
|
||||
const acceptBtn = Array.from(document.querySelectorAll("button")).find((b) =>
|
||||
b.textContent?.includes("understand")
|
||||
);
|
||||
await act(async () => {
|
||||
acceptBtn?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||
});
|
||||
|
||||
const riskKey = "omniroute-agentbridge-risk-dismissed-copilot";
|
||||
const riskWrites = setItemSpy.mock.calls.filter(([key]) => key === riskKey);
|
||||
// Must be exactly ONE write — RiskNoticeModal is the sole persistence owner (D16)
|
||||
expect(riskWrites).toHaveLength(1);
|
||||
expect(riskWrites[0][1]).toBe("true");
|
||||
|
||||
setItemSpy.mockRestore();
|
||||
}, 30000);
|
||||
|
||||
it("second DNS activation does NOT open modal when localStorage flag is set", async () => {
|
||||
// Pre-set the localStorage flag (simulates accepted risk on previous session)
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user