import assert from "node:assert/strict"; import { describe, it } from "node:test"; import { createDefaultExternalCsvConfiguration, type ExternalCsvColumnMapping, } from "../src/external-model/csv/external-csv-contracts.js"; import { assertExternalCsvConfiguration, validateExternalCsvConfiguration, } from "../src/external-model/csv/external-csv-configuration.js"; const columns: ExternalCsvColumnMapping = { ifcGuid: "IfcGUID", roomNumber: "Raumnummer", roomName: "Raumname", familyAndType: "Familie und Typ", selectionMarker: "CAx_Auswahlkenner", circuitIdentifier: "Stromkreis", power: "Elektrische Leistung", quantity: "Anzahl", }; describe("external CSV configuration", () => { it("creates the agreed UTF-8, semicolon and watt defaults", () => { const configuration = createDefaultExternalCsvConfiguration(columns); assert.doesNotThrow(() => assertExternalCsvConfiguration(configuration)); assert.equal(configuration.encoding, "utf-8"); assert.equal(configuration.delimiter, ";"); assert.equal(configuration.powerUnit, "W"); assert.equal(configuration.wattsPerSourceUnit, 1); }); it("accepts exact family/type rules and additional source mappings", () => { const configuration = createDefaultExternalCsvConfiguration(columns); configuration.additionalSourceMappings.push({ sourceColumn: "Montageart", targetField: "mountingType", }); configuration.familyTypeRules.push({ exactFamilyAndType: "_E_CAx Mehrfachsteckdose: Doppelsteckdose", internalDeviceType: "Steckdose", connectionKind: "socket", category: "single_phase", quantityRule: { kind: "mapped-column" }, displayNameSuggestion: { kind: "selection-marker" }, }); assert.deepEqual(validateExternalCsvConfiguration(configuration), { success: true, data: configuration, }); }); it("rejects ambiguous column and family/type mappings", () => { const duplicateColumn = createDefaultExternalCsvConfiguration({ ...columns, quantity: columns.power, }); assert.match( validateFailure(duplicateColumn), /column is mapped more than once/ ); const duplicateRule = createDefaultExternalCsvConfiguration(columns); duplicateRule.familyTypeRules = [ { exactFamilyAndType: "Leuchte: Standard", internalDeviceType: "Leuchte", connectionKind: null, category: "lighting", quantityRule: { kind: "fixed", quantity: 1 }, displayNameSuggestion: null, }, { exactFamilyAndType: "Leuchte: Standard", internalDeviceType: "Leuchte", connectionKind: null, category: "lighting", quantityRule: { kind: "fixed", quantity: 1 }, displayNameSuggestion: null, }, ]; assert.match( validateFailure(duplicateRule), /family\/type rule is duplicated/ ); }); it("rejects unsupported transport values and invalid fixed quantities", () => { const configuration = createDefaultExternalCsvConfiguration(columns) as unknown as Record; configuration.encoding = "ansi"; assert.match(validateFailure(configuration), /encoding must be utf-8/); const invalidQuantity = createDefaultExternalCsvConfiguration(columns); invalidQuantity.familyTypeRules.push({ exactFamilyAndType: "Steckdose: Standard", internalDeviceType: "Steckdose", connectionKind: null, category: "single_phase", quantityRule: { kind: "fixed", quantity: 0 }, displayNameSuggestion: { kind: "fixed", value: "Steckdose" }, }); assert.match(validateFailure(invalidQuantity), /positive finite number/); }); it("allows a missing quantity column only for fixed quantity rules", () => { const configuration = createDefaultExternalCsvConfiguration({ ...columns, quantity: null, }); configuration.familyTypeRules.push({ exactFamilyAndType: "Steckdose: Standard", internalDeviceType: "Steckdose", connectionKind: null, category: "single_phase", quantityRule: { kind: "fixed", quantity: 1 }, displayNameSuggestion: null, }); assert.equal(validateExternalCsvConfiguration(configuration).success, true); configuration.familyTypeRules[0].quantityRule = { kind: "mapped-column" }; assert.match(validateFailure(configuration), /requires a configured quantity column/); }); }); function validateFailure(value: unknown) { const result = validateExternalCsvConfiguration(value); assert.equal(result.success, false); return result.error; }