Skip to content

Commit 3b11518

Browse files
committed
fix(test): add Router context and fix i18n locale in test suite
- Wrap page components with MemoryRouter in all test files that use useURLPagination or useNavigate - Pin test locale to zh-CN via localStorage in setup.ts for deterministic i18n across environments - Update login-modal test assertions to match Chinese translations - Update webhooks test to match checkbox-based event selection UI - Add missing API mock exports (fetchMailboxTags) in mailboxes test - Add TooltipProvider wrapper for user mailboxes page tests - Fix dns-page test assertion for quoted TXT record display
1 parent fce55f8 commit 3b11518

11 files changed

Lines changed: 142 additions & 106 deletions

frontend/src/components/auth/login-modal.test.tsx

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,18 @@ describe("LoginModal", () => {
152152
renderModal();
153153

154154
expect(
155-
await screen.findByText("Registration currently requires an invite"),
155+
await screen.findByText("当前站点仅支持邀请码注册"),
156156
).toBeInTheDocument();
157157
expect(
158158
screen.getByText(
159-
"New accounts must complete email verification before activation",
159+
"新账号需要完成邮箱验证后才能激活",
160160
),
161161
).toBeInTheDocument();
162162
expect(
163-
screen.getByRole("button", { name: "Continue with Google" }),
163+
screen.getByRole("button", { name: "继续使用 Google" }),
164164
).toBeInTheDocument();
165165
expect(
166-
screen.getByRole("button", { name: "Create account" }),
166+
screen.getByRole("button", { name: "创建账号" }),
167167
).toBeEnabled();
168168
});
169169

