import { existsSync, readFileSync } from "node:fs"; import { resolve } from "node:path"; import { describe, expect, it } from "vitest"; import { DOMAIN_EVENT_LABELS, JOB_LABELS, JOB_RUN_STATUS_LABELS, QUEUE_STALE_WARNING_SECONDS, WEBHOOK_DELIVERY_STATUS_LABELS, attemptsLabel, formatAge, } from "./labels"; import { JOB_NAMES } from "./types"; describe("system labels", () => { it("labels every job", () => { expect(JOB_NAMES.every((job) => JOB_LABELS[job].length > 0)).toBe(true); expect(JOB_LABELS.cleanup).toBe("Aufräumen"); }); it("labels the voice transcribe job and both voice events", () => { expect(JOB_LABELS["voice-transcribe"]).toBe("Sprachnotizen abschreiben"); expect(DOMAIN_EVENT_LABELS.VoiceCaptureReady).toBe("Sprachnotiz fertig"); expect(DOMAIN_EVENT_LABELS.VoiceCaptureFailed).toBe("Sprachnotiz fehlgeschlagen"); }); it("labels the run and delivery states", () => { expect(JOB_RUN_STATUS_LABELS.FAILED).toBe("Fehlgeschlagen"); expect(WEBHOOK_DELIVERY_STATUS_LABELS.DELIVERED).toBe("Zugestellt"); expect(WEBHOOK_DELIVERY_STATUS_LABELS.PENDING).toBe("Offen"); expect(DOMAIN_EVENT_LABELS.InspectionRecorded).toBe("Durchsicht erfasst"); }); it("DOMAIN_EVENT_LABELS names ColonySplit, QueenAssigned, the extraction, honey batch and phenology events and SeasonPhaseChanged", () => { expect(DOMAIN_EVENT_LABELS).toMatchObject({ ColonySplit: "Ableger angelegt", QueenAssigned: "Königin zugewiesen", ExtractionRecorded: "Schleuderung erfasst", ExtractionCorrected: "Schleuderung korrigiert", HoneyBatchRecorded: "Honigcharge angelegt", HoneyBatchCorrected: "Honigcharge korrigiert", PhenologyReported: "Pflanzenmeldung erfasst", PhenologyCorrected: "Pflanzenmeldung korrigiert", SeasonPhaseChanged: "Saisonabschnitt gewechselt", }); }); it("warns after ten minutes", () => { expect(QUEUE_STALE_WARNING_SECONDS).toBe(600); }); it("pluralises attempts", () => { expect(attemptsLabel(1)).toBe("1 Versuch"); expect(attemptsLabel(0)).toBe("0 Versuche"); expect(attemptsLabel(8)).toBe("8 Versuche"); }); it("formats ages in German", () => { expect(formatAge(5)).toBe("vor wenigen Sekunden"); expect(formatAge(180)).toBe("vor 3 Min."); expect(formatAge(7300)).toBe("vor 2 Std."); expect(formatAge(2 * 86400 + 10)).toBe("vor 2 Tagen"); expect(formatAge(86400)).toBe("vor 1 Tag"); }); }); describe("DOMAIN_EVENT_LABELS completeness", () => { it("names PhenologyRecomputeRequested and WinterCheckRecorded", () => { expect(DOMAIN_EVENT_LABELS.PhenologyRecomputeRequested).toBe("Saison neu berechnen angefordert"); expect(DOMAIN_EVENT_LABELS.WinterCheckRecorded).toBe("Winterkontrolle erfasst"); }); it("has a German label for every backend domain event type", () => { const catalog = resolve(process.cwd(), "../ApiCore-Backend/src/domain-events/domain-event-types.ts"); if (!existsSync(catalog)) return; // frontend checked out alone const source = readFileSync(catalog, "utf8"); const block = source.slice(source.indexOf("const CATALOG"), source.indexOf("DOMAIN_EVENT_TYPES")); const types = [...block.matchAll(/^\s+([A-Z][A-Za-z]+): true,/gm)].map((match) => match[1]); expect(types.length).toBeGreaterThan(20); expect(types.filter((type) => !(type in DOMAIN_EVENT_LABELS))).toEqual([]); }); it("DOMAIN_EVENT_LABELS names ColonyCreated, ColonyMoved, ApiaryChanged and TskReferenceDayReached", () => { expect(DOMAIN_EVENT_LABELS).toMatchObject({ ColonyCreated: "Volk angelegt", ColonyMoved: "Volk umgesetzt", ApiaryChanged: "Stand geändert", TskReferenceDayReached: "TSK-Stichtag erreicht", }); }); it("names HiveChanged", () => { expect(DOMAIN_EVENT_LABELS.HiveChanged).toBe("Beute geändert"); }); });