189 lines
5.8 KiB
TypeScript
189 lines
5.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import {
|
|
createGridQuery,
|
|
gridQueryHasActiveFilters,
|
|
gridQueryKey,
|
|
gridListQueryKey,
|
|
isDefaultOutputBrowseQuery,
|
|
readGridQueryFromDataset,
|
|
readGridQueryFromElement,
|
|
readGridQueryText,
|
|
readGridSortKey,
|
|
} from "../vue/grid/useGridQuery.js";
|
|
|
|
describe("useGridQuery helpers", () => {
|
|
it("normalizes an immutable grid query", () => {
|
|
const query = createGridQuery({
|
|
scope: "Output",
|
|
q: " portrait ",
|
|
kind: "Image",
|
|
minRating: "4",
|
|
workflowOnly: "1",
|
|
sort: "MTIME_DESC",
|
|
semanticMode: true,
|
|
});
|
|
|
|
expect(Object.isFrozen(query)).toBe(true);
|
|
expect(query).toMatchObject({
|
|
scope: "output",
|
|
q: "portrait",
|
|
query: "portrait",
|
|
kind: "image",
|
|
minRating: 4,
|
|
workflowOnly: true,
|
|
sort: "mtime_desc",
|
|
semanticMode: true,
|
|
});
|
|
});
|
|
|
|
it("leaves UI-only booleans absent unless explicitly provided", () => {
|
|
const query = createGridQuery();
|
|
|
|
expect(query.semanticMode).toBeUndefined();
|
|
expect(query.groupStacks).toBeUndefined();
|
|
});
|
|
|
|
it("reads all grid filter fields from a DOM dataset shape", () => {
|
|
const query = readGridQueryFromDataset({
|
|
mjrScope: "custom",
|
|
mjrQuery: "cat",
|
|
mjrCustomRootId: "root-a",
|
|
mjrSubfolder: "animals",
|
|
mjrCollectionId: "collection-a",
|
|
mjrViewScope: "folder",
|
|
mjrFilterKind: "video",
|
|
mjrFilterWorkflowOnly: "1",
|
|
mjrFilterMinRating: "3",
|
|
mjrFilterMinSizeMB: "10",
|
|
mjrFilterMaxSizeMB: "20",
|
|
mjrFilterResolutionCompare: "lte",
|
|
mjrFilterMinWidth: "512",
|
|
mjrFilterMinHeight: "512",
|
|
mjrFilterMaxWidth: "2048",
|
|
mjrFilterMaxHeight: "2048",
|
|
mjrFilterWorkflowType: "t2i",
|
|
mjrFilterWorkflowModel: "Flux",
|
|
mjrFilterWorkflowRunsOn: "LOCAL",
|
|
mjrFilterDateRange: "TODAY",
|
|
mjrFilterDateExact: "2026-04-30",
|
|
mjrMetadataMode: "OR",
|
|
mjrSort: "name_asc",
|
|
mjrSemanticMode: "1",
|
|
mjrGroupStacks: "1",
|
|
});
|
|
|
|
expect(query).toMatchObject({
|
|
scope: "custom",
|
|
q: "cat",
|
|
customRootId: "root-a",
|
|
subfolder: "animals",
|
|
collectionId: "collection-a",
|
|
viewScope: "folder",
|
|
kind: "video",
|
|
workflowOnly: true,
|
|
minRating: 3,
|
|
minSizeMB: 10,
|
|
maxSizeMB: 20,
|
|
resolutionCompare: "lte",
|
|
minWidth: 512,
|
|
minHeight: 512,
|
|
maxWidth: 2048,
|
|
maxHeight: 2048,
|
|
workflowType: "T2I",
|
|
workflowModel: "Flux",
|
|
workflowRunsOn: "local",
|
|
dateRange: "today",
|
|
dateExact: "2026-04-30",
|
|
metadataSearchMode: "OR",
|
|
sort: "name_asc",
|
|
semanticMode: true,
|
|
groupStacks: true,
|
|
});
|
|
});
|
|
|
|
it("bridges query and sort reads from a grid element", () => {
|
|
const element = {
|
|
dataset: {
|
|
mjrQuery: " fox ",
|
|
mjrSort: "NAME_DESC",
|
|
mjrScope: "output",
|
|
},
|
|
};
|
|
|
|
expect(readGridQueryFromElement(element)).toMatchObject({ q: "fox", sort: "name_desc" });
|
|
expect(readGridQueryText(element, "*")).toBe("fox");
|
|
expect(readGridSortKey(element, "mtime_desc")).toBe("name_desc");
|
|
expect(readGridQueryText(null, "fallback")).toBe("fallback");
|
|
});
|
|
|
|
it("detects default output browse and stable query keys", () => {
|
|
const defaultQuery = createGridQuery();
|
|
const filteredQuery = createGridQuery({ minRating: 5 });
|
|
|
|
expect(isDefaultOutputBrowseQuery(defaultQuery)).toBe(true);
|
|
expect(gridQueryHasActiveFilters(defaultQuery)).toBe(false);
|
|
expect(isDefaultOutputBrowseQuery(filteredQuery)).toBe(false);
|
|
expect(gridQueryHasActiveFilters(filteredQuery)).toBe(true);
|
|
expect(gridQueryKey(defaultQuery)).toBe(gridQueryKey(createGridQuery({ q: "*" })));
|
|
});
|
|
|
|
it("does not treat UI-only modes as active search filters", () => {
|
|
const groupedDefaultOutput = createGridQuery({
|
|
scope: "output",
|
|
q: "*",
|
|
sort: "mtime_desc",
|
|
viewScope: "output",
|
|
semanticMode: true,
|
|
groupStacks: true,
|
|
});
|
|
|
|
expect(gridQueryHasActiveFilters(groupedDefaultOutput)).toBe(false);
|
|
expect(isDefaultOutputBrowseQuery(groupedDefaultOutput)).toBe(true);
|
|
});
|
|
|
|
it("treats a virtual view scope as an active filter", () => {
|
|
const similarView = createGridQuery({ scope: "output", viewScope: "similar" });
|
|
|
|
expect(gridQueryHasActiveFilters(similarView)).toBe(true);
|
|
expect(isDefaultOutputBrowseQuery(similarView)).toBe(false);
|
|
});
|
|
|
|
it("builds the list key used by early fetch without UI-only fields", () => {
|
|
const query = createGridQuery({
|
|
scope: "output",
|
|
q: "*",
|
|
sort: "mtime_desc",
|
|
viewScope: "folder",
|
|
semanticMode: true,
|
|
groupStacks: true,
|
|
});
|
|
|
|
expect(gridListQueryKey(query)).toBe([
|
|
"output",
|
|
"*",
|
|
"mtime_desc",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"gte",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
].join("|"));
|
|
expect(gridQueryKey(query)).not.toBe(gridListQueryKey(query));
|
|
});
|
|
});
|