forked from Dshield-xyz/Dshield
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathroute.test.ts
More file actions
64 lines (56 loc) · 2.52 KB
/
Copy pathroute.test.ts
File metadata and controls
64 lines (56 loc) · 2.52 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
import { describe, it, expect, vi } from "vitest";
const VALID_G = "GABZWK2YLPOGBEOZT6VOCID6ROSSZGPSLAEPCTWIBGAJDHISO6DFKYYZ";
// The route reads USDC_ISSUER_SECRET at module load, so reload per scenario.
async function loadRoute(secret?: string) {
vi.resetModules();
if (secret === undefined) delete process.env.USDC_ISSUER_SECRET;
else process.env.USDC_ISSUER_SECRET = secret;
process.env.NEXT_PUBLIC_NETWORK_PASSPHRASE = "Standalone Network ; February 2017";
process.env.NEXT_PUBLIC_USDC_CODE = "USDC";
return (await import("./route")).POST;
}
// Minimal NextRequest stand-in — the handler calls req.json() and
// req.headers.get(...) (for rate-limit keying).
const req = (body: unknown, ip = "1.2.3.4") =>
({
json: async () => body,
headers: { get: (k: string) => (k.toLowerCase() === "x-forwarded-for" ? ip : null) },
}) as never;
describe("/api/faucet validation", () => {
it("503 when the issuer secret is not configured", async () => {
const POST = await loadRoute(undefined);
const res = await POST(req({ address: VALID_G, amount: "1" }));
expect(res.status).toBe(503);
});
it("400 on an invalid recipient address", async () => {
const POST = await loadRoute("Sxxx-dummy-secret");
const res = await POST(req({ address: "not-an-address", amount: "1" }));
expect(res.status).toBe(400);
});
it("400 on a non-positive amount", async () => {
const POST = await loadRoute("Sxxx-dummy-secret");
const res = await POST(req({ address: VALID_G, amount: "0" }));
expect(res.status).toBe(400);
});
});
describe("/api/faucet rate limiting", () => {
it("429s a single IP after 5 requests within the window", async () => {
const POST = await loadRoute("Sxxx-dummy-secret");
// Each of these fails with 400 (invalid address, deliberately, to avoid
// needing a real RPC), but the rate limiter counts the attempt regardless.
for (let i = 0; i < 5; i++) {
const res = await POST(req({ address: "not-an-address", amount: "1" }, "9.9.9.9"));
expect(res.status).toBe(400);
}
const sixth = await POST(req({ address: "not-an-address", amount: "1" }, "9.9.9.9"));
expect(sixth.status).toBe(429);
});
it("does not rate-limit a different IP", async () => {
const POST = await loadRoute("Sxxx-dummy-secret");
for (let i = 0; i < 5; i++) {
await POST(req({ address: "not-an-address", amount: "1" }, "8.8.8.8"));
}
const res = await POST(req({ address: "not-an-address", amount: "1" }, "7.7.7.7"));
expect(res.status).toBe(400); // not 429
});
});