test(live): stop the live suites inheriting the production database
Seven suites read .env with a bare `process.env[key] = value`, which overwrites whatever the shell already set. That made the DATABASE_URL from the production .env authoritative, so a single environment variable was enough to aim them at the live hotel database: RUN_CATALOG_AUDIT_LIVE=1 pnpm vitest run src/lib/services/catalog-audit-repair-live.test.ts Three of those suites then repair the catalog in place: catalog-audit-repair-live and catalog-repair-direct-live rewrite catalog_items and delete duplicate classnames, and clone-bulk-import-live bulk-imports every cloneable item. None of that is undoable, and nothing in their output said the target was production rather than a sandbox. Added src/test/live-env.ts with one shared loader, and pointed all seven suites at it: - Values already in the real environment win, so an explicit DATABASE_URL on the command line is always respected. - DATABASE_URL defaults to the sandbox on port 3307 rather than inheriting the production one from .env. - Anything that is not loopback is treated as production and redirected. - Reaching production requires ALLOW_PRODUCTION_LIVE_DB=1 and logs a warning saying the suite repairs the catalog. Tests in src/test/live-env.test.ts run the loader against a temporary .env so the real project file is never read, and cover the redirect, the shell override, non-loopback detection, the opt-in and quote stripping. A second block asserts each of the seven suites no longer contains an inline `process.env[...] =` assignment. Verified four of them fail against the old loader. This does not enable the suites; they stay gated behind their RUN_* flags. It only removes the possibility of them silently hitting production. Unit suite: 3330 passed, 12 skipped. Typecheck and lint clean.
This commit is contained in:
1 parent
f705c67fc7
commit
8218039c64
9 files changed
+221
-119
No files matched your search
@@ -1,9 +1,9 @@
|
||||
// @ts-nocheck
|
||||
// Runs repairMissingIcons + repairMissingNitros directly (no source comparison
|
||||
// phase, which is the slow part of runCatalogAudit). Logs progress to a file.
|
||||
import { appendFileSync, existsSync, readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { appendFileSync } from "node:fs";
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { loadEnvForLiveTests } from "@/test/live-env";
|
||||
|
||||
const runLive = process.env.RUN_CATALOG_AUDIT_LIVE === "1";
|
||||
const LOG = "/tmp/catalog-asset-repair.log";
|
||||
@@ -16,21 +16,7 @@ describe.skipIf(!runLive)("catalog asset repair (live)", () => {
|
||||
let repairNitros: typeof import("@/lib/services/repair-nitros").repairMissingNitros;
|
||||
|
||||
beforeAll(async () => {
|
||||
const envFile = resolve(process.cwd(), ".env");
|
||||
if (existsSync(envFile)) {
|
||||
for (const line of readFileSync(envFile, "utf8").split(/\r?\n/)) {
|
||||
const m = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/);
|
||||
if (!m) continue;
|
||||
let value = m[2].trim();
|
||||
if (
|
||||
(value.startsWith('"') && value.endsWith('"')) ||
|
||||
(value.startsWith("'") && value.endsWith("'"))
|
||||
) {
|
||||
value = value.slice(1, -1);
|
||||
}
|
||||
process.env[m[1]] = value;
|
||||
}
|
||||
}
|
||||
loadEnvForLiveTests();
|
||||
process.env.SKIP_ENV_VALIDATION = "1";
|
||||
|
||||
[repairIcons, repairNitros] = await Promise.all([
|
||||
|
||||
Reference in new issue
Block a user