Skip to content

Commit b271187

Browse files
committed
Revert "🤖 debug: remove hook test to check CI"
This reverts commit cfab8bb. Signed-off-by: Thomas Kosiewski <tk@coder.com>
1 parent 128967b commit b271187

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { GlobalWindow } from "happy-dom";
2+
3+
const win = new GlobalWindow();
4+
// @ts-expect-error -- Patching global for test environment
5+
global.window = win;
6+
// @ts-expect-error -- Patching global for test environment
7+
global.document = win.document;
8+
// @ts-expect-error -- Patching global for test environment
9+
global.navigator = win.navigator;
10+
11+
import { describe, it, expect, beforeEach, afterEach, mock, type Mock } from "bun:test";
12+
import { renderHook, waitFor } from "@testing-library/react";
13+
import { useAvailableScripts } from "./useAvailableScripts";
14+
15+
// Define types for our mock
16+
type ListScriptsMock = Mock<() => Promise<{ success: boolean; data?: unknown[]; error?: string }>>;
17+
18+
describe("useAvailableScripts", () => {
19+
const mockListScripts = mock() as unknown as ListScriptsMock;
20+
21+
beforeEach(() => {
22+
// Mock window.api attached to the global window
23+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
24+
(global.window as any).api = {
25+
workspace: {
26+
listScripts: mockListScripts,
27+
},
28+
};
29+
});
30+
31+
afterEach(() => {
32+
mock.restore();
33+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
34+
delete (global.window as any).api;
35+
});
36+
37+
it("should fetch and return executable scripts", async () => {
38+
mockListScripts.mockResolvedValue({
39+
success: true,
40+
data: [
41+
{ name: "script1", isExecutable: true, description: "desc1" },
42+
{ name: "script2", isExecutable: false, description: "desc2" },
43+
],
44+
});
45+
46+
const { result } = renderHook(() => useAvailableScripts("ws-1"));
47+
48+
// Initial state
49+
expect(result.current).toEqual([]);
50+
51+
await waitFor(() => {
52+
expect(result.current).toHaveLength(1);
53+
});
54+
55+
expect(result.current).toEqual([{ name: "script1", description: "desc1" }]);
56+
});
57+
58+
it("should clear scripts immediately when workspaceId changes", async () => {
59+
// First load
60+
mockListScripts.mockResolvedValue({
61+
success: true,
62+
data: [{ name: "script1", isExecutable: true }],
63+
});
64+
65+
const { result, rerender } = renderHook(({ wsId }) => useAvailableScripts(wsId), {
66+
initialProps: { wsId: "ws-1" as string | null },
67+
});
68+
69+
await waitFor(() => {
70+
expect(result.current).toHaveLength(1);
71+
});
72+
73+
// Prepare for second load (hangs to prove clearance)
74+
mockListScripts.mockReturnValue(
75+
new Promise(() => {
76+
// Never resolve
77+
})
78+
);
79+
80+
rerender({ wsId: "ws-2" });
81+
82+
// Should be cleared immediately
83+
expect(result.current).toEqual([]);
84+
});
85+
86+
it("should clear scripts if listing fails", async () => {
87+
mockListScripts.mockResolvedValue({
88+
success: false,
89+
error: "Failed",
90+
});
91+
92+
const { result } = renderHook(() => useAvailableScripts("ws-1"));
93+
94+
await waitFor(() => {
95+
expect(mockListScripts).toHaveBeenCalled();
96+
});
97+
98+
expect(result.current).toEqual([]);
99+
});
100+
});

0 commit comments

Comments
 (0)