|
|
@@ -2,7 +2,7 @@ import { describe, expect, it, vi } from "vitest";
|
|
|
import {
|
|
|
matchServiceConfigEntryForDetail,
|
|
|
rehydrateServiceConnectionStatus,
|
|
|
- saveServiceConfigWithValidation,
|
|
|
+ saveServiceConfig,
|
|
|
} from "./service-detail-state";
|
|
|
|
|
|
describe("rehydrateServiceConnectionStatus", () => {
|
|
|
@@ -52,25 +52,19 @@ describe("matchServiceConfigEntryForDetail", () => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
-describe("saveServiceConfigWithValidation", () => {
|
|
|
- it("validates the key before persisting secrets/config", async () => {
|
|
|
+describe("saveServiceConfig", () => {
|
|
|
+ it("persists secrets/config without probing the upstream service", async () => {
|
|
|
const calls: string[] = [];
|
|
|
- const fetchJsonImpl = vi.fn(async (path: string) => {
|
|
|
+ const bodies: unknown[] = [];
|
|
|
+ const fetchJsonImpl = vi.fn(async (path: string, init?: { body?: string }) => {
|
|
|
calls.push(path);
|
|
|
- if (path === "/services/openai/test") {
|
|
|
- return {
|
|
|
- ok: true,
|
|
|
- models: [{ id: "gpt-5.4", name: "gpt-5.4" }],
|
|
|
- selectedModel: "gpt-5.4",
|
|
|
- detected: { apiFormat: "responses", stream: false },
|
|
|
- };
|
|
|
- }
|
|
|
+ if (init?.body) bodies.push(JSON.parse(init.body));
|
|
|
if (path === "/services/openai/secret") return { ok: true };
|
|
|
if (path === "/services/config") return { ok: true };
|
|
|
throw new Error(`unexpected path: ${path}`);
|
|
|
});
|
|
|
|
|
|
- const result = await saveServiceConfigWithValidation({
|
|
|
+ const result = await saveServiceConfig({
|
|
|
effectiveServiceId: "openai",
|
|
|
serviceId: "openai",
|
|
|
isCustom: false,
|
|
|
@@ -85,31 +79,35 @@ describe("saveServiceConfigWithValidation", () => {
|
|
|
});
|
|
|
|
|
|
expect(calls).toEqual([
|
|
|
- "/services/openai/test",
|
|
|
"/services/openai/secret",
|
|
|
"/services/config",
|
|
|
]);
|
|
|
- expect(result).toMatchObject({
|
|
|
- detectedModel: "gpt-5.4",
|
|
|
- detectedConfig: { apiFormat: "responses", stream: false },
|
|
|
- status: {
|
|
|
- state: "connected",
|
|
|
- models: [{ id: "gpt-5.4", name: "gpt-5.4" }],
|
|
|
+ expect(bodies).toEqual([
|
|
|
+ { apiKey: "sk-live" },
|
|
|
+ {
|
|
|
+ service: "openai",
|
|
|
+ services: [
|
|
|
+ { service: "openai", temperature: 0.7, apiFormat: "chat", stream: true },
|
|
|
+ ],
|
|
|
},
|
|
|
+ ]);
|
|
|
+ expect(result).toEqual({
|
|
|
+ detectedModel: "",
|
|
|
+ detectedConfig: null,
|
|
|
+ status: { state: "saved" },
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- it("does not persist secrets/config when validation fails", async () => {
|
|
|
+ it("still persists secrets/config when the key has not been manually tested", async () => {
|
|
|
const calls: string[] = [];
|
|
|
const fetchJsonImpl = vi.fn(async (path: string) => {
|
|
|
calls.push(path);
|
|
|
- if (path === "/services/openai/test") {
|
|
|
- throw new Error("401 Unauthorized");
|
|
|
- }
|
|
|
+ if (path === "/services/openai/secret") return { ok: true };
|
|
|
+ if (path === "/services/config") return { ok: true };
|
|
|
throw new Error(`unexpected path: ${path}`);
|
|
|
});
|
|
|
|
|
|
- await expect(saveServiceConfigWithValidation({
|
|
|
+ await expect(saveServiceConfig({
|
|
|
effectiveServiceId: "openai",
|
|
|
serviceId: "openai",
|
|
|
isCustom: false,
|
|
|
@@ -121,8 +119,11 @@ describe("saveServiceConfigWithValidation", () => {
|
|
|
temperature: "0.7",
|
|
|
detectedModel: "",
|
|
|
fetchJsonImpl: fetchJsonImpl as never,
|
|
|
- })).rejects.toThrow("401 Unauthorized");
|
|
|
+ })).resolves.toMatchObject({ status: { state: "saved" } });
|
|
|
|
|
|
- expect(calls).toEqual(["/services/openai/test"]);
|
|
|
+ expect(calls).toEqual([
|
|
|
+ "/services/openai/secret",
|
|
|
+ "/services/config",
|
|
|
+ ]);
|
|
|
});
|
|
|
});
|