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]); }); });