Files
yaak-mountain-loop/apps/yaak-proxy/lib/query.test.ts
T

108 lines
3.8 KiB
TypeScript

import { describe, expect, test } from "vite-plus/test";
import {
activeQuery,
anyCountsBackFromNow,
asOneTerm,
countsBackFromNow,
fieldTerm,
pathTerm,
termKeys,
widerQueries,
} from "./query";
import { savedCompletions } from "./searchBox";
describe("terms", () => {
test("quote values that need it", () => {
expect(fieldTerm("app", "Google Chrome")).toBe('@app:"Google Chrome"');
expect(fieldTerm("host", "api.x.com")).toBe("@host:api.x.com");
expect(fieldTerm("is", "system", true)).toBe("-@is:system");
});
test("select a path and what is under it", () => {
expect(pathTerm("/v1/charges")).toBe("@path:/v1/charges/*");
expect(pathTerm("/a b")).toBe('@path:"/a b"');
});
test("are read back as written, any case, with their exclusion", () => {
expect(termKeys('@app:"Google Chrome" -@is:System (a OR -b)')).toEqual([
'@app:"google chrome"',
"-@is:system",
"a",
"-b",
]);
expect(termKeys("")).toEqual([]);
});
});
describe("activeQuery", () => {
test("is null for all traffic, and carries hiding System", () => {
expect(activeQuery(" ", false)).toBeNull();
expect(activeQuery("", true)).toEqual({ query: "", hideSystem: true });
expect(activeQuery(" stripe ", false)).toEqual({ query: "stripe", hideSystem: false });
});
});
describe("widerQueries", () => {
test("leaves out each term in turn", () => {
expect(widerQueries('@app:Slack @status:5xx "card declined"')).toEqual([
'@status:5xx "card declined"',
'@app:Slack "card declined"',
"@app:Slack @status:5xx",
]);
expect(widerQueries("@app:Slack")).toEqual([]);
});
test("widens one OR group at a time, keeping the groups", () => {
const text = "@app:Slack @host:absent.com OR @app:Chrome @host:absent.com";
expect(widerQueries(text)).toEqual([
"@host:absent.com OR @app:Chrome @host:absent.com",
"@app:Slack OR @app:Chrome @host:absent.com",
"@app:Slack @host:absent.com OR @host:absent.com",
"@app:Slack @host:absent.com OR @app:Chrome",
]);
// A group of one term is not emptied, which would take in every flow.
expect(widerQueries("@app:Slack OR @app:Chrome @host:b.com")).toEqual([
"@app:Slack OR @host:b.com",
"@app:Slack OR @app:Chrome",
]);
});
test("keeps groups and exclusions whole", () => {
expect(widerQueries("(@status:4xx OR @status:5xx) -(a OR b) c")).toEqual([
"-(a OR b) c",
"(@status:4xx OR @status:5xx) c",
"(@status:4xx OR @status:5xx) -(a OR b)",
]);
});
});
describe("countsBackFromNow", () => {
test("is a @time comparison or range, which ages", () => {
expect(countsBackFromNow("@time:<5m")).toBe(true);
expect(countsBackFromNow("x -(@time:[1h TO 2h] OR y)")).toBe(true);
expect(countsBackFromNow("@time:2026-11-07")).toBe(false);
expect(countsBackFromNow("@status:<500 time")).toBe(false);
});
test("of saved searches, tells when their counts change with time alone", () => {
expect(anyCountsBackFromNow(["@status:4xx", "-@time:>1h stripe"])).toBe(true);
expect(anyCountsBackFromNow(["@status:4xx", "@time:2026-11-07"])).toBe(false);
expect(anyCountsBackFromNow([])).toBe(false);
});
});
describe("saved searches as completions", () => {
test("keep an OR at their top in one group, however it is spaced", () => {
expect(asOneTerm("@status:4xx OR @status:5xx")).toBe("(@status:4xx OR @status:5xx)");
expect(asOneTerm("(@status:4xx)OR(@status:5xx)")).toBe("((@status:4xx)OR(@status:5xx))");
expect(asOneTerm("(a OR b) c")).toBe("(a OR b) c");
const saved = [
{ id: "1", name: "Errors", query: "(@status:4xx)OR(@status:5xx)", sortOrder: 0 },
{ id: "2", name: "Stripe", query: "@host:*.stripe.com", sortOrder: 1 },
];
expect(savedCompletions(saved, "err").map((c) => c.apply)).toEqual([
"((@status:4xx)OR(@status:5xx))",
]);
});
});