refactor: 统一管理页面布局 — FilterToolbar + usePageSearchParams + parseListParams
This commit is contained in:
86
tests/web/use-page-search-params.test.ts
Normal file
86
tests/web/use-page-search-params.test.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { act, renderHook } from "@testing-library/react";
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { createElement } from "react";
|
||||
import { MemoryRouter, Route, Routes } from "react-router";
|
||||
|
||||
import { usePageSearchParams } from "../../src/web/shared/hooks/usePageSearchParams";
|
||||
|
||||
function renderWithRouter(initialPath: string) {
|
||||
return renderHook(() => usePageSearchParams(), {
|
||||
wrapper: ({ children }) =>
|
||||
createElement(
|
||||
MemoryRouter,
|
||||
{ initialEntries: [initialPath] },
|
||||
createElement(Routes, null, createElement(Route, { element: children, path: "*" })),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
function renderWithRouterAndDefaults(initialPath: string, defaults: Record<string, string>) {
|
||||
return renderHook(() => usePageSearchParams({ defaults }), {
|
||||
wrapper: ({ children }) =>
|
||||
createElement(
|
||||
MemoryRouter,
|
||||
{ initialEntries: [initialPath] },
|
||||
createElement(Routes, null, createElement(Route, { element: children, path: "*" })),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
describe("usePageSearchParams", () => {
|
||||
it("returns empty params when URL has no search params", () => {
|
||||
const { result } = renderWithRouter("/test");
|
||||
expect(result.current.params).toEqual({});
|
||||
});
|
||||
|
||||
it("parses existing URL search params", () => {
|
||||
const { result } = renderWithRouter("/test?page=2&keyword=abc");
|
||||
expect(result.current.params).toEqual({ keyword: "abc", page: "2" });
|
||||
});
|
||||
|
||||
it("merges defaults for missing keys", () => {
|
||||
const { result } = renderWithRouterAndDefaults("/test", { page: "1", pageSize: "20" });
|
||||
expect(result.current.params).toEqual({ page: "1", pageSize: "20" });
|
||||
});
|
||||
|
||||
it("URL value takes precedence over default", () => {
|
||||
const { result } = renderWithRouterAndDefaults("/test?page=3", { page: "1" });
|
||||
expect(result.current.params).toEqual({ page: "3" });
|
||||
});
|
||||
|
||||
it("setParam updates a single param", () => {
|
||||
const { result } = renderWithRouter("/test");
|
||||
act(() => result.current.setParam("keyword", "hello"));
|
||||
expect(result.current.params["keyword"]).toBe("hello");
|
||||
});
|
||||
|
||||
it("setParam with undefined removes the param", () => {
|
||||
const { result } = renderWithRouter("/test?keyword=hello");
|
||||
act(() => result.current.setParam("keyword", undefined));
|
||||
expect(result.current.params["keyword"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("setParam with empty string removes the param", () => {
|
||||
const { result } = renderWithRouter("/test?keyword=hello");
|
||||
act(() => result.current.setParam("keyword", ""));
|
||||
expect(result.current.params["keyword"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("setParams updates multiple params at once", () => {
|
||||
const { result } = renderWithRouter("/test");
|
||||
act(() => result.current.setParams({ keyword: "test", page: "2" }));
|
||||
expect(result.current.params).toEqual({ keyword: "test", page: "2" });
|
||||
});
|
||||
|
||||
it("setParams preserves existing params", () => {
|
||||
const { result } = renderWithRouter("/test?existing=yes");
|
||||
act(() => result.current.setParams({ page: "3" }));
|
||||
expect(result.current.params).toEqual({ existing: "yes", page: "3" });
|
||||
});
|
||||
|
||||
it("resetAll clears all params", () => {
|
||||
const { result } = renderWithRouter("/test?page=5&keyword=abc");
|
||||
act(() => result.current.resetAll());
|
||||
expect(result.current.params).toEqual({});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user