Skip to content

Commit e0a1e24

Browse files
committed
🤖 test: avoid global bun module mocks
Reworks useDraftWorkspaceSettings tests to use real providers (API/Mode/Thinking) instead of bun mock.module overrides, which leaked into other test files in CI.
1 parent 7303f0b commit e0a1e24

File tree

2 files changed

+124
-116
lines changed

2 files changed

+124
-116
lines changed

src/browser/hooks/useDraftWorkspaceSettings.test.ts

Lines changed: 0 additions & 116 deletions
This file was deleted.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
2+
import { act, cleanup, renderHook, waitFor } from "@testing-library/react";
3+
import { GlobalWindow } from "happy-dom";
4+
import React from "react";
5+
import { APIProvider, type APIClient } from "@/browser/contexts/API";
6+
import { ModeProvider } from "@/browser/contexts/ModeContext";
7+
import { ThinkingProvider } from "@/browser/contexts/ThinkingContext";
8+
import { updatePersistedState } from "@/browser/hooks/usePersistedState";
9+
import { getLastDockerImageKey, getLastSshHostKey } from "@/common/constants/storage";
10+
import { useDraftWorkspaceSettings } from "./useDraftWorkspaceSettings";
11+
12+
function createStubApiClient(): APIClient {
13+
// useModelLRU() only needs providers.getConfig + providers.onConfigChanged.
14+
// Provide a minimal stub so tests can run without spinning up a real oRPC client.
15+
async function* empty() {
16+
// no-op
17+
}
18+
19+
return {
20+
providers: {
21+
getConfig: () => Promise.resolve({}),
22+
onConfigChanged: () => Promise.resolve(empty()),
23+
},
24+
} as unknown as APIClient;
25+
}
26+
27+
describe("useDraftWorkspaceSettings", () => {
28+
beforeEach(() => {
29+
globalThis.window = new GlobalWindow() as unknown as Window & typeof globalThis;
30+
globalThis.document = globalThis.window.document;
31+
globalThis.localStorage = globalThis.window.localStorage;
32+
globalThis.localStorage.clear();
33+
});
34+
35+
afterEach(() => {
36+
cleanup();
37+
globalThis.window = undefined as unknown as Window & typeof globalThis;
38+
globalThis.document = undefined as unknown as Document;
39+
});
40+
41+
test("does not reset selected runtime to the default while editing SSH host", async () => {
42+
const projectPath = "/tmp/project";
43+
44+
const wrapper: React.FC<{ children: React.ReactNode }> = (props) => (
45+
<APIProvider client={createStubApiClient()}>
46+
<ModeProvider projectPath={projectPath}>
47+
<ThinkingProvider projectPath={projectPath}>{props.children}</ThinkingProvider>
48+
</ModeProvider>
49+
</APIProvider>
50+
);
51+
52+
const { result } = renderHook(() => useDraftWorkspaceSettings(projectPath, ["main"], "main"), {
53+
wrapper,
54+
});
55+
56+
act(() => {
57+
result.current.setSelectedRuntime({ mode: "ssh", host: "dev@host" });
58+
});
59+
60+
await waitFor(() => {
61+
expect(result.current.settings.selectedRuntime).toEqual({ mode: "ssh", host: "dev@host" });
62+
});
63+
});
64+
65+
test("seeds SSH host from the remembered value when switching modes", async () => {
66+
const projectPath = "/tmp/project";
67+
68+
updatePersistedState(getLastSshHostKey(projectPath), "remembered@host");
69+
70+
const wrapper: React.FC<{ children: React.ReactNode }> = (props) => (
71+
<APIProvider client={createStubApiClient()}>
72+
<ModeProvider projectPath={projectPath}>
73+
<ThinkingProvider projectPath={projectPath}>{props.children}</ThinkingProvider>
74+
</ModeProvider>
75+
</APIProvider>
76+
);
77+
78+
const { result } = renderHook(() => useDraftWorkspaceSettings(projectPath, ["main"], "main"), {
79+
wrapper,
80+
});
81+
82+
act(() => {
83+
// Simulate UI switching into ssh mode with an empty field.
84+
result.current.setSelectedRuntime({ mode: "ssh", host: "" });
85+
});
86+
87+
await waitFor(() => {
88+
expect(result.current.settings.selectedRuntime).toEqual({
89+
mode: "ssh",
90+
host: "remembered@host",
91+
});
92+
});
93+
});
94+
95+
test("seeds Docker image from the remembered value when switching modes", async () => {
96+
const projectPath = "/tmp/project";
97+
98+
updatePersistedState(getLastDockerImageKey(projectPath), "ubuntu:22.04");
99+
100+
const wrapper: React.FC<{ children: React.ReactNode }> = (props) => (
101+
<APIProvider client={createStubApiClient()}>
102+
<ModeProvider projectPath={projectPath}>
103+
<ThinkingProvider projectPath={projectPath}>{props.children}</ThinkingProvider>
104+
</ModeProvider>
105+
</APIProvider>
106+
);
107+
108+
const { result } = renderHook(() => useDraftWorkspaceSettings(projectPath, ["main"], "main"), {
109+
wrapper,
110+
});
111+
112+
act(() => {
113+
// Simulate UI switching into docker mode with an empty field.
114+
result.current.setSelectedRuntime({ mode: "docker", image: "" });
115+
});
116+
117+
await waitFor(() => {
118+
expect(result.current.settings.selectedRuntime).toEqual({
119+
mode: "docker",
120+
image: "ubuntu:22.04",
121+
});
122+
});
123+
});
124+
});

0 commit comments

Comments
 (0)