Fix confirmed Dot Runner shutdown and revoked binding cache

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-06 20:00:41 -05:00
1 parent 5201456bfc
commit fccf35f90f
5 files changed
+89 -2

No files matched your search

@@ -61,3 +61,17 @@ it("does not restore a stale binding while revocation refreshes the connection",
expect(onBinding).toHaveBeenLastCalledWith("");
expect(Array.from(container.querySelectorAll("button")).some(button => button.textContent === "Pair Dot")).toBe(true);
});
it("keeps a revoked binding cleared when the follow-up connection read fails", async () => {
api.get.mockResolvedValue({ enabled: true, resourceUrl: "https://paperclip.example/mcp/runner", binding });
api.delete.mockImplementation(async () => { api.get.mockRejectedValue(new Error("Connection refresh failed")); });
await render();
expect(container.querySelector("output")?.textContent).toBe(binding.id);
await act(async () => Array.from(container.querySelectorAll("button")).find(button => button.textContent === "Revoke connection")!.click());
await flush();
expect(container.querySelector("output")?.textContent).toBe("");
expect(onBinding).toHaveBeenLastCalledWith("");
expect(container.querySelector("[role=alert]")?.textContent).toBe("Connection refresh failed");
expect(client.getQueryData(["dot-binding", "company", "agent"])).toMatchObject({ binding: null });
expect(Array.from(container.querySelectorAll("button")).some(button => button.textContent === "Revoke connection")).toBe(false);
});
+6 -1
View File
@@ -26,7 +26,12 @@ export function DotRunnerConnection({ companyId, agentId, bindingId, onBinding }
const test = useMutation({ mutationFn: () => api.post(path + "/event-test", {}),
onSuccess: () => { void client.invalidateQueries({ queryKey: key }); } });
const revoke = useMutation({ mutationFn: () => api.delete(path),
onSuccess: async () => { await client.invalidateQueries({ queryKey: key }); setPairing(null); onBinding(""); } });
onSuccess: async () => {
await client.cancelQueries({ queryKey: key });
client.setQueryData<Connection>(key, previous => previous ? { ...previous, binding: null } : previous);
setPairing(null); onBinding("");
await client.invalidateQueries({ queryKey: key });
} });
const existingBindingId = state.data?.binding?.id;
useEffect(() => {
if (existingBindingId && existingBindingId !== bindingId && !revoke.isPending) onBinding(existingBindingId);