summaryrefslogtreecommitdiffhomepage
path: root/src/features/named-agents/logic/validate.test.ts
blob: d6473546d0cf66e170b6ba13424655487918a94c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import { describe, expect, it } from "vitest";
import { isUsableModel, isUsableName, nameError, normalizeName } from "./validate";

describe("normalizeName", () => {
  it("trims surrounding whitespace", () => {
    expect(normalizeName("  Coding  ")).toBe("Coding");
  });

  it("collapses internal runs of whitespace to one space", () => {
    expect(normalizeName("  Research   Agent  ")).toBe("Research Agent");
  });

  it("collapses an all-whitespace name to empty", () => {
    expect(normalizeName("   ")).toBe("");
  });
});

describe("nameError", () => {
  it("returns null for a nonempty unique name", () => {
    expect(nameError("Coding", ["Research", "Fast"])).toBeNull();
  });

  it("flags an empty/normalized-empty name", () => {
    expect(nameError("", ["Research"])).toBe("Name is required.");
    expect(nameError("   ", ["Research"])).toBe("Name is required.");
  });

  it("flags a name duplicate case-insensitively", () => {
    expect(nameError("coding", ["Coding"])).toBe("A named agent with this name already exists.");
    expect(nameError("FAST", ["Fast"])).toBe("A named agent with this name already exists.");
  });

  it("ignores whitespace when comparing uniqueness", () => {
    expect(nameError("  coding  ", ["Coding "])).toBe(
      "A named agent with this name already exists.",
    );
  });
});

describe("isUsableName", () => {
  it("is true only for a unique nonempty name", () => {
    expect(isUsableName("Coding", ["Research"])).toBe(true);
    expect(isUsableName("coding", ["Coding"])).toBe(false);
    expect(isUsableName("", [])).toBe(false);
  });
});

describe("isUsableModel", () => {
  it("accepts a canonical provider/model pair", () => {
    expect(isUsableModel("opencode-1/claude-sonnet-4.5")).toBe(true);
  });

  it("rejects a slashless / provider-only value", () => {
    expect(isUsableModel("opencode-1")).toBe(false);
    expect(isUsableModel("/claude")).toBe(false);
    expect(isUsableModel("")).toBe(false);
  });
});