test: add comprehensive automated test coverage
- Vitest multi-project setup (unit / integration / component) - Real-Postgres integration harness via in-process PGlite (TEST_DATABASE_URL override), migrations applied per worker; production code untouched - Unit: routing, locale, validation/Zod schemas, metadata, mail, site-theme, marquee, media, portfolio helpers, plus architecture-rule tests - Integration: Prisma data layer, API routes, and all server actions - Component: UI primitives and form components (jsdom + Testing Library) - 371 tests passing
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("next/headers", () => ({
|
||||
headers: async () => new Headers({ "x-forwarded-for": "203.0.113.7" }),
|
||||
cookies: async () => ({ get: () => undefined, set: () => {}, delete: () => {} }),
|
||||
}));
|
||||
|
||||
import {
|
||||
getAdminLockState,
|
||||
isAdminAuthConfigured,
|
||||
isPasswordValid,
|
||||
registerFailedAdminAttempt,
|
||||
resetAdminFailedAttempts,
|
||||
} from "@/lib/admin-auth";
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
describe("admin auth configuration", () => {
|
||||
it("is configured only when both password and secret are set", () => {
|
||||
vi.stubEnv("ADMIN_PASSWORD", "");
|
||||
vi.stubEnv("ADMIN_AUTH_SECRET", "");
|
||||
expect(isAdminAuthConfigured()).toBe(false);
|
||||
|
||||
vi.stubEnv("ADMIN_PASSWORD", "pw");
|
||||
vi.stubEnv("ADMIN_AUTH_SECRET", "");
|
||||
expect(isAdminAuthConfigured()).toBe(false);
|
||||
|
||||
vi.stubEnv("ADMIN_PASSWORD", "pw");
|
||||
vi.stubEnv("ADMIN_AUTH_SECRET", "secret");
|
||||
expect(isAdminAuthConfigured()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isPasswordValid", () => {
|
||||
it("returns false when auth is not configured", () => {
|
||||
vi.stubEnv("ADMIN_PASSWORD", "");
|
||||
vi.stubEnv("ADMIN_AUTH_SECRET", "");
|
||||
expect(isPasswordValid("anything")).toBe(false);
|
||||
});
|
||||
|
||||
it("accepts the correct password and rejects wrong ones", () => {
|
||||
vi.stubEnv("ADMIN_PASSWORD", "s3cret-password");
|
||||
vi.stubEnv("ADMIN_AUTH_SECRET", "hmac-secret");
|
||||
expect(isPasswordValid("s3cret-password")).toBe(true);
|
||||
expect(isPasswordValid("wrong")).toBe(false);
|
||||
expect(isPasswordValid("s3cret-passwordX")).toBe(false); // length mismatch
|
||||
});
|
||||
});
|
||||
|
||||
describe("login lockout", () => {
|
||||
it("locks the IP after the failed-attempt threshold", async () => {
|
||||
expect((await getAdminLockState()).locked).toBe(false);
|
||||
|
||||
for (let i = 0; i < 4; i += 1) {
|
||||
const state = await registerFailedAdminAttempt();
|
||||
expect(state.locked).toBe(false);
|
||||
}
|
||||
expect((await getAdminLockState()).locked).toBe(false);
|
||||
|
||||
const fifth = await registerFailedAdminAttempt();
|
||||
expect(fifth.locked).toBe(true);
|
||||
expect(fifth.remainingSeconds).toBeGreaterThan(0);
|
||||
|
||||
const lockState = await getAdminLockState();
|
||||
expect(lockState.locked).toBe(true);
|
||||
expect(lockState.remainingSeconds).toBeGreaterThan(0);
|
||||
expect(lockState.remainingSeconds).toBeLessThanOrEqual(15 * 60);
|
||||
});
|
||||
|
||||
it("clears the lock on reset", async () => {
|
||||
for (let i = 0; i < 5; i += 1) {
|
||||
await registerFailedAdminAttempt();
|
||||
}
|
||||
expect((await getAdminLockState()).locked).toBe(true);
|
||||
|
||||
await resetAdminFailedAttempts();
|
||||
expect((await getAdminLockState()).locked).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user