Skip to content

Commit a4d74e5

Browse files
committed
test(storage): more thorough testing
1 parent 52cb477 commit a4d74e5

File tree

1 file changed

+90
-1
lines changed

1 file changed

+90
-1
lines changed

src/utils/__tests__/storage.spec.ts

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ describe("getStorageBasePath - customStoragePath", () => {
2929

3030
expect(result).toBe(customPath)
3131
expect((fsPromises as any).mkdir).toHaveBeenCalledWith(customPath, { recursive: true })
32-
expect((fsPromises as any).access).toHaveBeenCalledWith(customPath, expect.any(Number))
32+
expect((fsPromises as any).access).toHaveBeenCalledWith(customPath, 7) // 7 = R_OK(4) | W_OK(2) | X_OK(1)
3333
})
3434

3535
it("falls back to default and shows an error when custom path is not writable", async () => {
@@ -63,4 +63,93 @@ describe("getStorageBasePath - customStoragePath", () => {
6363
const firstArg = showErrorSpy.mock.calls[0][0]
6464
expect(typeof firstArg).toBe("string")
6565
})
66+
it("returns the default path when customStoragePath is an empty string and does not touch fs", async () => {
67+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue({
68+
get: vi.fn().mockReturnValue(""),
69+
} as any)
70+
71+
const fsPromises = await import("fs/promises")
72+
const { getStorageBasePath } = await import("../storage")
73+
74+
const result = await getStorageBasePath(defaultPath)
75+
76+
expect(result).toBe(defaultPath)
77+
expect((fsPromises as any).mkdir).not.toHaveBeenCalled()
78+
expect((fsPromises as any).access).not.toHaveBeenCalled()
79+
})
80+
81+
it("falls back to default when mkdir fails and does not attempt access", async () => {
82+
const customPath = "/test/storage/failmkdir"
83+
84+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue({
85+
get: vi.fn().mockReturnValue(customPath),
86+
} as any)
87+
88+
const showErrorSpy = vi.spyOn(vscode.window, "showErrorMessage").mockResolvedValue(undefined as any)
89+
90+
const fsPromises = await import("fs/promises")
91+
const { getStorageBasePath } = await import("../storage")
92+
93+
const mkdirMock = (fsPromises as any).mkdir as ReturnType<typeof vi.fn>
94+
mkdirMock.mockImplementationOnce(async (p: string) => {
95+
if (p === customPath) {
96+
const err: any = new Error("EACCES: permission denied")
97+
err.code = "EACCES"
98+
throw err
99+
}
100+
return Promise.resolve()
101+
})
102+
103+
const result = await getStorageBasePath(defaultPath)
104+
105+
expect(result).toBe(defaultPath)
106+
expect((fsPromises as any).access).not.toHaveBeenCalled()
107+
expect(showErrorSpy).toHaveBeenCalledTimes(1)
108+
})
109+
110+
it("passes the correct permission flags (R_OK | W_OK | X_OK) to fs.access", async () => {
111+
const customPath = "/test/storage/path"
112+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue({
113+
get: vi.fn().mockReturnValue(customPath),
114+
} as any)
115+
116+
const fsPromises = await import("fs/promises")
117+
const { getStorageBasePath } = await import("../storage")
118+
119+
await getStorageBasePath(defaultPath)
120+
121+
const constants = (fsPromises as any).constants
122+
const expectedFlags = constants.R_OK | constants.W_OK | constants.X_OK
123+
124+
expect((fsPromises as any).access).toHaveBeenCalledWith(customPath, expectedFlags)
125+
})
126+
127+
it("falls back when directory is readable but not writable (partial permissions)", async () => {
128+
const customPath = "/test/storage/readonly"
129+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue({
130+
get: vi.fn().mockReturnValue(customPath),
131+
} as any)
132+
133+
const showErrorSpy = vi.spyOn(vscode.window, "showErrorMessage").mockResolvedValue(undefined as any)
134+
135+
const fsPromises = await import("fs/promises")
136+
const { getStorageBasePath } = await import("../storage")
137+
138+
const accessMock = (fsPromises as any).access as ReturnType<typeof vi.fn>
139+
const constants = (fsPromises as any).constants
140+
accessMock.mockImplementationOnce(async (p: string, mode?: number) => {
141+
// Simulate readable (R_OK) but not writable/executable (W_OK | X_OK)
142+
if (p === customPath && mode && mode & (constants.W_OK | constants.X_OK)) {
143+
const err: any = new Error("EACCES: permission denied")
144+
err.code = "EACCES"
145+
throw err
146+
}
147+
return Promise.resolve()
148+
})
149+
150+
const result = await getStorageBasePath(defaultPath)
151+
152+
expect(result).toBe(defaultPath)
153+
expect(showErrorSpy).toHaveBeenCalledTimes(1)
154+
})
66155
})

0 commit comments

Comments
 (0)