Files
SkyMoney/api/tests/setup.ts
Ricearoni1245 15e0c0a88a
Some checks failed
Deploy / deploy (push) Successful in 1m28s
Security Tests / security-non-db (push) Failing after 18s
Security Tests / security-db (push) Failing after 22s
feat: implement forgot password, added security updates
2026-03-01 21:47:15 -06:00

85 lines
3.2 KiB
TypeScript

import { execSync } from "node:child_process";
import { readFileSync, existsSync } from "node:fs";
import { resolve } from "node:path";
import { beforeAll, afterAll } from "vitest";
import { PrismaClient } from "@prisma/client";
function readEnvValue(filePath: string, key: string): string | undefined {
if (!existsSync(filePath)) return undefined;
const content = readFileSync(filePath, "utf8");
const line = content
.split(/\r?\n/)
.find((raw) => raw.trim().startsWith(`${key}=`));
if (!line) return undefined;
const value = line.slice(line.indexOf("=") + 1).trim();
return value.length > 0 ? value : undefined;
}
function resolveDatabaseUrl(): string {
if (process.env.TEST_DATABASE_URL?.trim()) return process.env.TEST_DATABASE_URL.trim();
if (process.env.BACKUP_DATABASE_URL?.trim()) return process.env.BACKUP_DATABASE_URL.trim();
if (process.env.DATABASE_URL?.trim()) return process.env.DATABASE_URL.trim();
const envPaths = [resolve(process.cwd(), ".env"), resolve(process.cwd(), "..", ".env")];
for (const envPath of envPaths) {
const testUrl = readEnvValue(envPath, "TEST_DATABASE_URL");
if (testUrl) return testUrl;
const backupUrl = readEnvValue(envPath, "BACKUP_DATABASE_URL");
if (backupUrl) return backupUrl;
const dbUrl = readEnvValue(envPath, "DATABASE_URL");
if (dbUrl) return dbUrl.replace("@postgres:", "@127.0.0.1:");
}
return "postgres://app:app@127.0.0.1:5432/skymoney";
}
process.env.NODE_ENV = process.env.NODE_ENV || "test";
process.env.DATABASE_URL = resolveDatabaseUrl();
process.env.PORT = process.env.PORT || "8081";
process.env.HOST ??= "127.0.0.1";
process.env.CORS_ORIGIN = process.env.CORS_ORIGIN || "";
process.env.AUTH_DISABLED = process.env.AUTH_DISABLED || "1";
process.env.SEED_DEFAULT_BUDGET = process.env.SEED_DEFAULT_BUDGET || "1";
process.env.JWT_SECRET =
process.env.JWT_SECRET || "test-jwt-secret-32-chars-min-abcdef";
process.env.COOKIE_SECRET =
process.env.COOKIE_SECRET || "test-cookie-secret-32-chars-abcdef";
export const prisma = new PrismaClient();
// hard reset for a single user
export async function resetUser(userId: string) {
await prisma.allocation.deleteMany({ where: { userId } });
await prisma.transaction.deleteMany({ where: { userId } });
await prisma.incomeEvent.deleteMany({ where: { userId } });
await prisma.fixedPlan.deleteMany({ where: { userId } });
await prisma.variableCategory.deleteMany({ where: { userId } });
await prisma.user.deleteMany({ where: { id: userId } });
}
beforeAll(async () => {
// Optional schema bootstrap for CI/local environments that can run Prisma CLI.
if (process.env.TEST_APPLY_SCHEMA === "1") {
try {
execSync("npx prisma migrate deploy", { stdio: "inherit" });
} catch {
execSync("npx prisma db push --skip-generate --accept-data-loss", { stdio: "inherit" });
}
}
// Ensure a clean slate: wipe all tables to avoid cross-file leakage
await prisma.$transaction([
prisma.emailToken.deleteMany({}),
prisma.allocation.deleteMany({}),
prisma.transaction.deleteMany({}),
prisma.incomeEvent.deleteMany({}),
prisma.fixedPlan.deleteMany({}),
prisma.variableCategory.deleteMany({}),
prisma.user.deleteMany({}),
]);
});
afterAll(async () => {
await prisma.$disconnect();
});