1import { describe, expect, it } from "vite-plus/test";
2import { ProviderDriverKind } from "@t3tools/contracts";
3
4import { providerClients } from "./providerDriverMeta";
5import {
6 deriveProviderSettingsFields,
7 nextProviderConfigWithFieldValue,
8} from "./ProviderSettingsForm";
9
10describe("ProviderSettingsForm helpers", () => {
11 it("keeps managed account homes out of the editable runtime fields", () => {
12 const codex = providerClients.get(ProviderDriverKind.make("codex"))!;
13 expect(
14 deriveProviderSettingsFields(codex, { sharedAccountId: "managed-account" }).map(
15 (field) => field.key,
16 ),
17 ).toEqual(["binaryPath", "launchArgs"]);
18 });
19 it("derives visible provider config fields from the client definition schema", () => {
20 const codex = providerClients.get(ProviderDriverKind.make("codex"));
21
22 expect(codex).toBeDefined();
23 expect(deriveProviderSettingsFields(codex!).map((field) => field.key)).toEqual([
24 "binaryPath",
25 "homePath",
26 "shadowHomePath",
27 "launchArgs",
28 ]);
29 });
30
31 it("sources labels and descriptions from schema annotations", () => {
32 const opencode = providerClients.get(ProviderDriverKind.make("opencode"));
33 expect(opencode).toBeDefined();
34
35 const serverPassword = deriveProviderSettingsFields(opencode!).find(
36 (field) => field.key === "serverPassword",
37 );
38
39 expect(serverPassword).toMatchObject({
40 label: "Server password",
41 description: "Stored in plain text on disk.",
42 control: "password",
43 });
44 });
45
46 it("uses a dedicated environment field instead of legacy Cursor CLI settings", () => {
47 const cursor = providerClients.get(ProviderDriverKind.make("cursor"));
48
49 expect(cursor).toBeDefined();
50 expect(deriveProviderSettingsFields(cursor!)).toEqual([]);
51 expect(cursor?.environmentFields).toEqual([
52 {
53 name: "CURSOR_API_KEY",
54 label: "Cursor API key",
55 description: "Optional. Overrides browser sign-in for this provider.",
56 placeholder: "Paste API key",
57 sensitive: true,
58 },
59 ]);
60 });
61
62 it("exposes ACP Registry as an instance-only configurable driver", () => {
63 const acpRegistry = providerClients.get(ProviderDriverKind.make("acpRegistry"));
64
65 expect(acpRegistry).toBeDefined();
66 expect(acpRegistry?.hasDefaultInstance).toBe(false);
67 expect(deriveProviderSettingsFields(acpRegistry!).map((field) => field.key)).toEqual([
68 "source",
69 "agentId",
70 "commandPath",
71 "authMethodId",
72 ]);
73 });
74
75 it("shows the local executable without registry identity or authentication fields", () => {
76 const acpRegistry = providerClients.get(ProviderDriverKind.make("acpRegistry"));
77 expect(
78 deriveProviderSettingsFields(acpRegistry!, { source: "local" }).map((field) => field.key),
79 ).toEqual(["source", "commandPath"]);
80 });
81
82 it("derives a select control with its choices for the Antigravity sign-in method", () => {
83 const antigravity = providerClients.get(ProviderDriverKind.make("antigravity"));
84 expect(antigravity).toBeDefined();
85
86 const fields = deriveProviderSettingsFields(antigravity!);
87 expect(fields.map((field) => field.key)).toEqual([
88 "authMethod",
89 "apiKey",
90 "gcpProject",
91 "gcpLocation",
92 "binaryPath",
93 ]);
94 const authMethod = fields.find((field) => field.key === "authMethod");
95 expect(authMethod).toMatchObject({ control: "select", clearWhenEmpty: "omit" });
96 expect(authMethod?.options?.map((option) => option.value)).toEqual([
97 "oauth-personal",
98 "oauth-business",
99 "gemini-api-key",
100 "agent-platform",
101 ]);
102 expect(fields.find((field) => field.key === "apiKey")?.control).toBe("password");
103 });
104
105 it("shows the auto-compaction threshold for Claude providers", () => {
106 const claude = providerClients.get(ProviderDriverKind.make("claudeAgent"));
107 expect(claude).toBeDefined();
108
109 expect(deriveProviderSettingsFields(claude!).map((field) => field.key)).toEqual([
110 "binaryPath",
111 "homePath",
112 "autoCompactWindow",
113 "launchArgs",
114 ]);
115 });
116
117 it("preserves unknown config keys while omitting empty configurable fields", () => {
118 const opencode = providerClients.get(ProviderDriverKind.make("opencode"));
119 expect(opencode).toBeDefined();
120
121 const serverUrl = deriveProviderSettingsFields(opencode!).find(
122 (field) => field.key === "serverUrl",
123 );
124 expect(serverUrl).toBeDefined();
125
126 const next = nextProviderConfigWithFieldValue(
127 { forkOwned: 1, serverUrl: "http://127.0.0.1:4096" },
128 serverUrl!,
129 "",
130 );
131
132 expect(next).toEqual({ forkOwned: 1 });
133 });
134
135 it("omits false boolean fields when clearWhenEmpty is omit", () => {
136 const next = nextProviderConfigWithFieldValue(
137 { forkOwned: 1, experimental: true },
138 {
139 key: "experimental",
140 control: "switch",
141 label: "Experimental",
142 clearWhenEmpty: "omit",
143 defaultBooleanValue: false,
144 },
145 false,
146 );
147
148 expect(next).toEqual({ forkOwned: 1 });
149 });
150
151 it("omits true boolean fields when true is the default", () => {
152 const next = nextProviderConfigWithFieldValue(
153 { forkOwned: 1, experimental: false },
154 {
155 key: "experimental",
156 control: "switch",
157 label: "Experimental",
158 clearWhenEmpty: "omit",
159 defaultBooleanValue: true,
160 },
161 true,
162 );
163
164 expect(next).toEqual({ forkOwned: 1 });
165 });
166
167 it("stores false boolean fields when true is the default", () => {
168 const next = nextProviderConfigWithFieldValue(
169 undefined,
170 {
171 key: "experimental",
172 control: "switch",
173 label: "Experimental",
174 clearWhenEmpty: "omit",
175 defaultBooleanValue: true,
176 },
177 false,
178 );
179
180 expect(next).toEqual({ experimental: false });
181 });
182
183 it("preserves false boolean fields when clearWhenEmpty is persist", () => {
184 const next = nextProviderConfigWithFieldValue(
185 undefined,
186 {
187 key: "experimental",
188 control: "switch",
189 label: "Experimental",
190 clearWhenEmpty: "persist",
191 },
192 false,
193 );
194
195 expect(next).toEqual({ experimental: false });
196 });
197});