140 lines
4.8 KiB
TypeScript
140 lines
4.8 KiB
TypeScript
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<string, unknown>;
|
|
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/);
|
|
});
|
|
|
|
it("rejects unknown configuration fields", () => {
|
|
const configuration = {
|
|
...createDefaultExternalCsvConfiguration(columns),
|
|
legacyMapping: true,
|
|
};
|
|
assert.match(validateFailure(configuration), /unknown or missing fields/);
|
|
});
|
|
});
|
|
|
|
function validateFailure(value: unknown) {
|
|
const result = validateExternalCsvConfiguration(value);
|
|
assert.equal(result.success, false);
|
|
return result.error;
|
|
}
|