116 lines
3.5 KiB
JavaScript
116 lines
3.5 KiB
JavaScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
groupSystemSearchResults,
|
|
moveSystemSearchSelection,
|
|
shouldBypassTextEntryForSystemSearchKey,
|
|
sortSystemSearchResults,
|
|
sortSystemSearchGroupKeys,
|
|
syncSystemSearchKeyboardState,
|
|
} from "@/components/viewport/page/headers/menu/systemSearchUiSupport.ts";
|
|
|
|
const row = (entityType, entityId) => ({
|
|
entity_type: entityType,
|
|
entity_id: String(entityId),
|
|
title: `${entityType}-${entityId}`,
|
|
score: 100,
|
|
});
|
|
|
|
describe("system search UI ordering support", () => {
|
|
it("preserves backend relevance order for flat results", () => {
|
|
const sorted = sortSystemSearchResults([
|
|
row("orders", 2),
|
|
row("module_config", 9),
|
|
row("customers", 7),
|
|
row("order_bookings", 4),
|
|
row("orders", 5),
|
|
row("notifications", 3),
|
|
]);
|
|
|
|
expect(sorted.map((entry) => `${entry.entity_type}:${entry.entity_id}`)).toEqual([
|
|
"orders:2",
|
|
"module_config:9",
|
|
"customers:7",
|
|
"order_bookings:4",
|
|
"orders:5",
|
|
"notifications:3",
|
|
]);
|
|
});
|
|
|
|
it("preserves backend relevance order for grouped keys", () => {
|
|
expect(sortSystemSearchGroupKeys(["orders", "mystery", "customers", "order_bookings"])).toEqual([
|
|
"orders",
|
|
"mystery",
|
|
"customers",
|
|
"order_bookings",
|
|
]);
|
|
});
|
|
|
|
it("builds grouped results in first-result order", () => {
|
|
const grouped = groupSystemSearchResults([
|
|
row("orders", 2),
|
|
row("customers", 7),
|
|
row("order_bookings", 4),
|
|
row("orders", 5),
|
|
]);
|
|
|
|
expect(Object.keys(grouped)).toEqual(["orders", "customers", "order_bookings"]);
|
|
expect(grouped.orders.map((entry) => entry.entity_id)).toEqual(["2", "5"]);
|
|
});
|
|
});
|
|
|
|
describe("system search keyboard selection support", () => {
|
|
it("defaults sidebar and result selection to the active group and first result", () => {
|
|
const synced = syncSystemSearchKeyboardState(
|
|
{
|
|
pane: "results",
|
|
selectedSidebarKey: null,
|
|
selectedResultKey: null,
|
|
},
|
|
["all", "customers", "orders"],
|
|
["customers-7", "orders-2"],
|
|
"all"
|
|
);
|
|
|
|
expect(synced).toEqual({
|
|
pane: "results",
|
|
selectedSidebarKey: "all",
|
|
selectedResultKey: "customers-7",
|
|
});
|
|
});
|
|
|
|
it("falls back to sidebar mode when the selected result disappears", () => {
|
|
const synced = syncSystemSearchKeyboardState(
|
|
{
|
|
pane: "results",
|
|
selectedSidebarKey: "customers",
|
|
selectedResultKey: "missing",
|
|
},
|
|
["all", "customers", "orders"],
|
|
[],
|
|
"customers"
|
|
);
|
|
|
|
expect(synced).toEqual({
|
|
pane: "sidebar",
|
|
selectedSidebarKey: "customers",
|
|
selectedResultKey: null,
|
|
});
|
|
});
|
|
|
|
it("moves selection up and down without wrapping past the list edges", () => {
|
|
const keys = ["customers", "orders", "order_bookings"];
|
|
|
|
expect(moveSystemSearchSelection(keys, null, 1)).toBe("customers");
|
|
expect(moveSystemSearchSelection(keys, "customers", -1)).toBe("customers");
|
|
expect(moveSystemSearchSelection(keys, "orders", 1)).toBe("order_bookings");
|
|
expect(moveSystemSearchSelection(keys, "order_bookings", 1)).toBe("order_bookings");
|
|
});
|
|
|
|
it("keeps navigation keys active when text focus lingers outside query mode", () => {
|
|
expect(shouldBypassTextEntryForSystemSearchKey("sidebar", "Enter")).toBe(true);
|
|
expect(shouldBypassTextEntryForSystemSearchKey("results", "ArrowDown")).toBe(true);
|
|
expect(shouldBypassTextEntryForSystemSearchKey("query", "Enter")).toBe(false);
|
|
expect(shouldBypassTextEntryForSystemSearchKey("results", "a")).toBe(false);
|
|
});
|
|
});
|