Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/scripts/demo-pro-seed/cli.test.ts
T

227 lines
8.9 KiB
TypeScript

import { describe, expect, test, vi } from "vitest";
import { DEMO_PRO_TENANT_SLUG, parseSeedCommand } from "./cli";
const stagingEnv = {
SEED_DEMO_PRO_ALLOWED: "true",
SEED_DEMO_PRO_EXPECTED_DATABASE: "hivegrid_staging",
SEED_DEMO_PRO_EXPECTED_DATABASE_HOST: "postgres-staging:5432",
SEED_DEMO_PRO_EXPECTED_STORAGE_BUCKET: "hivegrid-staging-media",
SEED_DEMO_PRO_EXPECTED_STORAGE_ENDPOINT: "https://staging-storage.example.test",
SEED_DEMO_PRO_EXPECTED_TENANT_ID: "tenant_staging_demo_pro",
SEED_DEMO_PRO_OUTBOUND_SANDBOX: "true",
SEED_DEMO_PRO_WORKERS_DRAINED: "true",
SEED_DEMO_USER_PASSWORD: "R7!qL2#vN9@xP4$kT8&m",
SENTRY_ENVIRONMENT: "staging",
};
describe("demo-pro seed CLI", () => {
test("defaults to an environment-free dry run", () => {
expect(parseSeedCommand([], {})).toEqual({
mode: "dry-run",
tenantSlug: DEMO_PRO_TENANT_SLUG,
});
expect(parseSeedCommand(["--dry-run"], {})).toEqual({
mode: "dry-run",
tenantSlug: DEMO_PRO_TENANT_SLUG,
});
});
test("accepts only the demo-pro-crm tenant", () => {
expect(parseSeedCommand(["--tenant=demo-pro-crm"], {})).toEqual({
mode: "dry-run",
tenantSlug: DEMO_PRO_TENANT_SLUG,
});
expect(() => parseSeedCommand(["--tenant=another-tenant"], {})).toThrow("target tenant must be demo-pro-crm");
});
test("rejects unknown, duplicate and conflicting arguments", () => {
expect(() => parseSeedCommand(["apply"], {})).toThrow("unknown argument");
expect(() => parseSeedCommand(["--apply", "--cleanup"], stagingEnv)).toThrow("exactly one mode");
expect(() => parseSeedCommand(["--tenant=demo-pro-crm", "--tenant=demo-pro-crm"], {})).toThrow("--tenant may only be provided once");
expect(() => parseSeedCommand(["--apply", "--confirm=demo-pro-crm", "--confirm=demo-pro-crm"], stagingEnv)).toThrow("--confirm may only be provided once");
});
test("requires an exact tenant confirmation for apply", () => {
expect(() => parseSeedCommand(["--apply"], stagingEnv)).toThrow("--confirm=demo-pro-crm");
expect(() => parseSeedCommand(["--apply", "--confirm=another-tenant"], stagingEnv)).toThrow("--confirm=demo-pro-crm");
});
test("requires explicit authorization for apply and cleanup", () => {
expect(() =>
parseSeedCommand(["--apply", "--confirm=demo-pro-crm"], {
SENTRY_ENVIRONMENT: "staging",
})
).toThrow("explicit staging seed authorization");
expect(() =>
parseSeedCommand(["--cleanup", "--confirm=demo-pro-crm"], {
SENTRY_ENVIRONMENT: "staging",
})
).toThrow("explicit staging seed authorization");
});
test("requires drained workers and a staging-only outbound sink", () => {
expect(() =>
parseSeedCommand(["--cleanup", "--confirm=demo-pro-crm"], {
...stagingEnv,
SEED_DEMO_PRO_WORKERS_DRAINED: "false",
})
).toThrow("drained workers");
expect(() =>
parseSeedCommand(["--cleanup", "--confirm=demo-pro-crm"], {
...stagingEnv,
SEED_DEMO_PRO_OUTBOUND_SANDBOX: "false",
})
).toThrow("outbound staging sandbox");
});
test("allows apply only on staging and resolves the configured staging password", () => {
expect(parseSeedCommand(["--apply", "--confirm=demo-pro-crm"], stagingEnv)).toEqual({
mode: "apply",
tenantSlug: DEMO_PRO_TENANT_SLUG,
userPassword: "R7!qL2#vN9@xP4$kT8&m",
expectedTenantId: "tenant_staging_demo_pro",
expectedDatabaseName: "hivegrid_staging",
expectedDatabaseHost: "postgres-staging:5432",
expectedStorageBucket: "hivegrid-staging-media",
expectedStorageEndpoint: "https://staging-storage.example.test",
});
});
test("requires the password to be supplied as a staging secret", () => {
expect(() =>
parseSeedCommand(["--apply", "--confirm=demo-pro-crm"], {
SEED_DEMO_PRO_ALLOWED: "true",
SEED_DEMO_PRO_EXPECTED_DATABASE: "hivegrid_staging",
SEED_DEMO_PRO_EXPECTED_DATABASE_HOST: "postgres-staging:5432",
SEED_DEMO_PRO_EXPECTED_STORAGE_BUCKET: "hivegrid-staging-media",
SEED_DEMO_PRO_EXPECTED_STORAGE_ENDPOINT: "https://staging-storage.example.test",
SEED_DEMO_PRO_EXPECTED_TENANT_ID: "tenant_staging_demo_pro",
SEED_DEMO_PRO_OUTBOUND_SANDBOX: "true",
SEED_DEMO_PRO_WORKERS_DRAINED: "true",
SENTRY_ENVIRONMENT: "staging",
})
).toThrow("demo-user password secret");
});
test("requires mutation to be bound to the exact staging tenant and database", () => {
expect(() =>
parseSeedCommand(["--cleanup", "--confirm=demo-pro-crm"], {
SEED_DEMO_PRO_ALLOWED: "true",
SEED_DEMO_PRO_OUTBOUND_SANDBOX: "true",
SEED_DEMO_PRO_WORKERS_DRAINED: "true",
SENTRY_ENVIRONMENT: "staging",
})
).toThrow("tenant, database, and storage binding");
});
test.each(["passwort", "password", "HiveGrid-Demo-Password", "short-but-varied!9A"])("rejects a weak shared staging password (%s)", (password) => {
expect(() =>
parseSeedCommand(["--apply", "--confirm=demo-pro-crm"], {
...stagingEnv,
SEED_DEMO_USER_PASSWORD: password,
})
).toThrow("strong random secret");
});
test("allows the explicitly requested shared password only behind the dedicated staging guard", () => {
expect(
parseSeedCommand(["--apply", "--confirm=demo-pro-crm"], {
...stagingEnv,
SEED_DEMO_PRO_ALLOW_SHARED_STAGING_PASSWORD: "true",
SEED_DEMO_USER_PASSWORD: "password",
}),
).toMatchObject({ mode: "apply", userPassword: "password" });
expect(() =>
parseSeedCommand(["--apply", "--confirm=demo-pro-crm"], {
...stagingEnv,
SEED_DEMO_PRO_ALLOW_SHARED_STAGING_PASSWORD: "true",
SEED_DEMO_USER_PASSWORD: "passwort",
}),
).toThrow("strong random secret");
});
test("keeps a configured password opaque and does not log it", () => {
const consoleSpies = [
vi.spyOn(console, "log").mockImplementation(() => undefined),
vi.spyOn(console, "info").mockImplementation(() => undefined),
vi.spyOn(console, "warn").mockImplementation(() => undefined),
vi.spyOn(console, "error").mockImplementation(() => undefined),
];
const password = " R7!qL2#vN9@xP4$kT8&m ";
const command = parseSeedCommand(["--apply", "--confirm=demo-pro-crm"], {
...stagingEnv,
SEED_DEMO_USER_PASSWORD: password,
});
expect(command).toEqual({
mode: "apply",
tenantSlug: DEMO_PRO_TENANT_SLUG,
userPassword: password,
expectedTenantId: "tenant_staging_demo_pro",
expectedDatabaseName: "hivegrid_staging",
expectedDatabaseHost: "postgres-staging:5432",
expectedStorageBucket: "hivegrid-staging-media",
expectedStorageEndpoint: "https://staging-storage.example.test",
});
for (const spy of consoleSpies) expect(spy).not.toHaveBeenCalled();
vi.restoreAllMocks();
});
test("does not echo values from rejected arguments", () => {
const accidentalSecret = "Never expose this value";
expect(() => parseSeedCommand([`--password=${accidentalSecret}`], {})).toThrowError(
expect.not.objectContaining({ message: expect.stringContaining(accidentalSecret) })
);
});
test.each([undefined, "", "production", "development", "test", "STAGING", "staging-preview"])(
"rejects verify outside the exact staging environment (%s)",
(environment) => {
expect(() =>
parseSeedCommand(["--verify"], {
SENTRY_ENVIRONMENT: environment,
})
).toThrow("restricted to the staging environment");
}
);
test("allows read-only verification on staging without mutation authorization", () => {
expect(parseSeedCommand(["--verify"], { SENTRY_ENVIRONMENT: "staging" })).toEqual({
mode: "verify",
tenantSlug: DEMO_PRO_TENANT_SLUG,
});
});
test("allows cleanup only with every destructive-operation guard", () => {
expect(parseSeedCommand(["--cleanup", "--confirm=demo-pro-crm"], stagingEnv)).toEqual({
mode: "cleanup",
tenantSlug: DEMO_PRO_TENANT_SLUG,
expectedTenantId: "tenant_staging_demo_pro",
expectedDatabaseName: "hivegrid_staging",
expectedDatabaseHost: "postgres-staging:5432",
expectedStorageBucket: "hivegrid-staging-media",
expectedStorageEndpoint: "https://staging-storage.example.test",
});
});
test("does not treat NODE_ENV=production as production when the deployment is explicitly staging", () => {
expect(
parseSeedCommand(["--apply", "--confirm=demo-pro-crm"], {
...stagingEnv,
NODE_ENV: "production",
})
).toMatchObject({ mode: "apply", tenantSlug: DEMO_PRO_TENANT_SLUG });
});
test("does not accept confirmation for non-mutating modes", () => {
expect(() => parseSeedCommand(["--confirm=demo-pro-crm"], {})).toThrow("--confirm is only valid for apply and cleanup");
expect(() => parseSeedCommand(["--verify", "--confirm=demo-pro-crm"], { SENTRY_ENVIRONMENT: "staging" })).toThrow(
"--confirm is only valid for apply and cleanup"
);
});
});