120 lines
3.0 KiB
TypeScript
120 lines
3.0 KiB
TypeScript
import { act, renderHook } from "@testing-library/react";
|
|
import { describe, expect, it, vi, beforeEach } from "vitest";
|
|
|
|
import { useUrlSorting } from "./use-url-sorting";
|
|
|
|
const replaceMock = vi.fn();
|
|
let mockPathname = "/agents";
|
|
|
|
vi.mock("next/navigation", () => ({
|
|
useRouter: () => ({
|
|
replace: replaceMock,
|
|
}),
|
|
usePathname: () => mockPathname,
|
|
}));
|
|
|
|
describe("useUrlSorting", () => {
|
|
beforeEach(() => {
|
|
replaceMock.mockReset();
|
|
mockPathname = "/agents";
|
|
window.history.replaceState({}, "", "/agents");
|
|
});
|
|
|
|
it("uses default sorting when no params are present", () => {
|
|
const { result } = renderHook(() =>
|
|
useUrlSorting({
|
|
allowedColumnIds: ["name", "status"],
|
|
defaultSorting: [{ id: "name", desc: false }],
|
|
paramPrefix: "agents",
|
|
}),
|
|
);
|
|
|
|
expect(result.current.sorting).toEqual([{ id: "name", desc: false }]);
|
|
});
|
|
|
|
it("reads sorting from URL params", () => {
|
|
window.history.replaceState(
|
|
{},
|
|
"",
|
|
"/agents?agents_sort=status&agents_dir=desc",
|
|
);
|
|
|
|
const { result } = renderHook(() =>
|
|
useUrlSorting({
|
|
allowedColumnIds: ["name", "status"],
|
|
defaultSorting: [{ id: "name", desc: false }],
|
|
paramPrefix: "agents",
|
|
}),
|
|
);
|
|
|
|
expect(result.current.sorting).toEqual([{ id: "status", desc: true }]);
|
|
});
|
|
|
|
it("writes updated sorting to URL and preserves unrelated params", () => {
|
|
window.history.replaceState({}, "", "/agents?foo=1");
|
|
|
|
const { result } = renderHook(() =>
|
|
useUrlSorting({
|
|
allowedColumnIds: ["name", "status"],
|
|
defaultSorting: [{ id: "name", desc: false }],
|
|
paramPrefix: "agents",
|
|
}),
|
|
);
|
|
|
|
act(() => {
|
|
result.current.onSortingChange([{ id: "status", desc: true }]);
|
|
});
|
|
|
|
expect(replaceMock).toHaveBeenCalledWith(
|
|
"/agents?foo=1&agents_sort=status&agents_dir=desc",
|
|
{
|
|
scroll: false,
|
|
},
|
|
);
|
|
});
|
|
|
|
it("removes sorting params when returning to default sorting", () => {
|
|
window.history.replaceState(
|
|
{},
|
|
"",
|
|
"/agents?foo=1&agents_sort=status&agents_dir=desc",
|
|
);
|
|
|
|
const { result } = renderHook(() =>
|
|
useUrlSorting({
|
|
allowedColumnIds: ["name", "status"],
|
|
defaultSorting: [{ id: "name", desc: false }],
|
|
paramPrefix: "agents",
|
|
}),
|
|
);
|
|
|
|
act(() => {
|
|
result.current.onSortingChange([{ id: "name", desc: false }]);
|
|
});
|
|
|
|
expect(replaceMock).toHaveBeenCalledWith("/agents?foo=1", {
|
|
scroll: false,
|
|
});
|
|
});
|
|
|
|
it("supports explicit no-sorting state via sentinel", () => {
|
|
window.history.replaceState({}, "", "/agents?agents_sort=none");
|
|
|
|
const { result } = renderHook(() =>
|
|
useUrlSorting({
|
|
allowedColumnIds: ["name", "status"],
|
|
defaultSorting: [{ id: "name", desc: false }],
|
|
paramPrefix: "agents",
|
|
}),
|
|
);
|
|
|
|
expect(result.current.sorting).toEqual([]);
|
|
|
|
act(() => {
|
|
result.current.onSortingChange([]);
|
|
});
|
|
|
|
expect(replaceMock).not.toHaveBeenCalled();
|
|
});
|
|
});
|