Skip to content

Commit c5f2f68

Browse files
Xaohssvenvandescheur
authored andcommitted
✅ test: login action test
1 parent ec09890 commit c5f2f68

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { beforeEach, describe, expect, it, vi } from "vitest";
2+
import { login } from "~/api/auth.ts";
3+
import { loginAction } from "~/pages";
4+
5+
vi.mock("~/api/auth.ts", () => ({
6+
login: vi.fn(),
7+
}));
8+
9+
vi.mock("react-router", async () => {
10+
const actual = await vi.importActual("react-router");
11+
return {
12+
...actual,
13+
redirect: vi.fn((path: string) => ({ type: "redirect", location: path })),
14+
};
15+
});
16+
17+
describe("loginAction", () => {
18+
const mockFormData = new FormData();
19+
const mockRequest = (url = "http://localhost/login") =>
20+
new Request(url, {
21+
method: "POST",
22+
body: mockFormData,
23+
});
24+
25+
beforeEach(() => {
26+
mockFormData.set("username", "testuser");
27+
mockFormData.set("password", "testpass");
28+
vi.clearAllMocks();
29+
});
30+
31+
it("calls login with correct arguments", async () => {
32+
(login as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce({});
33+
34+
await loginAction({ request: mockRequest(), params: {}, context: {} });
35+
36+
expect(login).toHaveBeenCalledWith(
37+
"testuser",
38+
"testpass",
39+
expect.any(AbortSignal),
40+
);
41+
});
42+
43+
it("redirects to '/' by default after successful login", async () => {
44+
(login as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce({});
45+
46+
const result = await loginAction({
47+
request: mockRequest(),
48+
params: {},
49+
context: {},
50+
});
51+
52+
expect(result).toEqual({ type: "redirect", location: "/" });
53+
});
54+
55+
it("redirects to 'next' query param if present", async () => {
56+
(login as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce({});
57+
58+
const result = await loginAction({
59+
request: mockRequest("http://localhost/login?next=/dashboard"),
60+
params: {},
61+
context: {},
62+
});
63+
64+
expect(result).toEqual({ type: "redirect", location: "/dashboard" });
65+
});
66+
67+
it("returns error JSON if login fails", async () => {
68+
const mockErrorResponse = new Response(
69+
JSON.stringify({ error: "Invalid credentials" }),
70+
{
71+
status: 401,
72+
headers: { "Content-Type": "application/json" },
73+
},
74+
);
75+
76+
(login as unknown as ReturnType<typeof vi.fn>).mockImplementationOnce(
77+
() => {
78+
throw mockErrorResponse;
79+
},
80+
);
81+
82+
const result = await loginAction({
83+
request: mockRequest(),
84+
params: {},
85+
context: {},
86+
});
87+
88+
expect(result).toEqual({ error: "Invalid credentials" });
89+
});
90+
});

0 commit comments

Comments
 (0)