import { describe, expect, it, vi } from "vite-plus/test"; import { filterAvailableSettingsSearchItems, searchableSetting, searchSettings, SETTINGS_SEARCH_ITEMS, type SettingsSearchItem,} from "./settingsSearch"; const ITEMS: ReadonlyArray<SettingsSearchItem> = [ { id: "word-wrap", title: "Word wrap", to: "/settings/general", searchTerms: ["long lines in code previews"], }, { id: "network-access", title: "Network access", to: "/settings/connections", searchTerms: ["remote pairing backend"], }, { id: "providers", title: "Providers", to: "/settings/providers", searchTerms: ["claude codex agents"], }, { id: "provider-updates", title: "Update checks", to: "/settings/general", }, { id: "automatic-updates", title: "Automatic updates", to: "/settings/general", },]; describe("searchSettings", () => { it("matches titles, sections, and remembered setting details", () => { expect(searchSettings("word", ITEMS).map((item) => item.id)).toEqual(["word-wrap"]); expect(searchSettings("network", ITEMS).map((item) => item.id)).toEqual(["network-access"]); expect(searchSettings("connections", ITEMS).map((item) => item.id)).toEqual(["network-access"]); expect(searchSettings("claude", ITEMS).map((item) => item.id)).toEqual(["providers"]); expect(searchSettings("long lines", ITEMS).map((item) => item.id)).toEqual(["word-wrap"]); }); it("matches normalized title substrings", () => { expect(searchSettings(" WORD WRAP ", ITEMS).map((item) => item.id)).toEqual(["word-wrap"]); expect(searchSettings("glass").map((item) => item.id)).toEqual(["setting-glass-opacity"]); expect(searchSettings("panel animations").map((item) => item.id)).toEqual(["panel-animations"]); expect(searchSettings("thè\u{1ab0}mes")[0]?.id).toBe("theme"); const localeLowerCase = vi.spyOn(String.prototype, "toLocaleLowerCase").mockReturnValue("gıt"); try { expect(searchSettings("GIT")[0]?.id).toBe("git-fetch-interval"); expect(localeLowerCase).not.toHaveBeenCalled(); } finally { localeLowerCase.mockRestore(); } expect(searchSettings("xyzzy")).toEqual([]); }); it("keeps catalog order for multiple title matches", () => { expect(searchSettings("update", ITEMS).map((item) => item.id)).toEqual([ "provider-updates", "automatic-updates", ]); }); it("matches query words across fields and ranks the strongest result first", () => { expect(searchSettings("pairing remote", ITEMS).map((item) => item.id)).toEqual([ "network-access", ]); expect( searchSettings("remote pairing") .slice(0, 2) .map((item) => item.id), ).toEqual(["network-access", "connections-environment"]); }); it("finds settings that used to be reachable only through their section", () => { expect(searchSettings("pull request template")[0]?.id).toBe("follow-change-request-templates"); expect(searchSettings("git security keys")[0]?.id).toBe("git-fetch-interval"); expect(searchSettings("push notifications")[0]?.id).toBe("publish-agent-activity"); expect(searchSettings("battery saver")[0]?.id).toBe("background-activity"); expect(searchSettings("binary path")[0]?.id).toBe("providers"); expect(searchSettings("Antigravity")[0]?.id).toBe("providers"); expect(searchSettings("Google sign in")[0]?.id).toBe("providers"); expect(searchSettings("authorized clients")[0]?.id).toBe("connections-environment"); expect(searchSettings("administrative access")[0]?.id).toBe("connections-environment"); }); it("lists thread confirmations in panel order", () => { expect(searchSettings("confirmation").map((item) => item.id)).toEqual([ "unpin-confirmation", "archive-confirmation", "delete-confirmation", ]); }); it.each(["usage providers", "CLIProxyAPI", "CLI proxy hub", "management key"])( "finds usage-provider management by %s", (query) => { expect(searchSettings(query)[0]).toMatchObject({ id: "usage-providers", to: "/settings/providers", }); }, ); it("returns no results for an empty query", () => { expect(searchSettings(" ", ITEMS)).toEqual([]); }); it("hides desktop-only settings from browser search", () => { expect(SETTINGS_SEARCH_ITEMS.some((item) => item.id === "quit-confirmation")).toBe(true); expect(searchSettings("hold to quit")).toEqual([]); expect(searchSettings("wsl")).toEqual([]); }); it("hides macOS-only settings on other platforms", () => { vi.stubGlobal("navigator", { platform: "Win32" }); try { expect(searchSettings("font smoothing")).toEqual([]); } finally { vi.unstubAllGlobals(); } }); it("registers the WSL backend as a desktop-only setting", () => { expect(SETTINGS_SEARCH_ITEMS.find((item) => item.id === "wsl-backend")).toMatchObject({ id: "wsl-backend", title: "WSL backend", to: "/settings/connections", desktopOnly: true, windowsOnly: true, }); }); it("hides settings whose controls are unavailable", () => { const available = filterAvailableSettingsSearchItems({ hasCloudPublicConfig: false, hasPrimaryEnvironment: false, hasProviderSettingsEnvironment: false, canManageLocalBackend: false, isWslSettingsRowVisible: false, hasThreadAutoSettlement: false, }); const gatedIds = new Set<string>([ "follow-change-request-templates", "git-fetch-interval", "network-access", "publish-agent-activity", "provider-health-check-interval", "source-control-writer-model", "source-control-writing-style", "t3-connect", "tailscale-https", "wsl-backend", "auto-settle-inactive-threads", "auto-settle-merged-threads", "days-before-auto-settle", ]); expect(available.map((item) => item.id).filter((id) => gatedIds.has(id))).toEqual([]); }); it("shows automatic settlement settings when the server supports them", () => { const available = filterAvailableSettingsSearchItems({ hasCloudPublicConfig: false, hasPrimaryEnvironment: false, hasProviderSettingsEnvironment: false, canManageLocalBackend: false, isWslSettingsRowVisible: false, hasThreadAutoSettlement: true, }); expect(searchSettings("auto-settle", available).map((item) => item.id)).toEqual([ "auto-settle-inactive-threads", "auto-settle-merged-threads", "days-before-auto-settle", ]); }); it("keeps catalog result ids unique", () => { const ids = SETTINGS_SEARCH_ITEMS.map((item) => item.id); expect(new Set(ids).size).toBe(ids.length); }); it("serves anchor props to panels from the catalog", () => { expect(searchableSetting("word-wrap")).toEqual({ id: "word-wrap", title: "Word wrap" }); expect(searchableSetting("archive")).toEqual({ id: "archive", title: "Archived threads" }); }); it("routes appearance settings to their current section", () => { expect(searchSettings("theme")[0]).toMatchObject({ id: "theme", to: "/settings/appearance", }); expect(searchSettings("word wrap")[0]).toMatchObject({ id: "word-wrap", to: "/settings/appearance", }); expect(searchSettings("environment identification")[0]).toMatchObject({ id: "environment-identification", to: "/settings/appearance", targetId: "appearance-interface", }); }); it("routes conditional window capture settings to the stable toggle row", () => { const targets = [ "capture accessibility data", "capture shortcut", "capture sound", "capture flash", "capture animations", ].map((query) => { const match = searchSettings(query)[0]; return [match?.id, match?.targetId]; }); expect(targets).toEqual([ ["snap-shot-accessibility", "snap-shot-enabled"], ["snap-shot-shortcut", "snap-shot-enabled"], ["snap-shot-sound", "snap-shot-enabled"], ["snap-shot-flash", "snap-shot-enabled"], ["snap-shot-animations", "snap-shot-enabled"], ]); }); it("routes browser recording quality to integrations", () => { const result = searchSettings("recording frame rate")[0]; expect(result).toMatchObject({ id: "browser-recording-frame-rate", to: "/settings/integrations", }); expect(result).not.toHaveProperty("targetId"); }); it("routes where links open to integrations", () => { expect(searchSettings("open links in")[0]).toMatchObject({ id: "browser-link-target", to: "/settings/integrations", }); expect(searchSettings("external links")[0]).toMatchObject({ id: "browser-link-target" }); }); it("finds the default browser profile action in the profiles list", () => { expect(searchSettings("default profile")[0]).toMatchObject({ id: "browser-default-profile", to: "/settings/integrations", targetId: "browser-profiles", }); });});
import { describe, expect, it, vi } from "vite-plus/test";
import {
filterAvailableSettingsSearchItems,
searchableSetting,
searchSettings,
SETTINGS_SEARCH_ITEMS,
type SettingsSearchItem,
} from "./settingsSearch";
const ITEMS: ReadonlyArray<SettingsSearchItem> = [
{
id: "word-wrap",
title: "Word wrap",
to: "/settings/general",
searchTerms: ["long lines in code previews"],
},
{
id: "network-access",
title: "Network access",
to: "/settings/connections",
searchTerms: ["remote pairing backend"],
},
{
id: "providers",
title: "Providers",
to: "/settings/providers",
searchTerms: ["claude codex agents"],
},
{
id: "provider-updates",
title: "Update checks",
to: "/settings/general",
},
{
id: "automatic-updates",
title: "Automatic updates",
to: "/settings/general",
},
];
describe("searchSettings", () => {
it("matches titles, sections, and remembered setting details", () => {
expect(searchSettings("word", ITEMS).map((item) => item.id)).toEqual(["word-wrap"]);
expect(searchSettings("network", ITEMS).map((item) => item.id)).toEqual(["network-access"]);
expect(searchSettings("connections", ITEMS).map((item) => item.id)).toEqual(["network-access"]);
expect(searchSettings("claude", ITEMS).map((item) => item.id)).toEqual(["providers"]);
expect(searchSettings("long lines", ITEMS).map((item) => item.id)).toEqual(["word-wrap"]);
});
it("matches normalized title substrings", () => {
expect(searchSettings(" WORD WRAP ", ITEMS).map((item) => item.id)).toEqual(["word-wrap"]);
expect(searchSettings("glass").map((item) => item.id)).toEqual(["setting-glass-opacity"]);
expect(searchSettings("panel animations").map((item) => item.id)).toEqual(["panel-animations"]);
expect(searchSettings("thè\u{1ab0}mes")[0]?.id).toBe("theme");
const localeLowerCase = vi.spyOn(String.prototype, "toLocaleLowerCase").mockReturnValue("gıt");
try {
expect(searchSettings("GIT")[0]?.id).toBe("git-fetch-interval");
expect(localeLowerCase).not.toHaveBeenCalled();
} finally {
localeLowerCase.mockRestore();
}
expect(searchSettings("xyzzy")).toEqual([]);
});
it("keeps catalog order for multiple title matches", () => {
expect(searchSettings("update", ITEMS).map((item) => item.id)).toEqual([
"provider-updates",
"automatic-updates",
]);
});
it("matches query words across fields and ranks the strongest result first", () => {
expect(searchSettings("pairing remote", ITEMS).map((item) => item.id)).toEqual([
"network-access",
]);
expect(
searchSettings("remote pairing")
.slice(0, 2)
.map((item) => item.id),
).toEqual(["network-access", "connections-environment"]);
});
it("finds settings that used to be reachable only through their section", () => {
expect(searchSettings("pull request template")[0]?.id).toBe("follow-change-request-templates");
expect(searchSettings("git security keys")[0]?.id).toBe("git-fetch-interval");
expect(searchSettings("push notifications")[0]?.id).toBe("publish-agent-activity");
expect(searchSettings("battery saver")[0]?.id).toBe("background-activity");
expect(searchSettings("binary path")[0]?.id).toBe("providers");
expect(searchSettings("Antigravity")[0]?.id).toBe("providers");
expect(searchSettings("Google sign in")[0]?.id).toBe("providers");
expect(searchSettings("authorized clients")[0]?.id).toBe("connections-environment");
expect(searchSettings("administrative access")[0]?.id).toBe("connections-environment");
});
it("lists thread confirmations in panel order", () => {
expect(searchSettings("confirmation").map((item) => item.id)).toEqual([
"unpin-confirmation",
"archive-confirmation",
"delete-confirmation",
]);
});
it.each(["usage providers", "CLIProxyAPI", "CLI proxy hub", "management key"])(
"finds usage-provider management by %s",
(query) => {
expect(searchSettings(query)[0]).toMatchObject({
id: "usage-providers",
to: "/settings/providers",
});
},
);
it("returns no results for an empty query", () => {
expect(searchSettings(" ", ITEMS)).toEqual([]);
});
it("hides desktop-only settings from browser search", () => {
expect(SETTINGS_SEARCH_ITEMS.some((item) => item.id === "quit-confirmation")).toBe(true);
expect(searchSettings("hold to quit")).toEqual([]);
expect(searchSettings("wsl")).toEqual([]);
});
it("hides macOS-only settings on other platforms", () => {
vi.stubGlobal("navigator", { platform: "Win32" });
try {
expect(searchSettings("font smoothing")).toEqual([]);
} finally {
vi.unstubAllGlobals();
}
});
it("registers the WSL backend as a desktop-only setting", () => {
expect(SETTINGS_SEARCH_ITEMS.find((item) => item.id === "wsl-backend")).toMatchObject({
id: "wsl-backend",
title: "WSL backend",
to: "/settings/connections",
desktopOnly: true,
windowsOnly: true,
});
});
it("hides settings whose controls are unavailable", () => {
const available = filterAvailableSettingsSearchItems({
hasCloudPublicConfig: false,
hasPrimaryEnvironment: false,
hasProviderSettingsEnvironment: false,
canManageLocalBackend: false,
isWslSettingsRowVisible: false,
hasThreadAutoSettlement: false,
});
const gatedIds = new Set<string>([
"follow-change-request-templates",
"git-fetch-interval",
"network-access",
"publish-agent-activity",
"provider-health-check-interval",
"source-control-writer-model",
"source-control-writing-style",
"t3-connect",
"tailscale-https",
"wsl-backend",
"auto-settle-inactive-threads",
"auto-settle-merged-threads",
"days-before-auto-settle",
]);
expect(available.map((item) => item.id).filter((id) => gatedIds.has(id))).toEqual([]);
});
it("shows automatic settlement settings when the server supports them", () => {
const available = filterAvailableSettingsSearchItems({
hasCloudPublicConfig: false,
hasPrimaryEnvironment: false,
hasProviderSettingsEnvironment: false,
canManageLocalBackend: false,
isWslSettingsRowVisible: false,
hasThreadAutoSettlement: true,
});
expect(searchSettings("auto-settle", available).map((item) => item.id)).toEqual([
"auto-settle-inactive-threads",
"auto-settle-merged-threads",
"days-before-auto-settle",
]);
});
it("keeps catalog result ids unique", () => {
const ids = SETTINGS_SEARCH_ITEMS.map((item) => item.id);
expect(new Set(ids).size).toBe(ids.length);
});
it("serves anchor props to panels from the catalog", () => {
expect(searchableSetting("word-wrap")).toEqual({ id: "word-wrap", title: "Word wrap" });
expect(searchableSetting("archive")).toEqual({ id: "archive", title: "Archived threads" });
});
it("routes appearance settings to their current section", () => {
expect(searchSettings("theme")[0]).toMatchObject({
id: "theme",
to: "/settings/appearance",
});
expect(searchSettings("word wrap")[0]).toMatchObject({
id: "word-wrap",
to: "/settings/appearance",
});
expect(searchSettings("environment identification")[0]).toMatchObject({
id: "environment-identification",
to: "/settings/appearance",
targetId: "appearance-interface",
});
});
it("routes conditional window capture settings to the stable toggle row", () => {
const targets = [
"capture accessibility data",
"capture shortcut",
"capture sound",
"capture flash",
"capture animations",
].map((query) => {
const match = searchSettings(query)[0];
return [match?.id, match?.targetId];
});
expect(targets).toEqual([
["snap-shot-accessibility", "snap-shot-enabled"],
["snap-shot-shortcut", "snap-shot-enabled"],
["snap-shot-sound", "snap-shot-enabled"],
["snap-shot-flash", "snap-shot-enabled"],
["snap-shot-animations", "snap-shot-enabled"],
]);
});
it("routes browser recording quality to integrations", () => {
const result = searchSettings("recording frame rate")[0];
expect(result).toMatchObject({
id: "browser-recording-frame-rate",
to: "/settings/integrations",
});
expect(result).not.toHaveProperty("targetId");
});
it("routes where links open to integrations", () => {
expect(searchSettings("open links in")[0]).toMatchObject({
id: "browser-link-target",
to: "/settings/integrations",
});
expect(searchSettings("external links")[0]).toMatchObject({ id: "browser-link-target" });
});
it("finds the default browser profile action in the profiles list", () => {
expect(searchSettings("default profile")[0]).toMatchObject({
id: "browser-default-profile",
to: "/settings/integrations",
targetId: "browser-profiles",
});
});
});