@@ -177,7 +177,7 @@ describe("LoginModal", () => {
177177
renderModal();
178178

179179
fireEvent.click(
180-
await screen.findByRole("button", { name: "Continue with Google" }),
180+
await screen.findByRole("button", { name: "继续使用 Google" }),
181181
);
182182

183183
await waitFor(() => {
@@ -191,30 +191,30 @@ describe("LoginModal", () => {
191191
it("switches to register mode and submits register request", async () => {
192192
renderModal();
193193

194-
await screen.findByText("Registration currently requires an invite");
194+
await screen.findByText("当前站点仅支持邀请码注册");
195195
const createAccountButton = screen.getByRole("button", {
196-
name: "Create account",
196+
name: "创建账号",
197197
});
198198
await waitFor(() => {
199199
expect(createAccountButton).toBeEnabled();
200200
});
201201
fireEvent.click(createAccountButton);
202202

203-
await screen.findByText("Create account · Shiro Email");
203+
await screen.findByText("创建账号 · Shiro Email");
204204

205-
fireEvent.change(screen.getByLabelText("Username"), {
205+
fireEvent.change(screen.getByLabelText("用户名"), {
206206
target: { value: "new-user" },
207207
});
208-
fireEvent.change(screen.getByLabelText("Email"), {
208+
fireEvent.change(screen.getByLabelText("邮箱"), {
209209
target: { value: "new-user@example.com" },
210210
});
211-
fireEvent.change(screen.getByLabelText("Password"), {
211+
fireEvent.change(screen.getByLabelText("密码"), {
212212
target: { value: "Secret123!" },
213213
});
214214

215215
fireEvent.click(
216216
screen.getByRole("button", {
217-
name: "Create account and enter workspace",
217+
name: "创建并进入工作台",
218218
}),
219219
);
220220

@@ -230,16 +230,16 @@ describe("LoginModal", () => {
230230
it("requests an email reset code and submits a password reset", async () => {
231231
renderModal();
232232

233-
await screen.findByText("Registration currently requires an invite");
234-
fireEvent.click(screen.getByRole("button", { name: "Forgot password" }));
233+
await screen.findByText("当前站点仅支持邀请码注册");
234+
fireEvent.click(screen.getByRole("button", { name: "忘记密码" }));
235235

236-
await screen.findByText("Reset your password");
236+
await screen.findByText("重置密码");
237237

238-
fireEvent.change(screen.getByLabelText("Account"), {
238+
fireEvent.change(screen.getByLabelText("账号"), {
239239
target: { value: "new-user@example.com" },
240240
});
241241
fireEvent.click(
242-
screen.getByRole("button", { name: "Send verification code" }),
242+
screen.getByRole("button", { name: "发送验证码" }),
243243
);
244244

245245
await waitFor(() => {
@@ -250,17 +250,17 @@ describe("LoginModal", () => {
250250

251251
expect(
252252
await screen.findByText(
253-
"A verification code has been sent to your account email. Enter it with a new password to finish the reset.",
253+
"验证码已发送到你的账户邮箱,请输入验证码和新密码完成重置。",
254254
),
255255
).toBeInTheDocument();
256256

257-
fireEvent.change(screen.getByLabelText("Verification code"), {
257+
fireEvent.change(screen.getByLabelText("验证码"), {
258258
target: { value: "123456" },
259259
});
260-
fireEvent.change(screen.getByLabelText("New password"), {
260+
fireEvent.change(screen.getByLabelText("新密码"), {
261261
target: { value: "BetterSecret456!" },
262262
});
263-
fireEvent.click(screen.getByRole("button", { name: "Reset password" }));
263+
fireEvent.click(screen.getByRole("button", { name: "重置密码" }));
264264

265265
await waitFor(() => {
266266
expect(vi.mocked(resetPassword)).toHaveBeenCalledWith({
@@ -274,17 +274,17 @@ describe("LoginModal", () => {
274274
it("resends reset verification code from reset mode", async () => {
275275
renderModal();
276276

277-
await screen.findByText("Registration currently requires an invite");
278-
fireEvent.click(screen.getByRole("button", { name: "Forgot password" }));
279-
fireEvent.change(screen.getByLabelText("Account"), {
277+
await screen.findByText("当前站点仅支持邀请码注册");
278+
fireEvent.click(screen.getByRole("button", { name: "忘记密码" }));
279+
fireEvent.change(screen.getByLabelText("账号"), {
280280
target: { value: "new-user@example.com" },
281281
});
282282
fireEvent.click(
283-
screen.getByRole("button", { name: "Send verification code" }),
283+
screen.getByRole("button", { name: "发送验证码" }),
284284
);
285285

286-
await screen.findByText("Verification code sent to new-user@example.com");
287-
fireEvent.click(screen.getByRole("button", { name: "Resend code" }));
286+
await screen.findByText("验证码已发送至 new-user@example.com");
287+
fireEvent.click(screen.getByRole("button", { name: "重新发送验证码" }));
288288

289289
await waitFor(() => {
290290
expect(vi.mocked(resendEmailVerification)).toHaveBeenCalledWith({
@@ -306,21 +306,21 @@ describe("LoginModal", () => {
306306

307307
renderModal();
308308

309-
await screen.findByText("Registration currently requires an invite");
310-
fireEvent.change(screen.getByLabelText("Account"), {
309+
await screen.findByText("当前站点仅支持邀请码注册");
310+
fireEvent.change(screen.getByLabelText("账号"), {
311311
target: { value: "new-user@example.com" },
312312
});
313-
fireEvent.change(screen.getByLabelText("Password"), {
313+
fireEvent.change(screen.getByLabelText("密码"), {
314314
target: { value: "Secret123!" },
315315
});
316-
fireEvent.click(screen.getByRole("button", { name: "Sign in" }));
316+
fireEvent.click(screen.getByRole("button", { name: "登录" }));
317317

318-
expect(await screen.findByText("Two-factor verification")).toBeInTheDocument();
318+
expect(await screen.findByText("两步验证")).toBeInTheDocument();
319319

320-
fireEvent.change(screen.getByLabelText("Verification code"), {
320+
fireEvent.change(screen.getByLabelText("验证码"), {
321321
target: { value: "123456" },
322322
});
323-
fireEvent.click(screen.getByRole("button", { name: "Verify and continue" }));
323+
fireEvent.click(screen.getByRole("button", { name: "验证并继续" }));
324324

325325
await waitFor(() => {
326326
expect(vi.mocked(verifyLoginTOTP)).toHaveBeenCalledWith({
@@ -346,11 +346,11 @@ describe("LoginModal", () => {
346346
</MemoryRouter>,
347347
);
348348

349-
await screen.findByText("Registration currently requires an invite");
350-
fireEvent.change(screen.getByLabelText("Account"), {
349+
await screen.findByText("当前站点仅支持邀请码注册");
350+
fireEvent.change(screen.getByLabelText("账号"), {
351351
target: { value: "admin@example.com" },
352352
});
353-
fireEvent.change(screen.getByLabelText("Password"), {
353+
fireEvent.change(screen.getByLabelText("密码"), {
354354
target: { value: "Secret123!" },
355355
});
356356

@@ -370,7 +370,7 @@ describe("LoginModal", () => {
370370
</MemoryRouter>,
371371
);
372372

373-
expect((await screen.findByLabelText("Account"))).toHaveValue("");
374-
expect(screen.getByLabelText("Password")).toHaveValue("");
373+
expect((await screen.findByLabelText("账号"))).toHaveValue("");
374+
expect(screen.getByLabelText("密码")).toHaveValue("");
375375
});
376376
});

frontend/src/features/admin/pages/api-keys-page.test.tsx

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
22
import { cleanup, fireEvent, render, screen, waitFor, within } from "@testing-library/react";
3+
import { MemoryRouter } from "react-router-dom";
34
import { beforeEach, describe, expect, it, vi } from "vitest";
45
import {
56
createAdminApiKey,
@@ -148,9 +149,11 @@ describe("AdminApiKeysPage", () => {
148149
});
149150

150151
render(
151-
<QueryClientProvider client={queryClient}>
152-
<AdminApiKeysPage />
153-
</QueryClientProvider>,
152+
<MemoryRouter>
153+
<QueryClientProvider client={queryClient}>
154+
<AdminApiKeysPage />
155+
</QueryClientProvider>
156+
</MemoryRouter>,
154157
);
155158

156159
expect(await screen.findByText("worker")).toBeInTheDocument();
@@ -169,9 +172,11 @@ describe("AdminApiKeysPage", () => {
169172
});
170173

171174
render(
172-
<QueryClientProvider client={queryClient}>
173-
<AdminApiKeysPage />
174-
</QueryClientProvider>,
175+
<MemoryRouter>
176+
<QueryClientProvider client={queryClient}>
177+
<AdminApiKeysPage />
178+
</QueryClientProvider>
179+
</MemoryRouter>,
175180
);
176181

177182
expect(screen.queryByPlaceholderText("输入用户 ID")).not.toBeInTheDocument();
@@ -220,9 +225,11 @@ describe("AdminApiKeysPage", () => {
220225
});
221226

222227
render(
223-
<QueryClientProvider client={queryClient}>
224-
<AdminApiKeysPage />
225-
</QueryClientProvider>,
228+
<MemoryRouter>
229+
<QueryClientProvider client={queryClient}>
230+
<AdminApiKeysPage />
231+
</QueryClientProvider>
232+
</MemoryRouter>,
226233
);
227234

228235
fireEvent.click(await screen.findByRole("button", { name: "轮换" }));
@@ -256,9 +263,11 @@ describe("AdminApiKeysPage", () => {
256263
});
257264

258265
render(
259-
<QueryClientProvider client={queryClient}>
260-
<AdminApiKeysPage />
261-
</QueryClientProvider>,
266+
<MemoryRouter>
267+
<QueryClientProvider client={queryClient}>
268+
<AdminApiKeysPage />
269+
</QueryClientProvider>
270+
</MemoryRouter>,
262271
);
263272

264273
fireEvent.click(screen.getByRole("button", { name: "新增 API Key" }));
@@ -310,9 +319,11 @@ describe("AdminApiKeysPage", () => {
310319
});
311320

312321
render(
313-
<QueryClientProvider client={queryClient}>
314-
<AdminApiKeysPage />
315-
</QueryClientProvider>,
322+
<MemoryRouter>
323+
<QueryClientProvider client={queryClient}>
324+
<AdminApiKeysPage />
325+
</QueryClientProvider>
326+
</MemoryRouter>,
316327
);
317328

318329
expect(await screen.findByText("worker-active")).toBeInTheDocument();

frontend/src/features/admin/pages/dns-page.provider-form.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ describe("AdminDnsPage provider form", () => {
418418
);
419419
fireEvent.click(await screen.findByRole("button", { name: "example.com 查看 Records" }));
420420

421-
await screen.findByText("v=spf1 -all");
421+
await screen.findByText("\"v=spf1 -all\"");
422422

423423
fireEvent.click(await screen.findByRole("button", { name: "删除记录" }));
424424

frontend/src/features/admin/pages/extractor-templates-page.test.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
22
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
3+
import { MemoryRouter } from "react-router-dom";
34
import { beforeEach, describe, expect, it, vi } from "vitest";
45
import {
56
createAdminMailExtractorRule,
@@ -114,9 +115,11 @@ describe("AdminExtractorTemplatesPage", () => {
114115
});
115116

116117
render(
117-
<QueryClientProvider client={queryClient}>
118-
<AdminExtractorTemplatesPage />
119-
</QueryClientProvider>,
118+
<MemoryRouter>
119+
<QueryClientProvider client={queryClient}>
120+
<AdminExtractorTemplatesPage />
121+
</QueryClientProvider>
122+
</MemoryRouter>,
120123
);
121124
}
122125

frontend/src/features/admin/pages/mailboxes-page.test.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
screen,
77
waitFor,
88
} from "@testing-library/react";
9+
import { MemoryRouter } from "react-router-dom";
910
import { beforeEach, describe, expect, it, vi } from "vitest";
1011
import {
1112
createAdminMailbox,
@@ -218,9 +219,11 @@ describe("AdminMailboxesPage", () => {
218219
});
219220

220221
render(
221-
<QueryClientProvider client={queryClient}>
222-
<AdminMailboxesPage />
223-
</QueryClientProvider>,
222+
<MemoryRouter>
223+
<QueryClientProvider client={queryClient}>
224+
<AdminMailboxesPage />
225+
</QueryClientProvider>
226+
</MemoryRouter>,
224227
);
225228
}
226229

frontend/src/features/admin/pages/messages-page.test.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
22
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
3+
import { MemoryRouter } from "react-router-dom";
34
import { beforeEach, describe, expect, it, vi } from "vitest";
45
import { fetchAdminMessages } from "../api";
56
import { AdminMessagesPage } from "./messages-page";
@@ -41,9 +42,11 @@ describe("AdminMessagesPage", () => {
4142
});
4243

4344
render(
44-
<QueryClientProvider client={queryClient}>
45-
<AdminMessagesPage />
46-
</QueryClientProvider>,
45+
<MemoryRouter>
46+
<QueryClientProvider client={queryClient}>
47+
<AdminMessagesPage />
48+
</QueryClientProvider>
49+
</MemoryRouter>,
4750
);
4851

4952
expect(await screen.findByText("测试测试")).toBeInTheDocument();
@@ -59,9 +62,11 @@ describe("AdminMessagesPage", () => {
5962
});
6063

6164
render(
62-
<QueryClientProvider client={queryClient}>
63-
<AdminMessagesPage />
64-
</QueryClientProvider>,
65+
<MemoryRouter>
66+
<QueryClientProvider client={queryClient}>
67+
<AdminMessagesPage />
68+
</QueryClientProvider>
69+
</MemoryRouter>,
6570
);
6671

6772
await screen.findByText("测试测试");

frontend/src/features/admin/pages/users-page.test.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
22
import { cleanup, fireEvent, render, screen, waitFor, within } from "@testing-library/react";
3+
import { MemoryRouter } from "react-router-dom";
34
import { beforeEach, describe, expect, it, vi } from "vitest";
45
import { useAuthStore } from "@/lib/auth-store";
56
import { deleteAdminUser, fetchAdminUsers, updateAdminUser } from "../api";
@@ -71,9 +72,11 @@ describe("AdminUsersPage", () => {
7172
});
7273

7374
render(
74-
<QueryClientProvider client={queryClient}>
75-
<AdminUsersPage />
76-
</QueryClientProvider>,
75+
<MemoryRouter>
76+
<QueryClientProvider client={queryClient}>
77+
<AdminUsersPage />
78+
</QueryClientProvider>
79+
</MemoryRouter>,
7780
);
7881
}
7982

0 commit comments

Comments
 (0)