Files
pokemon-inventory/apps/api/tests/domain/search-query.test.js
T
2026-09-10 03:04:10 -04:00

90 lines
2.8 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import {
buildSearchFilters,
createSearchQuery,
normalizeSearchQuery,
} from "../../src/modules/search/domain/search-query.js";
test("normalizes a public search query and keeps filter values within bounds", () => {
const query = createSearchQuery({
query: " Charizard ex ",
category: "Cards",
setName: "SV151",
eventName: "Worlds",
tag: "Binder",
minPriceMinor: 1000,
maxPriceMinor: 5000,
page: 1,
limit: 20,
includeSold: false,
});
assert.equal(query.text, "charizard ex");
assert.equal(query.category, "Cards");
assert.equal(query.setName, "SV151");
assert.equal(query.eventName, "Worlds");
assert.equal(query.tag, "binder");
assert.equal(query.minPriceMinor, 1000);
assert.equal(query.maxPriceMinor, 5000);
assert.equal(query.page, 1);
assert.equal(query.limit, 20);
assert.equal(query.includeSold, false);
});
test("rejects invalid pagination and price boundaries", () => {
assert.throws(
() => createSearchQuery({ query: "abc", page: 0, limit: 20 }),
/page must be >= 1/,
);
assert.throws(
() =>
createSearchQuery({
query: "abc",
minPriceMinor: 5000,
maxPriceMinor: 1000,
}),
/minPriceMinor must be <= maxPriceMinor/,
);
assert.throws(
() => createSearchQuery({ query: "abc", limit: 0 }),
/limit must be between 1 and 100/,
);
});
test("builds a public query filter set that hides sold items by default", () => {
const filters = buildSearchFilters({ includeSold: false });
assert.equal(filters.status, "AVAILABLE");
assert.equal(filters.includeSold, false);
assert.deepEqual(filters.sort, ["recently_added"]);
});
test("accepts only the supported public search sort values", () => {
assert.equal(createSearchQuery({ sort: "price_low" }).sort, "price_low");
assert.equal(createSearchQuery({ sort: "updated" }).sort, "updated");
assert.equal(createSearchQuery({ sort: "name_asc" }).sort, "name_asc");
assert.equal(createSearchQuery({ sort: "name_desc" }).sort, "name_desc");
assert.equal(createSearchQuery({ sort: "market_low" }).sort, "market_low");
assert.equal(createSearchQuery({ sort: "market_high" }).sort, "market_high");
assert.throws(
() => createSearchQuery({ sort: "random" }),
/sort must be recent/,
);
});
test("accepts public status and newly-added filters", () => {
const query = createSearchQuery({ status: "SOLD", newlyAdded: true });
assert.equal(query.status, "SOLD");
assert.equal(query.newlyAdded, true);
assert.throws(() => createSearchQuery({ status: "UNKNOWN" }), /status must be/);
});
test("normalizes whitespace and punctuation in free-text search terms", () => {
assert.equal(
normalizeSearchQuery(" Pikachu #199 / holo "),
"pikachu 199 holo",
);
});