67 lines
3.8 KiB
TypeScript
67 lines
3.8 KiB
TypeScript
import { readFileSync, readdirSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
const repoFile = (path: string): string => readFileSync(resolve(process.cwd(), path), "utf8");
|
|
const persistenceSource = repoFile("scripts/demo-pro-seed/persistence.ts");
|
|
const projectServiceSource = repoFile("apps/web/app/utils/integrations/projects/projectService.server.ts");
|
|
const orderServiceSource = repoFile("apps/web/app/utils/integrations/projects/auftragService.server.ts");
|
|
const formTemplateSource = repoFile("apps/web/app/modules/forms/services/shkFormTemplates.server.ts");
|
|
const customFieldSource = repoFile("apps/web/app/utils/integrations/crm/customFieldService.server.ts");
|
|
const automationSource = repoFile("apps/web/app/services/automation/automation.server.ts");
|
|
const crmLegacySeedSource = repoFile("scripts/ops/seed-crm-leads-demo.mts");
|
|
const hrLegacySeedSource = repoFile("scripts/ops/seed-hr-demo.mts");
|
|
|
|
describe("managed staging business data", () => {
|
|
it("never persists comprehensive seed rows behind product demo filters", () => {
|
|
const creationSource = persistenceSource.split("export async function verifyDemoProTenant")[0]!;
|
|
expect(creationSource).toContain("const STAGING_BUSINESS_DATA_IS_DEMO = false;");
|
|
expect(creationSource).not.toContain("isDemoData: true");
|
|
expect(creationSource).toContain("isDemoData: STAGING_BUSINESS_DATA_IS_DEMO");
|
|
expect(creationSource).not.toContain('tags: ["Demo"');
|
|
expect(creationSource).not.toContain("Seed-Gruppe");
|
|
expect(creationSource).not.toContain("Demo-Signatur");
|
|
});
|
|
|
|
it("creates lazy project defaults as normal tenant data", () => {
|
|
expect(projectServiceSource).not.toContain("isDemoData: true");
|
|
expect(orderServiceSource).not.toContain("isDemoData: true");
|
|
});
|
|
|
|
it("keeps reachable template writers on the normal-data invariant", () => {
|
|
expect(formTemplateSource).toContain("const isDemoData = input.isDemoData ?? false");
|
|
expect(customFieldSource).toContain("const isDemoData = input.isDemoData ?? false");
|
|
const userTemplateCreation = automationSource.split("export async function createAutomationRuleFromTemplate")[1]!.split("export async function createAutomationRuleFromTemplateForRoute")[0]!;
|
|
expect(userTemplateCreation).not.toContain("isDemoData: true");
|
|
expect(userTemplateCreation).toContain("isDemoData: false");
|
|
});
|
|
|
|
it("verifies every tenant model that currently carries an isDemoData flag", () => {
|
|
const declaredList = persistenceSource.match(/const TENANT_MODELS_WITH_DEMO_FLAG = \[([\s\S]*?)\] as const;/u)?.[1];
|
|
expect(declaredList).toBeDefined();
|
|
const verifiedModels = [...(declaredList?.matchAll(/"([A-Za-z0-9]+)"/gu) ?? [])].map((match) => match[1]).sort();
|
|
const schemaDir = resolve(process.cwd(), "prisma/schema");
|
|
const schemaModels = readdirSync(schemaDir)
|
|
.filter((name) => name.endsWith(".prisma"))
|
|
.flatMap((name) => {
|
|
const source = readFileSync(resolve(schemaDir, name), "utf8");
|
|
return [...source.matchAll(/model\s+(\w+)\s*\{([\s\S]*?)\n\}/gu)]
|
|
.filter(([, , body]) => /\btenantId\s+String\??\b/u.test(body!) && /\bisDemoData\s+Boolean\b/u.test(body!))
|
|
.map(([, model]) => model!);
|
|
})
|
|
.sort();
|
|
|
|
expect(verifiedModels).toEqual(schemaModels);
|
|
});
|
|
|
|
it("keeps legacy demo scripts away from the managed staging tenant", () => {
|
|
for (const source of [crmLegacySeedSource, hrLegacySeedSource]) {
|
|
const targetList = source.match(/const DEMO_SLUGS = \[(.*?)\];/u)?.[1];
|
|
expect(targetList).toBeDefined();
|
|
expect(targetList).not.toContain('"demo-pro-crm"');
|
|
expect(source).toContain('const MANAGED_STAGING_TENANT_SLUG = "demo-pro-crm";');
|
|
expect(source).toContain("if (t.slug === MANAGED_STAGING_TENANT_SLUG)");
|
|
}
|
|
});
|
|
});
|