mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-14 12:16:54 +00:00
Vault: handle empty delete responses (#913)
Co-authored-by: Viet Tran <viettranx@gmail.com>
This commit is contained in:
1 parent
ce620c87ef
commit
770af6b1c0
2 files changed
+63
-2
No files matched your search
@@ -0,0 +1,48 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { HttpClient } from "./http-client";
|
||||
|
||||
function createClient() {
|
||||
return new HttpClient("https://example.com", () => "", () => "");
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
describe("HttpClient", () => {
|
||||
it("returns undefined for 204 no-content responses", async () => {
|
||||
const fetchMock = vi.fn().mockResolvedValue(new Response(null, { status: 204, statusText: "No Content" }));
|
||||
vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch);
|
||||
|
||||
const client = createClient();
|
||||
const result = await client.delete<void>("/v1/vault/documents/123");
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
"https://example.com/v1/vault/documents/123",
|
||||
expect.objectContaining({
|
||||
method: "DELETE",
|
||||
headers: expect.objectContaining({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("parses JSON responses from successful requests", async () => {
|
||||
const payload = { deleted: true };
|
||||
const fetchMock = vi.fn().mockResolvedValue(
|
||||
new Response(JSON.stringify(payload), {
|
||||
status: 200,
|
||||
headers: { "content-type": "application/json" },
|
||||
}),
|
||||
);
|
||||
vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch);
|
||||
|
||||
const client = createClient();
|
||||
const result = await client.post<{ deleted: boolean }>("/v1/test", { id: "123" });
|
||||
|
||||
expect(result).toEqual(payload);
|
||||
});
|
||||
});
|
||||
@@ -90,7 +90,7 @@ export class HttpClient {
|
||||
throw new ApiError(code, message);
|
||||
}
|
||||
|
||||
return res.json() as Promise<T>;
|
||||
return this.readJson<T>(res);
|
||||
}
|
||||
|
||||
private buildUrl(path: string, params?: Record<string, string>): string {
|
||||
@@ -150,6 +150,19 @@ export class HttpClient {
|
||||
throw new ApiError(code, message);
|
||||
}
|
||||
|
||||
return res.json() as Promise<T>;
|
||||
return this.readJson<T>(res);
|
||||
}
|
||||
|
||||
private async readJson<T>(res: Response): Promise<T> {
|
||||
if (res.status === 204 || res.headers.get("content-length") === "0") {
|
||||
return undefined as T;
|
||||
}
|
||||
|
||||
const text = await res.text();
|
||||
if (text.trim().length === 0) {
|
||||
return undefined as T;
|
||||
}
|
||||
|
||||
return JSON.parse(text) as T;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user