diff --git a/src/shared/validation/settingsSchemas.ts b/src/shared/validation/settingsSchemas.ts index e278ab8173c8..ae8b78cb4ece 100644 --- a/src/shared/validation/settingsSchemas.ts +++ b/src/shared/validation/settingsSchemas.ts @@ -36,6 +36,11 @@ export const updateSettingsSchema = z.object({ hideEndpointNgrokTunnel: z.boolean().optional(), autoRefreshProviderQuota: z.boolean().optional(), autoRefreshProviderQuotaInterval: z.number().int().min(10).max(3600).optional(), + pinProviderQuotaToHome: z.boolean().optional(), + showQuickStartOnHome: z.boolean().optional(), + showProviderTopologyOnHome: z.boolean().optional(), + localOnlyManageScopeBypassEnabled: z.boolean().optional(), + localOnlyManageScopeBypassPrefixes: z.array(z.string().max(200)).optional(), debugMode: z.boolean().optional(), hiddenSidebarItems: z.array(z.enum(HIDEABLE_SIDEBAR_ITEM_IDS)).optional(), sidebarSectionOrder: z diff --git a/tests/unit/home-page-pin-settings-schema.test.ts b/tests/unit/home-page-pin-settings-schema.test.ts new file mode 100644 index 000000000000..ed7c2b2fa4e5 --- /dev/null +++ b/tests/unit/home-page-pin-settings-schema.test.ts @@ -0,0 +1,67 @@ +import test from "node:test"; +import assert from "node:assert/strict"; + +import { updateSettingsSchema } from "../../src/shared/validation/settingsSchemas.ts"; + +test("home page pin settings are accepted by the settings PATCH schema", () => { + const validation = updateSettingsSchema.safeParse({ + pinProviderQuotaToHome: true, + showQuickStartOnHome: false, + showProviderTopologyOnHome: true, + }); + + assert.equal(validation.success, true); + if (!validation.success) return; + assert.equal(validation.data.pinProviderQuotaToHome, true); + assert.equal(validation.data.showQuickStartOnHome, false); + assert.equal(validation.data.showProviderTopologyOnHome, true); +}); + +test("home page pin settings default to undefined when not provided", () => { + const validation = updateSettingsSchema.safeParse({}); + + assert.equal(validation.success, true); + if (!validation.success) return; + assert.equal(validation.data.pinProviderQuotaToHome, undefined); + assert.equal(validation.data.showQuickStartOnHome, undefined); + assert.equal(validation.data.showProviderTopologyOnHome, undefined); +}); + +test("home page pin settings reject non-boolean values", () => { + const validation = updateSettingsSchema.safeParse({ + pinProviderQuotaToHome: "yes", + }); + + assert.equal(validation.success, false); +}); + +test("localOnlyManageScopeBypass settings are accepted by the settings PATCH schema", () => { + const validation = updateSettingsSchema.safeParse({ + localOnlyManageScopeBypassEnabled: true, + localOnlyManageScopeBypassPrefixes: ["/api/mcp/", "/api/cli-tools/runtime/"], + }); + + assert.equal(validation.success, true); + if (!validation.success) return; + assert.equal(validation.data.localOnlyManageScopeBypassEnabled, true); + assert.deepEqual(validation.data.localOnlyManageScopeBypassPrefixes, [ + "/api/mcp/", + "/api/cli-tools/runtime/", + ]); +}); + +test("localOnlyManageScopeBypassEnabled rejects non-boolean values", () => { + const validation = updateSettingsSchema.safeParse({ + localOnlyManageScopeBypassEnabled: "yes", + }); + + assert.equal(validation.success, false); +}); + +test("localOnlyManageScopeBypassPrefixes rejects non-array values", () => { + const validation = updateSettingsSchema.safeParse({ + localOnlyManageScopeBypassPrefixes: "/api/mcp/", + }); + + assert.equal(validation.success, false); +});