1
11import { describe, expect, it } from "vitest";
12import { optionIdForName } from "@factory/ai";
13import { normalizeSelectOptions } from "../database.service.js";
14
15describe("normalizeSelectOptions (select option-id backfill)", () => {
16 it("assigns a deterministic id to options that lack one", () => {
17 const out = normalizeSelectOptions({
18 options: [
19 { name: "To Do", color: "default" },
20 { name: "In Progress", color: "blue" },
21 { name: "Done", color: "green" }
22 ]
23 }) as { options: { id: string; name: string }[] };
24 expect(out.options.map((o) => o.id)).toEqual([
25 optionIdForName("To Do"),
26 optionIdForName("In Progress"),
27 optionIdForName("Done")
28 ]);
29
30 expect(out.options[0]).toEqual({ name: "To Do", color: "default", id: optionIdForName("To Do") });
31 });
32
33 it("leaves already-id'd options untouched (idempotent)", () => {
34 const id = optionIdForName("To Do");
35 const cfg = { options: [{ id, name: "To Do", color: "default" }] };
36 const out = normalizeSelectOptions(cfg) as { options: { id: string }[] };
37 expect(out.options[0].id).toBe(id);
38
39 expect(normalizeSelectOptions(cfg)).toBe(cfg);
40 });
41
42 it("keeps the ids of PRESENT options on a partial update patch (existing values stay resolvable)", () => {
43
44
45
46
47 const existing = [
48 { id: optionIdForName("To Do"), name: "To Do" },
49 { id: "opt-custom-blocked", name: "Blocked" }
50 ];
51 const out = normalizeSelectOptions(
52 { options: [{ name: "To Do" }, { name: "Blocked" }, { name: "Done" }] },
53 existing
54 ) as { options: { id: string; name: string }[] };
55 expect(out.options[0].id).toBe(optionIdForName("To Do"));
56 expect(out.options[1].id).toBe("opt-custom-blocked");
57 expect(out.options[2].id).toBe(optionIdForName("Done"));
58 });
59
60 it("passes through non-select configs (no options array) unchanged", () => {
61 const cfg = { format: "currency", currency: "USD" };
62 expect(normalizeSelectOptions(cfg)).toBe(cfg);
63 expect(normalizeSelectOptions(null)).toBe(null);
64 expect(normalizeSelectOptions(undefined)).toBe(undefined);
65 expect(normalizeSelectOptions({})).toEqual({});
66 });
67
68 it("does not mutate the input", () => {
69 const cfg = { options: [{ name: "To Do", color: "default" }] };
70 const before = JSON.stringify(cfg);
71 normalizeSelectOptions(cfg);
72 expect(JSON.stringify(cfg)).toBe(before);
73 });
74});
75