Skip to content

Commit bfb9aa4

Browse files
fix(site): only attempt to watch when dev containers enabled (#18892)
1 parent ca6b5e3 commit bfb9aa4

File tree

2 files changed

+71
-19
lines changed

2 files changed

+71
-19
lines changed

site/src/modules/resources/useAgentContainers.test.tsx

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,19 @@ import type { WorkspaceAgentListContainersResponse } from "api/typesGenerated";
44
import * as GlobalSnackbar from "components/GlobalSnackbar/utils";
55
import { http, HttpResponse } from "msw";
66
import type { FC, PropsWithChildren } from "react";
7-
import { QueryClient, QueryClientProvider } from "react-query";
7+
import { act } from "react";
8+
import { QueryClientProvider } from "react-query";
89
import {
910
MockWorkspaceAgent,
1011
MockWorkspaceAgentDevcontainer,
1112
} from "testHelpers/entities";
13+
import { createTestQueryClient } from "testHelpers/renderHelpers";
1214
import { server } from "testHelpers/server";
1315
import type { OneWayWebSocket } from "utils/OneWayWebSocket";
1416
import { useAgentContainers } from "./useAgentContainers";
1517

1618
const createWrapper = (): FC<PropsWithChildren> => {
17-
const queryClient = new QueryClient({
18-
defaultOptions: {
19-
queries: {
20-
retry: false,
21-
},
22-
},
23-
});
19+
const queryClient = createTestQueryClient();
2420
return ({ children }) => (
2521
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
2622
);
@@ -111,22 +107,29 @@ describe("useAgentContainers", () => {
111107
),
112108
);
113109

114-
const { unmount } = renderHook(
110+
const { result, unmount } = renderHook(
115111
() => useAgentContainers(MockWorkspaceAgent),
116112
{
117113
wrapper: createWrapper(),
118114
},
119115
);
120116

121-
// Simulate message event with parsing error
117+
// Wait for initial query to complete
118+
await waitFor(() => {
119+
expect(result.current).toEqual([MockWorkspaceAgentDevcontainer]);
120+
});
121+
122+
// Now simulate message event with parsing error
122123
const messageHandler = mockSocket.addEventListener.mock.calls.find(
123124
(call) => call[0] === "message",
124125
)?.[1];
125126

126127
if (messageHandler) {
127-
messageHandler({
128-
parseError: new Error("Parse error"),
129-
parsedMessage: null,
128+
act(() => {
129+
messageHandler({
130+
parseError: new Error("Parse error"),
131+
parsedMessage: null,
132+
});
130133
});
131134
}
132135

@@ -166,20 +169,27 @@ describe("useAgentContainers", () => {
166169
),
167170
);
168171

169-
const { unmount } = renderHook(
172+
const { result, unmount } = renderHook(
170173
() => useAgentContainers(MockWorkspaceAgent),
171174
{
172175
wrapper: createWrapper(),
173176
},
174177
);
175178

176-
// Simulate error event
179+
// Wait for initial query to complete
180+
await waitFor(() => {
181+
expect(result.current).toEqual([MockWorkspaceAgentDevcontainer]);
182+
});
183+
184+
// Now simulate error event
177185
const errorHandler = mockSocket.addEventListener.mock.calls.find(
178186
(call) => call[0] === "error",
179187
)?.[1];
180188

181189
if (errorHandler) {
182-
errorHandler(new Error("WebSocket error"));
190+
act(() => {
191+
errorHandler(new Error("WebSocket error"));
192+
});
183193
}
184194

185195
await waitFor(() => {
@@ -211,4 +221,36 @@ describe("useAgentContainers", () => {
211221

212222
watchAgentContainersSpy.mockRestore();
213223
});
224+
225+
it("does not establish WebSocket connection when dev container feature is not enabled", async () => {
226+
const watchAgentContainersSpy = jest.spyOn(API, "watchAgentContainers");
227+
228+
server.use(
229+
http.get(
230+
`/api/v2/workspaceagents/${MockWorkspaceAgent.id}/containers`,
231+
() => {
232+
return HttpResponse.json(
233+
{ message: "Dev Container feature not enabled." },
234+
{ status: 403 },
235+
);
236+
},
237+
),
238+
);
239+
240+
const { result } = renderHook(
241+
() => useAgentContainers(MockWorkspaceAgent),
242+
{
243+
wrapper: createWrapper(),
244+
},
245+
);
246+
247+
// Wait for the query to complete and error to be processed
248+
await waitFor(() => {
249+
expect(result.current).toBeUndefined();
250+
});
251+
252+
expect(watchAgentContainersSpy).not.toHaveBeenCalled();
253+
254+
watchAgentContainersSpy.mockRestore();
255+
});
214256
});

site/src/modules/resources/useAgentContainers.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ export function useAgentContainers(
1414
): readonly WorkspaceAgentDevcontainer[] | undefined {
1515
const queryClient = useQueryClient();
1616

17-
const { data: devcontainers } = useQuery({
17+
const {
18+
data: devcontainers,
19+
error: queryError,
20+
isLoading: queryIsLoading,
21+
} = useQuery({
1822
queryKey: ["agents", agent.id, "containers"],
1923
queryFn: () => API.getAgentContainers(agent.id),
2024
enabled: agent.status === "connected",
@@ -31,7 +35,7 @@ export function useAgentContainers(
3135
);
3236

3337
useEffect(() => {
34-
if (agent.status !== "connected") {
38+
if (agent.status !== "connected" || queryIsLoading || queryError) {
3539
return;
3640
}
3741

@@ -57,7 +61,13 @@ export function useAgentContainers(
5761
});
5862

5963
return () => socket.close();
60-
}, [agent.id, agent.status, updateDevcontainersCache]);
64+
}, [
65+
agent.id,
66+
agent.status,
67+
queryIsLoading,
68+
queryError,
69+
updateDevcontainersCache,
70+
]);
6171

6272
return devcontainers;
6373
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy