story-kit: merge 110_story_add_test_coverage_for_api_settings_ts
This commit is contained in:
134
frontend/src/api/settings.test.ts
Normal file
134
frontend/src/api/settings.test.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { settingsApi } from "./settings";
|
||||
|
||||
const mockFetch = vi.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
vi.stubGlobal("fetch", mockFetch);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
function okResponse(body: unknown) {
|
||||
return new Response(JSON.stringify(body), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
|
||||
function errorResponse(status: number, text: string) {
|
||||
return new Response(text, { status });
|
||||
}
|
||||
|
||||
describe("settingsApi", () => {
|
||||
describe("getEditorCommand", () => {
|
||||
it("sends GET to /settings/editor and returns editor settings", async () => {
|
||||
const expected = { editor_command: "zed" };
|
||||
mockFetch.mockResolvedValueOnce(okResponse(expected));
|
||||
|
||||
const result = await settingsApi.getEditorCommand();
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
"/api/settings/editor",
|
||||
expect.objectContaining({
|
||||
headers: expect.objectContaining({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it("returns null editor_command when not configured", async () => {
|
||||
const expected = { editor_command: null };
|
||||
mockFetch.mockResolvedValueOnce(okResponse(expected));
|
||||
|
||||
const result = await settingsApi.getEditorCommand();
|
||||
expect(result.editor_command).toBeNull();
|
||||
});
|
||||
|
||||
it("uses custom baseUrl when provided", async () => {
|
||||
mockFetch.mockResolvedValueOnce(okResponse({ editor_command: "code" }));
|
||||
|
||||
await settingsApi.getEditorCommand("http://localhost:4000/api");
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
"http://localhost:4000/api/settings/editor",
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("setEditorCommand", () => {
|
||||
it("sends PUT to /settings/editor with command body", async () => {
|
||||
const expected = { editor_command: "zed" };
|
||||
mockFetch.mockResolvedValueOnce(okResponse(expected));
|
||||
|
||||
const result = await settingsApi.setEditorCommand("zed");
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
"/api/settings/editor",
|
||||
expect.objectContaining({
|
||||
method: "PUT",
|
||||
body: JSON.stringify({ editor_command: "zed" }),
|
||||
}),
|
||||
);
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it("sends PUT with null to clear the editor command", async () => {
|
||||
const expected = { editor_command: null };
|
||||
mockFetch.mockResolvedValueOnce(okResponse(expected));
|
||||
|
||||
const result = await settingsApi.setEditorCommand(null);
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
"/api/settings/editor",
|
||||
expect.objectContaining({
|
||||
method: "PUT",
|
||||
body: JSON.stringify({ editor_command: null }),
|
||||
}),
|
||||
);
|
||||
expect(result.editor_command).toBeNull();
|
||||
});
|
||||
|
||||
it("uses custom baseUrl when provided", async () => {
|
||||
mockFetch.mockResolvedValueOnce(okResponse({ editor_command: "vim" }));
|
||||
|
||||
await settingsApi.setEditorCommand("vim", "http://localhost:4000/api");
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
"http://localhost:4000/api/settings/editor",
|
||||
expect.objectContaining({ method: "PUT" }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("error handling", () => {
|
||||
it("throws with response body text on non-ok response", async () => {
|
||||
mockFetch.mockResolvedValueOnce(errorResponse(400, "Bad Request"));
|
||||
|
||||
await expect(settingsApi.getEditorCommand()).rejects.toThrow(
|
||||
"Bad Request",
|
||||
);
|
||||
});
|
||||
|
||||
it("throws with status code message when response body is empty", async () => {
|
||||
mockFetch.mockResolvedValueOnce(errorResponse(500, ""));
|
||||
|
||||
await expect(settingsApi.getEditorCommand()).rejects.toThrow(
|
||||
"Request failed (500)",
|
||||
);
|
||||
});
|
||||
|
||||
it("throws on setEditorCommand error", async () => {
|
||||
mockFetch.mockResolvedValueOnce(errorResponse(403, "Forbidden"));
|
||||
|
||||
await expect(settingsApi.setEditorCommand("code")).rejects.toThrow(
|
||||
"Forbidden",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user