Files
WonderQ-Project/WonderQ-MiniAPP/tests/searchFilters.test.ts
2026-08-11 19:19:11 +08:00

103 lines
3.2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { Product } from "@/lib/types";
import {
defaultSearchFilterState,
filterAndSortSearchProducts,
normalizePriceInput,
parseTripDays,
} from "@/lib/searchFilters";
function createProduct(id: number, title: string, price: string): Product {
return {
id,
title,
price,
tags: [],
image: `/assets/test-${id}.jpg`,
};
}
describe("search filter helpers", () => {
const products = [
createProduct(1, "贵州黄果树 7天6晚精品小包团", "57500"),
createProduct(2, "荔波小七孔 15天及以上深度旅行", "112500"),
createProduct(3, "西江苗寨 4日轻松游", "36000"),
createProduct(4, "贵州定制旅行方案", "98000"),
];
it("parses trip days from route titles", () => {
expect(parseTripDays("贵州黄果树 7天6晚精品小包团")).toBe(7);
expect(parseTripDays("西江苗寨 4日轻松游")).toBe(4);
expect(parseTripDays("贵州定制旅行方案")).toBeNull();
});
it("normalizes price input values", () => {
expect(normalizePriceInput(" 57500 ")).toBe(57500);
expect(normalizePriceInput("")).toBeNull();
expect(normalizePriceInput("abc")).toBeNull();
});
it("filters products by applied price range", () => {
const results = filterAndSortSearchProducts(products, {
...defaultSearchFilterState,
priceMin: 50000,
priceMax: 100000,
});
expect(results.map((product) => product.id)).toEqual([1, 4]);
});
it("treats reversed price bounds as the same numeric range", () => {
const results = filterAndSortSearchProducts(products, {
...defaultSearchFilterState,
priceMin: 100000,
priceMax: 50000,
});
expect(results.map((product) => product.id)).toEqual([1, 4]);
});
it("sorts by price ascending and descending", () => {
const lowToHigh = filterAndSortSearchProducts(products, {
...defaultSearchFilterState,
sortKey: "priceAsc",
});
const highToLow = filterAndSortSearchProducts(products, {
...defaultSearchFilterState,
sortKey: "priceDesc",
});
expect(lowToHigh.map((product) => product.id)).toEqual([3, 1, 4, 2]);
expect(highToLow.map((product) => product.id)).toEqual([2, 4, 1, 3]);
});
it("keeps the recommended order for sales proxy sorting", () => {
const results = filterAndSortSearchProducts(products, {
...defaultSearchFilterState,
sortKey: "salesDesc",
});
expect(results.map((product) => product.id)).toEqual([1, 2, 3, 4]);
});
it("filters by exact days and fifteen days plus", () => {
const exact = filterAndSortSearchProducts(products, {
...defaultSearchFilterState,
duration: 4,
});
const longTrip = filterAndSortSearchProducts(products, {
...defaultSearchFilterState,
duration: "15plus",
});
expect(exact.map((product) => product.id)).toEqual([3]);
expect(longTrip.map((product) => product.id)).toEqual([2]);
});
it("clears filter conditions by using the default state", () => {
const results = filterAndSortSearchProducts(products, defaultSearchFilterState);
expect(results.map((product) => product.id)).toEqual([1, 2, 3, 4]);
});
});