Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/modules/templates/defaultEntityTemplates.test.ts
T

124 lines
4.6 KiB
TypeScript

import fs from "node:fs";
import path from "node:path";
import { describe, expect, it } from "vitest";
import type { EntitiesTemplateDto } from "./EntityTemplateDto";
import {
ALL_PROPERTY_TYPES_ENTITY_TEMPLATE,
CRM_ENTITIES_TEMPLATE,
EMPLOYEES_ENTITIES_TEMPLATE,
TENANT_SETTINGS_ENTITIES_TEMPLATE,
} from "./defaultEntityTemplates";
const repoRoot = process.cwd();
describe("default entity templates i18n seed polish", () => {
it("keeps default seed labels on existing translation keys", () => {
expect(CRM_ENTITIES_TEMPLATE.defaultLanguage).toBe("en");
expect(CRM_ENTITIES_TEMPLATE.languages).toEqual(["en"]);
expect(TENANT_SETTINGS_ENTITIES_TEMPLATE.defaultLanguage).toBe("en");
expect(TENANT_SETTINGS_ENTITIES_TEMPLATE.languages).toEqual(["en"]);
expect(EMPLOYEES_ENTITIES_TEMPLATE.defaultLanguage).toBe("en");
expect(EMPLOYEES_ENTITIES_TEMPLATE.languages).toEqual(["en"]);
expect(ALL_PROPERTY_TYPES_ENTITY_TEMPLATE.defaultLanguage).toBe("en");
expect(ALL_PROPERTY_TYPES_ENTITY_TEMPLATE.languages).toEqual(["en"]);
const labels = [
...collectTemplateLabels(CRM_ENTITIES_TEMPLATE),
...collectTemplateLabels(TENANT_SETTINGS_ENTITIES_TEMPLATE),
...collectTemplateLabels(EMPLOYEES_ENTITIES_TEMPLATE),
...collectTemplateLabels(ALL_PROPERTY_TYPES_ENTITY_TEMPLATE),
];
const en = readTranslations("en");
const de = readTranslations("de");
expect(labels).toEqual(
expect.arrayContaining([
"models.opportunity.expectedCloseDate",
"models.contact.jobTitle",
"models.tenantSettings.object",
"models.employee.object",
"models.employee.status.options.on_leave",
"models.allPropertyTypesEntity.object",
"models.allPropertyTypesEntity.singleSelectDropdown",
"models.allPropertyTypesEntity.options.option_1",
])
);
expect(labels).not.toEqual(
expect.arrayContaining([
"Expected close date",
"Job title",
"Account settings",
"Tenant settings",
"Employee",
"Employees",
"Salary",
"On Leave",
"All Property Types Entity",
"Text (Single-line)",
"Single Select (Dropdown)",
])
);
for (const label of labels) {
expect(getTranslation(en, label), label).toBeTypeOf("string");
expect(getTranslation(de, label), label).toBeTypeOf("string");
}
});
it("has English and German picker copy for CRM and tenant settings defaults", () => {
const en = readTranslations("en");
const de = readTranslations("de");
expect(en.models.entityTemplate.defaultTemplates.crm).toBe("Default CRM");
expect(en.models.entityTemplate.defaultTemplates.tenantSettings).toBe("Default account settings");
expect(en.models.entityTemplate.defaultTemplates.employee).toBe("Example: Employee");
expect(en.models.entityTemplate.defaultTemplates.allPropertyTypes).toBe("Example: All property types entity");
expect(de.models.entityTemplate.defaultTemplates.crm).toBe("Standard-CRM");
expect(de.models.entityTemplate.defaultTemplates.tenantSettings).toBe("Standard-Kontoeinstellungen");
expect(de.models.entityTemplate.defaultTemplates.employee).toBe("Beispiel: Mitarbeitende");
expect(de.models.entityTemplate.defaultTemplates.allPropertyTypes).toBe("Beispiel: Entität mit allen Eigenschaftstypen");
});
});
type TemplateWithLanguageScope = EntitiesTemplateDto & {
defaultLanguage: "en";
languages: readonly ["en"];
};
function collectTemplateLabels(template: TemplateWithLanguageScope) {
return template.entities.flatMap((entity) => [
entity.title,
entity.titlePlural,
...entity.properties.flatMap((property) => [
property.title,
...(property.options ?? [])
.map((option) => option.name)
.filter((name): name is string => typeof name === "string"),
]),
...(entity.views ?? []).map((view) => view.title),
]);
}
function readTranslations(locale: "en" | "de") {
return JSON.parse(fs.readFileSync(path.join(repoRoot, `apps/web/public/locales/${locale}/translations.json`), "utf8")) as {
models: Record<string, unknown> & {
entityTemplate: {
defaultTemplates: {
crm: string;
tenantSettings: string;
employee: string;
allPropertyTypes: string;
};
};
};
};
}
function getTranslation(translations: ReturnType<typeof readTranslations>, key: string) {
return key.split(".").reduce<unknown>((value, segment) => {
if (value && typeof value === "object" && segment in value) {
return (value as Record<string, unknown>)[segment];
}
return undefined;
}, translations);
}