135 lines
4.9 KiB
TypeScript
135 lines
4.9 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
import {
|
|
allColumns,
|
|
buildCircuitEditPatch,
|
|
buildDeviceRowEditPatch,
|
|
formatValue,
|
|
getBlockSortValue,
|
|
getCellKind,
|
|
getCircuitValue,
|
|
getDeviceValue,
|
|
parseNumeric,
|
|
} from "../src/frontend/utils/circuit-grid-model.js";
|
|
import type { CircuitTreeCircuitDto, CircuitTreeDeviceRowDto } from "../src/frontend/types.js";
|
|
|
|
const device: CircuitTreeDeviceRowDto = {
|
|
id: "row-1",
|
|
sortOrder: 10,
|
|
name: "Technical light",
|
|
displayName: "Office light",
|
|
phaseType: "single_phase",
|
|
roomNumberSnapshot: "1.01",
|
|
roomNameSnapshot: "Office",
|
|
quantity: 2,
|
|
powerPerUnit: 0.05,
|
|
simultaneityFactor: 0.8,
|
|
rowTotalPower: 0.08,
|
|
remark: "Device remark",
|
|
};
|
|
|
|
const circuit: CircuitTreeCircuitDto = {
|
|
id: "circuit-1",
|
|
circuitListId: "list-1",
|
|
sectionId: "section-1",
|
|
equipmentIdentifier: "-1F1",
|
|
displayName: "Lighting circuit",
|
|
sortOrder: 10,
|
|
protectionType: "MCB",
|
|
protectionRatedCurrent: 16,
|
|
protectionCharacteristic: "B",
|
|
cableType: "NYM-J",
|
|
cableCrossSection: "1.5 mm²",
|
|
cableLength: 20,
|
|
voltage: 230,
|
|
controlRequirement: "DALI",
|
|
isReserve: false,
|
|
remark: "Circuit remark",
|
|
circuitTotalPower: 0.08,
|
|
deviceRows: [device],
|
|
};
|
|
|
|
describe("circuit grid model", () => {
|
|
it("keeps the equipment identifier locked as the first column", () => {
|
|
assert.equal(allColumns[0].key, "equipmentIdentifier");
|
|
assert.equal(allColumns[0].locked, true);
|
|
});
|
|
|
|
it("maps shared fields to the correct level for every row shape", () => {
|
|
assert.equal(getCellKind("circuitCompact", "displayName"), "deviceField");
|
|
assert.equal(getCellKind("circuitCompact", "equipmentIdentifier"), "circuitField");
|
|
assert.equal(getCellKind("circuitSummary", "displayName"), "circuitField");
|
|
assert.equal(getCellKind("deviceRow", "displayName"), "deviceField");
|
|
assert.equal(getCellKind("reserveCircuit", "remark"), "deviceField");
|
|
assert.equal(getCellKind("placeholder", "displayName"), "deviceField");
|
|
assert.equal(getCellKind("deviceRow", "equipmentIdentifier"), "readonly");
|
|
assert.equal(getCellKind("circuitSummary", "controlRequirement"), "circuitField");
|
|
assert.equal(getCellKind("deviceRow", "controlRequirement"), "readonly");
|
|
assert.equal(getCellKind("circuitCompact", "rowTotalPower"), "computed");
|
|
});
|
|
|
|
it("projects circuit and device values without mixing ownership", () => {
|
|
assert.equal(getDeviceValue(device, "roomSummary"), "1.01 Office");
|
|
assert.equal(getDeviceValue(device, "rowTotalPower"), 0.08);
|
|
assert.equal(getCircuitValue(circuit, "protectionSummary"), "MCB 16A B");
|
|
assert.equal(getCircuitValue(circuit, "voltage"), 230);
|
|
assert.equal(getCircuitValue(circuit, "controlRequirement"), "DALI");
|
|
assert.equal(getCircuitValue(circuit, "cableSummary"), "NYM-J, 1.5 mm², 20 m");
|
|
});
|
|
|
|
it("formats displayed numeric values without changing their stored precision", () => {
|
|
assert.equal(formatValue(0.123456, "powerPerUnit"), "0,123");
|
|
assert.equal(formatValue(0.87654, "simultaneityFactor"), "0,88");
|
|
assert.equal(formatValue(230.4, "voltage"), "230");
|
|
assert.equal(formatValue(16, "protectionRatedCurrent"), "16");
|
|
assert.equal(formatValue("single_phase", "phaseType"), "1-phasig");
|
|
assert.equal(formatValue("three_phase", "phaseType"), "3-phasig");
|
|
});
|
|
|
|
it("uses circuit display values for block sorting and falls back to the first device", () => {
|
|
assert.equal(getBlockSortValue(circuit, "displayName"), "Lighting circuit");
|
|
assert.equal(getBlockSortValue({ ...circuit, displayName: undefined }, "displayName"), "Office light");
|
|
assert.equal(getBlockSortValue(circuit, "quantity"), 2);
|
|
});
|
|
|
|
it("parses numeric drafts and rejects invalid values", () => {
|
|
assert.equal(parseNumeric("quantity", " 2.5 "), 2.5);
|
|
assert.equal(parseNumeric("quantity", ""), undefined);
|
|
assert.throws(() => parseNumeric("quantity", "two"), /Ungültiger Zahlenwert/);
|
|
});
|
|
|
|
it("builds nullable circuit command patches from grid drafts", () => {
|
|
assert.deepEqual(buildCircuitEditPatch("voltage", ""), {
|
|
voltage: null,
|
|
});
|
|
assert.deepEqual(
|
|
buildCircuitEditPatch("controlRequirement", " DALI "),
|
|
{ controlRequirement: "DALI" }
|
|
);
|
|
assert.deepEqual(buildCircuitEditPatch("isReserve", "ja"), {
|
|
isReserve: true,
|
|
});
|
|
});
|
|
|
|
it("builds device command patches with explicit clearing semantics", () => {
|
|
assert.deepEqual(buildDeviceRowEditPatch("roomSummary", ""), {
|
|
roomNumberSnapshot: null,
|
|
roomNameSnapshot: null,
|
|
});
|
|
assert.deepEqual(
|
|
buildDeviceRowEditPatch("roomSummary", "1.01 Büro"),
|
|
{
|
|
roomNumberSnapshot: "1.01",
|
|
roomNameSnapshot: "Büro",
|
|
}
|
|
);
|
|
assert.deepEqual(buildDeviceRowEditPatch("technicalName", " Leuchte "), {
|
|
name: "Leuchte",
|
|
});
|
|
assert.throws(
|
|
() => buildDeviceRowEditPatch("quantity", ""),
|
|
/darf nicht leer sein/
|
|
);
|
|
});
|
|
});
|