Files
windmill/cli/test/settings_unit.test.ts
2026-03-09 21:39:03 +00:00

214 lines
6.7 KiB
TypeScript

/**
* Unit tests for settings.ts pure functions.
* Tests migrateToGroupedFormat which converts legacy flat settings to grouped format.
*/
import { expect, test, describe } from "bun:test";
import { migrateToGroupedFormat } from "../src/core/settings.ts";
// =============================================================================
// migrateToGroupedFormat
// =============================================================================
describe("migrateToGroupedFormat", () => {
test("migrates legacy auto_invite fields to grouped format", () => {
const legacy = {
name: "my-workspace",
auto_invite_enabled: true,
auto_invite_as: "operator",
auto_invite_mode: "add",
};
const result = migrateToGroupedFormat(legacy);
expect(result.auto_invite).toEqual({
enabled: true,
operator: true,
mode: "add",
});
});
test("migrates legacy auto_invite with non-operator role", () => {
const legacy = {
name: "ws",
auto_invite_enabled: true,
auto_invite_as: "developer",
auto_invite_mode: "invite",
};
const result = migrateToGroupedFormat(legacy);
expect(result.auto_invite).toEqual({
enabled: true,
operator: false,
mode: "invite",
});
});
test("migrates legacy auto_invite when disabled", () => {
const legacy = {
name: "ws",
auto_invite_enabled: false,
auto_invite_as: "operator",
};
const result = migrateToGroupedFormat(legacy);
expect(result.auto_invite!.enabled).toBe(false);
});
test("preserves already-grouped auto_invite", () => {
const grouped = {
name: "ws",
auto_invite: { enabled: true, operator: false, mode: "invite" as const },
};
const result = migrateToGroupedFormat(grouped);
expect(result.auto_invite).toEqual({
enabled: true,
operator: false,
mode: "invite",
});
});
test("migrates legacy error_handler string to grouped format", () => {
const legacy = {
name: "ws",
error_handler: "u/admin/error_handler",
error_handler_extra_args: { notify: true },
error_handler_muted_on_cancel: true,
};
const result = migrateToGroupedFormat(legacy);
expect(result.error_handler).toEqual({
path: "u/admin/error_handler",
extra_args: { notify: true },
muted_on_cancel: true,
});
});
test("preserves already-grouped error_handler", () => {
const grouped = {
name: "ws",
error_handler: {
path: "u/admin/handler",
extra_args: {},
muted_on_cancel: false,
},
};
const result = migrateToGroupedFormat(grouped);
expect(result.error_handler).toEqual({
path: "u/admin/handler",
extra_args: {},
muted_on_cancel: false,
});
});
test("migrates legacy success_handler string to grouped format", () => {
const legacy = {
name: "ws",
success_handler: "u/admin/on_success",
success_handler_extra_args: { channel: "#deploys" },
};
const result = migrateToGroupedFormat(legacy);
expect(result.success_handler).toEqual({
path: "u/admin/on_success",
extra_args: { channel: "#deploys" },
});
});
test("preserves already-grouped success_handler", () => {
const grouped = {
name: "ws",
success_handler: { path: "u/admin/handler", extra_args: {} },
};
const result = migrateToGroupedFormat(grouped);
expect(result.success_handler).toEqual({
path: "u/admin/handler",
extra_args: {},
});
});
test("copies non-legacy fields through", () => {
const settings = {
name: "my-workspace",
webhook: "https://example.com/hook",
deploy_to: "staging",
default_app: "u/admin/dashboard",
mute_critical_alerts: true,
color: "#ff0000",
};
const result = migrateToGroupedFormat(settings);
expect(result.name).toBe("my-workspace");
expect(result.webhook).toBe("https://example.com/hook");
expect(result.deploy_to).toBe("staging");
expect(result.default_app).toBe("u/admin/dashboard");
expect(result.mute_critical_alerts).toBe(true);
expect(result.color).toBe("#ff0000");
});
test("handles minimal settings with only name", () => {
const result = migrateToGroupedFormat({ name: "ws" });
expect(result.name).toBe("ws");
expect(result.auto_invite).toBeUndefined();
expect(result.error_handler).toBeUndefined();
expect(result.success_handler).toBeUndefined();
});
test("defaults name to empty string when missing", () => {
const result = migrateToGroupedFormat({});
expect(result.name).toBe("");
});
test("defaults auto_invite_mode to invite when missing", () => {
const legacy = {
name: "ws",
auto_invite_enabled: true,
auto_invite_as: "operator",
};
const result = migrateToGroupedFormat(legacy);
expect(result.auto_invite!.mode).toBe("invite");
});
test("defaults error_handler_muted_on_cancel to false when missing", () => {
const legacy = {
name: "ws",
error_handler: "u/admin/handler",
};
const result = migrateToGroupedFormat(legacy);
expect(result.error_handler!.muted_on_cancel).toBe(false);
});
test("preserves ai_config, large_file_storage, git_sync, default_scripts, operator_settings", () => {
const settings = {
name: "ws",
ai_config: { provider: "openai" },
large_file_storage: { type: "s3" },
git_sync: { enabled: true },
default_scripts: { python: "template.py" },
operator_settings: { hideCode: true },
};
const result = migrateToGroupedFormat(settings);
expect(result.ai_config).toEqual({ provider: "openai" });
expect(result.large_file_storage).toEqual({ type: "s3" });
expect(result.git_sync).toEqual({ enabled: true });
expect(result.default_scripts).toEqual({ python: "template.py" });
expect(result.operator_settings).toEqual({ hideCode: true });
});
test("does not include undefined fields in result", () => {
const result = migrateToGroupedFormat({ name: "ws" });
expect("webhook" in result).toBe(false);
expect("deploy_to" in result).toBe(false);
expect("color" in result).toBe(false);
expect("slack_team_id" in result).toBe(false);
expect("slack_name" in result).toBe(false);
expect("slack_command_script" in result).toBe(false);
});
test("copies slack fields through", () => {
const settings = {
name: "ws",
slack_team_id: "T12345",
slack_name: "my-team",
slack_command_script: "u/admin/slack_handler",
};
const result = migrateToGroupedFormat(settings);
expect(result.slack_team_id).toBe("T12345");
expect(result.slack_name).toBe("my-team");
expect(result.slack_command_script).toBe("u/admin/slack_handler");
});
});