File size: 4,536 Bytes
fd2c364 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | /**
* Regression test for the automation-detail-page bug where every
* activity-log row mounted a (closed) RunLogsModal, each of which fired a
* `/api/conversations?ids=<id>` request on page load.
*
* useBashCommandLogs must honor its `enabled` flag (set to the modal's
* `isOpen`) when resolving the conversation: a closed modal fetches
* nothing; opening it resolves exactly one conversation lookup.
*
* Per the testing rules we exercise the REAL useUserConversation and mock
* only the underlying service it depends on
* (AgentServerConversationService.batchGetAppConversations).
*/
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { renderHook, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useBashCommandLogs } from "#/hooks/query/use-bash-command-logs";
// ββ Mocks βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
const { batchGetAppConversationsMock, listOutputsMock, useActiveBackendMock } =
vi.hoisted(() => ({
batchGetAppConversationsMock: vi.fn(),
listOutputsMock: vi.fn(),
useActiveBackendMock: vi.fn(),
}));
vi.mock(
"#/api/conversation-service/agent-server-conversation-service.api",
() => ({
default: {
batchGetAppConversations: (...args: unknown[]) =>
batchGetAppConversationsMock(...args),
},
}),
);
vi.mock("#/api/bash-service/bash-service.api", () => ({
default: { listOutputs: (...args: unknown[]) => listOutputsMock(...args) },
}));
vi.mock("#/contexts/active-backend-context", () => ({
useActiveBackend: () => useActiveBackendMock(),
}));
// ββ Helpers βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// Build a wrapper whose QueryClient is created once and stays stable for the
// lifetime of the test. Creating the client inside the component body would
// re-instantiate it on every wrapper re-render (e.g. a `rerender` call),
// discarding the cache and tripping TanStack Query dev-mode warnings.
function makeWrapper() {
const client = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
return function Wrapper({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={client}>{children}</QueryClientProvider>
);
};
}
beforeEach(() => {
batchGetAppConversationsMock.mockReset();
listOutputsMock.mockReset();
useActiveBackendMock.mockReset();
useActiveBackendMock.mockReturnValue({
backend: { id: "bk-1", kind: "local" },
orgId: null,
});
listOutputsMock.mockResolvedValue([]);
batchGetAppConversationsMock.mockResolvedValue([
{ conversation_url: null, session_api_key: null, sandbox_status: null },
]);
});
afterEach(() => {
vi.clearAllMocks();
});
// ββ Tests βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
describe("useBashCommandLogs β gates the conversation lookup on `enabled`", () => {
it("does not fetch the conversation while the modal is closed (enabled=false)", () => {
// Arrange + Act: a RunLogsModal mounted closed for an activity-log row.
renderHook(
() =>
useBashCommandLogs({
conversationId: "conv-1",
bashCommandId: "cmd-1",
enabled: false,
}),
{ wrapper: makeWrapper() },
);
// Assert: no /api/conversations request is issued on page load.
expect(batchGetAppConversationsMock).not.toHaveBeenCalled();
});
it("fetches the conversation exactly once when the modal opens (enabled=true)", async () => {
// Arrange + Act: the user opens the row's logs modal.
renderHook(
() =>
useBashCommandLogs({
conversationId: "conv-1",
bashCommandId: "cmd-1",
enabled: true,
}),
{ wrapper: makeWrapper() },
);
// Assert: one lookup fires for that conversation id (functionality preserved).
await waitFor(() =>
expect(batchGetAppConversationsMock).toHaveBeenCalledWith(["conv-1"]),
);
expect(batchGetAppConversationsMock).toHaveBeenCalledTimes(1);
});
});
|