Spaces:
Running
Running
File size: 3,234 Bytes
00443a6 |
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 |
import { beforeEach, describe, expect, it, vi } from "vitest";
let mockArgon2VerifyResult = true;
let mockIsVerifiedToken = false;
let mockRateLimiterShouldFail = false;
const mockAddVerifiedToken = vi.fn();
const mockConsume = vi.fn();
vi.mock("hash-wasm", () => ({
argon2Verify: vi.fn(() => Promise.resolve(mockArgon2VerifyResult)),
}));
vi.mock("rate-limiter-flexible", () => ({
RateLimiterMemory: class {
consume = vi.fn((token: string) => {
mockConsume(token);
if (mockRateLimiterShouldFail) {
return Promise.reject(new Error("Rate limit exceeded"));
}
return Promise.resolve(undefined);
});
},
}));
vi.mock("./searchToken", () => ({
getSearchToken: vi.fn().mockReturnValue("dummy-token"),
}));
vi.mock("./verifiedTokens", () => ({
addVerifiedToken: vi.fn((token: string) => mockAddVerifiedToken(token)),
isVerifiedToken: vi.fn(() => mockIsVerifiedToken),
}));
describe("verifyTokenAndRateLimit", () => {
beforeEach(() => {
vi.clearAllMocks();
mockArgon2VerifyResult = true;
mockIsVerifiedToken = false;
mockRateLimiterShouldFail = false;
});
it("should reject missing token", async () => {
const { verifyTokenAndRateLimit } = await import(
"./verifyTokenAndRateLimit"
);
const result = await verifyTokenAndRateLimit(null);
expect(result.isAuthorized).toBe(false);
expect(result.statusCode).toBe(400);
expect(result.error).toBe("Missing token.");
});
it("should reject invalid token", async () => {
mockArgon2VerifyResult = false;
vi.resetModules();
const { verifyTokenAndRateLimit } = await import(
"./verifyTokenAndRateLimit"
);
const result = await verifyTokenAndRateLimit("invalid-token");
expect(result.isAuthorized).toBe(false);
expect(result.statusCode).toBe(401);
expect(result.error).toBe("Invalid token.");
});
it("should accept valid token and add to verified tokens", async () => {
mockArgon2VerifyResult = true;
vi.resetModules();
const { verifyTokenAndRateLimit } = await import(
"./verifyTokenAndRateLimit"
);
const result = await verifyTokenAndRateLimit("valid-token");
expect(result.isAuthorized).toBe(true);
expect(result).not.toHaveProperty("statusCode");
expect(mockAddVerifiedToken).toHaveBeenCalledWith("valid-token");
});
it("should skip verification for already verified tokens", async () => {
mockIsVerifiedToken = true;
vi.resetModules();
const { verifyTokenAndRateLimit } = await import(
"./verifyTokenAndRateLimit"
);
const hashWasm = await import("hash-wasm");
const result = await verifyTokenAndRateLimit("already-verified-token");
expect(result.isAuthorized).toBe(true);
expect(hashWasm.argon2Verify).not.toHaveBeenCalled();
});
it("should enforce rate limiting", async () => {
mockRateLimiterShouldFail = true;
vi.resetModules();
const { verifyTokenAndRateLimit } = await import(
"./verifyTokenAndRateLimit"
);
const result = await verifyTokenAndRateLimit("rate-limit-token");
expect(result.isAuthorized).toBe(false);
expect(result.statusCode).toBe(429);
expect(result.error).toBe("Too many requests.");
});
});
|