208 lines
5.5 KiB
TypeScript
208 lines
5.5 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
import {
|
|
buildCircuitDeviceRowInsertSnapshot,
|
|
buildCircuitInsertSnapshot,
|
|
} from "../src/frontend/utils/circuit-structure-command.js";
|
|
import {
|
|
deleteCircuitCommand,
|
|
deleteCircuitDeviceRowCommand,
|
|
insertCircuitCommand,
|
|
insertCircuitDeviceRowCommand,
|
|
} from "../src/frontend/utils/api.js";
|
|
|
|
describe("circuit structure command adapters", () => {
|
|
it("builds a complete row snapshot without legacy identities", () => {
|
|
const row = buildCircuitDeviceRowInsertSnapshot({
|
|
id: "row-1",
|
|
circuitId: "circuit-1",
|
|
defaultSortOrder: 20,
|
|
values: {
|
|
linkedProjectDeviceId: "device-1",
|
|
name: "Steckdose",
|
|
displayName: "Steckdose Büro",
|
|
quantity: 2,
|
|
powerPerUnit: 0.4,
|
|
simultaneityFactor: 0.8,
|
|
},
|
|
});
|
|
|
|
assert.deepEqual(row, {
|
|
id: "row-1",
|
|
circuitId: "circuit-1",
|
|
linkedProjectDeviceId: "device-1",
|
|
legacyConsumerId: null,
|
|
sortOrder: 20,
|
|
name: "Steckdose",
|
|
displayName: "Steckdose Büro",
|
|
phaseType: null,
|
|
connectionKind: null,
|
|
costGroup: null,
|
|
category: null,
|
|
level: null,
|
|
roomId: null,
|
|
roomNumberSnapshot: null,
|
|
roomNameSnapshot: null,
|
|
quantity: 2,
|
|
powerPerUnit: 0.4,
|
|
simultaneityFactor: 0.8,
|
|
cosPhi: null,
|
|
remark: null,
|
|
overriddenFields: null,
|
|
});
|
|
});
|
|
|
|
it("derives reserve state from the complete device-row snapshot", () => {
|
|
const reserve = buildCircuitInsertSnapshot({
|
|
id: "circuit-1",
|
|
circuitListId: "list-1",
|
|
values: {
|
|
sectionId: "section-1",
|
|
equipmentIdentifier: "-2F1",
|
|
sortOrder: 10,
|
|
isReserve: false,
|
|
voltage: 230,
|
|
controlRequirement: "DALI",
|
|
},
|
|
deviceRows: [],
|
|
});
|
|
|
|
assert.equal(reserve.isReserve, true);
|
|
assert.equal(reserve.displayName, null);
|
|
assert.equal(reserve.voltage, 230);
|
|
assert.equal(reserve.controlRequirement, "DALI");
|
|
|
|
const row = buildCircuitDeviceRowInsertSnapshot({
|
|
id: "row-1",
|
|
circuitId: reserve.id,
|
|
defaultSortOrder: 10,
|
|
values: {
|
|
name: "Gerät",
|
|
displayName: "Gerät",
|
|
quantity: 1,
|
|
powerPerUnit: 0,
|
|
simultaneityFactor: 1,
|
|
cosPhi: 1,
|
|
},
|
|
});
|
|
const populated = buildCircuitInsertSnapshot({
|
|
id: reserve.id,
|
|
circuitListId: reserve.circuitListId,
|
|
values: {
|
|
sectionId: reserve.sectionId,
|
|
equipmentIdentifier: reserve.equipmentIdentifier,
|
|
sortOrder: reserve.sortOrder,
|
|
isReserve: true,
|
|
},
|
|
deviceRows: [row],
|
|
});
|
|
|
|
assert.equal(populated.isReserve, false);
|
|
assert.deepEqual(populated.deviceRows, [row]);
|
|
});
|
|
|
|
it("sends structure envelopes through the project command route", async () => {
|
|
const requests: Array<{ url: string; body: Record<string, unknown> }> = [];
|
|
const originalFetch = globalThis.fetch;
|
|
globalThis.fetch = async (input, init) => {
|
|
requests.push({
|
|
url: String(input),
|
|
body: JSON.parse(String(init?.body)) as Record<string, unknown>,
|
|
});
|
|
return new Response(
|
|
JSON.stringify({
|
|
revision: {
|
|
revisionId: "revision-1",
|
|
changeSetId: "change-1",
|
|
projectId: "project-1",
|
|
revisionNumber: requests.length,
|
|
createdAtIso: "2026-07-25T00:00:00.000Z",
|
|
},
|
|
history: {
|
|
projectId: "project-1",
|
|
currentRevision: requests.length,
|
|
undoDepth: requests.length,
|
|
redoDepth: 0,
|
|
undoChangeSetId: "change-1",
|
|
redoChangeSetId: null,
|
|
},
|
|
}),
|
|
{ status: 200, headers: { "Content-Type": "application/json" } }
|
|
);
|
|
};
|
|
|
|
try {
|
|
const row = buildCircuitDeviceRowInsertSnapshot({
|
|
id: "row-1",
|
|
circuitId: "circuit-1",
|
|
defaultSortOrder: 10,
|
|
values: {
|
|
name: "Gerät",
|
|
displayName: "Gerät",
|
|
quantity: 1,
|
|
powerPerUnit: 0,
|
|
simultaneityFactor: 1,
|
|
},
|
|
});
|
|
const circuit = buildCircuitInsertSnapshot({
|
|
id: "circuit-1",
|
|
circuitListId: "list-1",
|
|
values: {
|
|
sectionId: "section-1",
|
|
equipmentIdentifier: "-2F1",
|
|
sortOrder: 10,
|
|
},
|
|
deviceRows: [row],
|
|
});
|
|
|
|
await insertCircuitCommand("project-1", 0, circuit, "insert circuit");
|
|
await deleteCircuitCommand(
|
|
"project-1",
|
|
1,
|
|
circuit.id,
|
|
circuit.circuitListId,
|
|
"delete circuit"
|
|
);
|
|
await insertCircuitDeviceRowCommand(
|
|
"project-1",
|
|
2,
|
|
row,
|
|
"insert row"
|
|
);
|
|
await deleteCircuitDeviceRowCommand(
|
|
"project-1",
|
|
3,
|
|
row.id,
|
|
row.circuitId,
|
|
"delete row"
|
|
);
|
|
} finally {
|
|
globalThis.fetch = originalFetch;
|
|
}
|
|
|
|
assert.deepEqual(
|
|
requests.map((request) => request.url),
|
|
Array(4).fill("/api/projects/project-1/commands")
|
|
);
|
|
assert.deepEqual(
|
|
requests.map((request) => {
|
|
const command = request.body.command as {
|
|
schemaVersion: number;
|
|
type: string;
|
|
};
|
|
return [
|
|
request.body.expectedRevision,
|
|
command.schemaVersion,
|
|
command.type,
|
|
];
|
|
}),
|
|
[
|
|
[0, 1, "circuit.insert"],
|
|
[1, 1, "circuit.delete"],
|
|
[2, 1, "circuit-device-row.insert"],
|
|
[3, 1, "circuit-device-row.delete"],
|
|
]
|
|
);
|
|
});
|
|
});
|