-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproxy.test.ts
More file actions
84 lines (65 loc) · 2.83 KB
/
Copy pathproxy.test.ts
File metadata and controls
84 lines (65 loc) · 2.83 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
import { beforeEach, describe, expect, it, vi } from "vitest";
import { NextRequest } from "next/server";
const { mockAuth } = vi.hoisted(() => ({
mockAuth: vi.fn(),
}));
vi.mock("@/lib/auth", () => ({
auth: mockAuth,
}));
import { proxy, shouldAllowMarketingRoute, shouldBypassProxy } from "./proxy";
describe("shouldBypassProxy", () => {
it("skips next internals and api routes", () => {
expect(shouldBypassProxy("/_next/webpack-hmr")).toBe(true);
expect(shouldBypassProxy("/api/ready")).toBe(true);
});
it("keeps application routes protected", () => {
expect(shouldBypassProxy("/dashboard")).toBe(false);
});
});
describe("proxy", () => {
beforeEach(() => {
vi.clearAllMocks();
vi.unstubAllEnvs();
});
it("redirects unauthenticated users on protected routes", async () => {
mockAuth.mockResolvedValue(null);
const response = await proxy(new NextRequest("http://localhost:3000/dashboard?q=react"));
expect(response.headers.get("location")).toBe(
"http://localhost:3000/sign-in?callbackUrl=%2Fdashboard%3Fq%3Dreact"
);
});
it("redirects authenticated users away from sign-in", async () => {
mockAuth.mockResolvedValue({ user: { id: "user-1" } });
const response = await proxy(new NextRequest("http://localhost:3000/sign-in?callbackUrl=https://evil.example/steal"));
expect(response.headers.get("location")).toBe("http://localhost:3000/dashboard");
});
it("redirects application routes to installation docs in marketing mode", async () => {
vi.stubEnv("NEXT_PUBLIC_DEPLOYMENT_MODE", "marketing");
const response = await proxy(new NextRequest("http://localhost:3000/dashboard"));
expect(response.headers.get("location")).toBe(
"http://localhost:3000/docs/getting-started/installation"
);
expect(mockAuth).not.toHaveBeenCalled();
});
it("does not expose application APIs in marketing mode", async () => {
vi.stubEnv("NEXT_PUBLIC_DEPLOYMENT_MODE", "marketing");
const response = await proxy(new NextRequest("http://localhost:3000/api/v1/snippets"));
expect(response.status).toBe(404);
await expect(response.json()).resolves.toMatchObject({
error: { code: "not_available" },
ok: false,
});
expect(mockAuth).not.toHaveBeenCalled();
});
});
describe("shouldAllowMarketingRoute", () => {
it("allows only the public site, docs, assets, and health check", () => {
expect(shouldAllowMarketingRoute("/")).toBe(true);
expect(shouldAllowMarketingRoute("/docs/getting-started")).toBe(true);
expect(shouldAllowMarketingRoute("/_next/static/app.js")).toBe(true);
expect(shouldAllowMarketingRoute("/api/health")).toBe(true);
expect(shouldAllowMarketingRoute("/sign-in")).toBe(false);
expect(shouldAllowMarketingRoute("/setup")).toBe(false);
expect(shouldAllowMarketingRoute("/api/v1/snippets")).toBe(false);
});
});