169 lines
4.4 KiB
TypeScript
169 lines
4.4 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
import {
|
|
deserializeProjectCommand,
|
|
serializeProjectCommand,
|
|
type SerializedProjectCommand,
|
|
} from "../src/domain/models/project-command.model.js";
|
|
import {
|
|
assertCircuitUpdateProjectCommand,
|
|
createCircuitUpdateProjectCommand,
|
|
} from "../src/domain/models/circuit-project-command.model.js";
|
|
import {
|
|
assertCircuitDeviceRowUpdateProjectCommand,
|
|
createCircuitDeviceRowUpdateProjectCommand,
|
|
} from "../src/domain/models/circuit-device-row-project-command.model.js";
|
|
|
|
describe("serialized project commands", () => {
|
|
it("round-trips a versioned command envelope", () => {
|
|
const command: SerializedProjectCommand = {
|
|
schemaVersion: 1,
|
|
type: "circuit.update",
|
|
payload: {
|
|
circuitId: "circuit-1",
|
|
changes: {
|
|
displayName: "Werkstatt",
|
|
protectionRatedCurrent: 16,
|
|
isReserve: false,
|
|
remark: null,
|
|
},
|
|
},
|
|
};
|
|
|
|
assert.deepEqual(
|
|
deserializeProjectCommand(serializeProjectCommand(command)),
|
|
command
|
|
);
|
|
});
|
|
|
|
it("rejects values that JSON would lose or silently change", () => {
|
|
const invalidPayloads: unknown[] = [
|
|
{ value: undefined },
|
|
{ value: Number.NaN },
|
|
{ value: Number.POSITIVE_INFINITY },
|
|
{ value: new Date() },
|
|
];
|
|
|
|
for (const payload of invalidPayloads) {
|
|
assert.throws(() =>
|
|
serializeProjectCommand({
|
|
schemaVersion: 1,
|
|
type: "test.invalid",
|
|
payload: payload as never,
|
|
})
|
|
);
|
|
}
|
|
});
|
|
|
|
it("rejects cyclic payloads before persistence", () => {
|
|
const payload: Record<string, unknown> = {};
|
|
payload.self = payload;
|
|
|
|
assert.throws(
|
|
() =>
|
|
serializeProjectCommand({
|
|
schemaVersion: 1,
|
|
type: "test.cyclic",
|
|
payload: payload as never,
|
|
}),
|
|
/must not contain cycles/
|
|
);
|
|
});
|
|
|
|
it("rejects malformed serialized envelopes", () => {
|
|
assert.throws(
|
|
() =>
|
|
deserializeProjectCommand(
|
|
JSON.stringify({ schemaVersion: 0, type: "", payload: null })
|
|
),
|
|
/schema version/
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("circuit update project commands", () => {
|
|
it("creates a typed command with explicit null clearing semantics", () => {
|
|
const command = createCircuitUpdateProjectCommand("circuit-1", {
|
|
displayName: null,
|
|
cableLength: 12.5,
|
|
isReserve: false,
|
|
});
|
|
|
|
assert.doesNotThrow(() => assertCircuitUpdateProjectCommand(command));
|
|
assert.deepEqual(command.payload.changes, [
|
|
{ field: "displayName", value: null },
|
|
{ field: "cableLength", value: 12.5 },
|
|
{ field: "isReserve", value: false },
|
|
]);
|
|
});
|
|
|
|
it("rejects empty, duplicate and invalid field changes", () => {
|
|
assert.throws(
|
|
() => createCircuitUpdateProjectCommand("circuit-1", {}),
|
|
/at least one change/
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
assertCircuitUpdateProjectCommand({
|
|
schemaVersion: 1,
|
|
type: "circuit.update",
|
|
payload: {
|
|
circuitId: "circuit-1",
|
|
changes: [
|
|
{ field: "displayName", value: "A" },
|
|
{ field: "displayName", value: "B" },
|
|
],
|
|
},
|
|
}),
|
|
/duplicate field/
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
createCircuitUpdateProjectCommand("circuit-1", {
|
|
voltage: 0,
|
|
}),
|
|
/outside its allowed range/
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("circuit device-row update project commands", () => {
|
|
it("creates typed nullable device-row changes", () => {
|
|
const command = createCircuitDeviceRowUpdateProjectCommand("row-1", {
|
|
roomId: null,
|
|
quantity: 2,
|
|
cosPhi: 0.9,
|
|
});
|
|
|
|
assert.doesNotThrow(() =>
|
|
assertCircuitDeviceRowUpdateProjectCommand(command)
|
|
);
|
|
assert.deepEqual(command.payload.changes, [
|
|
{ field: "roomId", value: null },
|
|
{ field: "quantity", value: 2 },
|
|
{ field: "cosPhi", value: 0.9 },
|
|
]);
|
|
});
|
|
|
|
it("rejects invalid device-row values", () => {
|
|
assert.throws(
|
|
() => createCircuitDeviceRowUpdateProjectCommand("row-1", {}),
|
|
/at least one change/
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
createCircuitDeviceRowUpdateProjectCommand("row-1", {
|
|
displayName: "",
|
|
}),
|
|
/non-empty string/
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
createCircuitDeviceRowUpdateProjectCommand("row-1", {
|
|
quantity: -1,
|
|
}),
|
|
/non-negative/
|
|
);
|
|
});
|
|
});
|