forked from StellarSplit/StellarSplit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSplitHistoryPage.test.tsx
More file actions
148 lines (127 loc) · 4.44 KB
/
Copy pathSplitHistoryPage.test.tsx
File metadata and controls
148 lines (127 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { MemoryRouter, useLocation, useNavigate } from "react-router-dom";
import { beforeEach, describe, expect, it, vi } from "vitest";
import SplitHistoryPage from "./SplitHistoryPage";
const repositoryMocks = vi.hoisted(() => ({
fetchHistory: vi.fn(),
}));
vi.mock("../services/splitHistoryRepository", () => ({
getSplitHistoryRepository: () => ({
fetchHistory: repositoryMocks.fetchHistory,
}),
}));
const emptyResponse = {
data: [],
source: "api" as const,
meta: {
page: 1,
limit: 20,
totalItems: 0,
totalPages: 1,
hasMore: false,
},
summary: {
totalAmount: 0,
average: 0,
counts: { active: 0, completed: 0, cancelled: 0 },
},
};
describe("SplitHistoryPage", () => {
beforeEach(() => {
repositoryMocks.fetchHistory.mockReset();
repositoryMocks.fetchHistory.mockResolvedValue(emptyResponse);
});
it("reads filters and pagination from the URL and fetches that page", async () => {
renderPage(
"/history?status=completed&role=creator&search=taxi&sort=amount-desc&page=2",
);
await waitFor(() =>
expect(repositoryMocks.fetchHistory).toHaveBeenCalledWith({
statuses: ["completed"],
role: "creator",
search: "taxi",
sort: "amount-desc",
page: 2,
limit: 20,
}),
);
expect(screen.getByLabelText("Search")).toHaveValue("taxi");
expect(screen.getByLabelText("Role")).toHaveValue("creator");
expect(screen.getByLabelText("Sort")).toHaveValue("amount-desc");
});
it("writes filter changes to the URL, resets the page, and restores state on Back", async () => {
renderPage("/history?role=creator&page=2", true);
await waitFor(() => expect(repositoryMocks.fetchHistory).toHaveBeenCalledTimes(1));
fireEvent.change(screen.getByLabelText("Role"), {
target: { value: "participant" },
});
await waitFor(() => {
expect(screen.getByTestId("location")).toHaveTextContent("role=participant");
expect(screen.getByTestId("location")).not.toHaveTextContent("page=");
});
expect(repositoryMocks.fetchHistory).toHaveBeenLastCalledWith(
expect.objectContaining({ role: "participant", page: 1 }),
);
fireEvent.click(screen.getByRole("button", { name: "Back" }));
await waitFor(() => {
expect(screen.getByLabelText("Role")).toHaveValue("creator");
expect(screen.getByTestId("location")).toHaveTextContent(
"role=creator&page=2",
);
});
expect(repositoryMocks.fetchHistory).toHaveBeenLastCalledWith(
expect.objectContaining({ role: "creator", page: 2 }),
);
});
it("updates the page query parameter and fetches the next page", async () => {
repositoryMocks.fetchHistory.mockResolvedValue({
...emptyResponse,
meta: {
...emptyResponse.meta,
totalItems: 21,
totalPages: 2,
hasMore: true,
},
});
renderPage("/history");
await waitFor(() => expect(repositoryMocks.fetchHistory).toHaveBeenCalledTimes(1));
fireEvent.click(screen.getByRole("button", { name: "Next" }));
await waitFor(() =>
expect(screen.getByTestId("location")).toHaveTextContent("?page=2"),
);
expect(repositoryMocks.fetchHistory).toHaveBeenLastCalledWith(
expect.objectContaining({ page: 2, limit: 20 }),
);
});
it("shows the translated empty state when the API returns no rows", async () => {
renderPage("/history");
expect(await screen.findByText("No splits found")).toBeInTheDocument();
});
it("shows an API error instead of substituting fixture history", async () => {
repositoryMocks.fetchHistory.mockRejectedValueOnce(
new Error("Unable to load history"),
);
renderPage("/history");
expect(await screen.findByRole("alert")).toHaveTextContent(
"Unable to load history",
);
expect(screen.queryByText("No splits found")).not.toBeInTheDocument();
});
});
function renderPage(initialEntry: string, includeBackButton = false) {
return render(
<MemoryRouter initialEntries={[initialEntry]}>
{includeBackButton ? <BackButton /> : null}
<SplitHistoryPage />
<LocationProbe />
</MemoryRouter>,
);
}
function BackButton() {
const navigate = useNavigate();
return <button onClick={() => navigate(-1)}>Back</button>;
}
function LocationProbe() {
const location = useLocation();
return <output data-testid="location">{location.search}</output>;
}