Add explicit project device sync
This commit is contained in:
@@ -599,4 +599,34 @@ describe("circuit write service rules", () => {
|
||||
(db as unknown as { transaction: unknown }).transaction = originalTransaction;
|
||||
}
|
||||
});
|
||||
|
||||
it("tracks local edits on linked device rows as overridden fields", async () => {
|
||||
let savedOverrides: string | undefined;
|
||||
const current = {
|
||||
id: "r1",
|
||||
circuitId: "c1",
|
||||
linkedProjectDeviceId: "pd1",
|
||||
name: "Luminaire",
|
||||
displayName: "Local name",
|
||||
quantity: 1,
|
||||
powerPerUnit: 0.1,
|
||||
simultaneityFactor: 1,
|
||||
sortOrder: 10,
|
||||
overriddenFields: null,
|
||||
};
|
||||
const service = new CircuitWriteService({
|
||||
deviceRowRepository: {
|
||||
async findById() {
|
||||
return current as never;
|
||||
},
|
||||
async update(_rowId: string, input: { overriddenFields?: string }) {
|
||||
savedOverrides = input.overriddenFields;
|
||||
},
|
||||
} as never,
|
||||
});
|
||||
|
||||
await service.updateDeviceRow("r1", { quantity: 2 });
|
||||
|
||||
assert.deepEqual(JSON.parse(savedOverrides ?? "[]"), ["quantity"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
import { ProjectDeviceSyncService } from "../src/domain/services/project-device-sync.service.js";
|
||||
|
||||
function projectDevice() {
|
||||
return {
|
||||
id: "pd1",
|
||||
projectId: "p1",
|
||||
name: "Luminaire",
|
||||
displayName: "Office lighting",
|
||||
phaseType: "single_phase",
|
||||
connectionKind: "fixed",
|
||||
costGroup: "440",
|
||||
category: "Lighting",
|
||||
quantity: 6,
|
||||
powerPerUnit: 0.04,
|
||||
simultaneityFactor: 0.8,
|
||||
totalPower: 0.192,
|
||||
cosPhi: 0.95,
|
||||
remark: "DALI",
|
||||
};
|
||||
}
|
||||
|
||||
function linkedRow() {
|
||||
return {
|
||||
id: "row1",
|
||||
circuitId: "c1",
|
||||
linkedProjectDeviceId: "pd1",
|
||||
legacyConsumerId: null,
|
||||
sortOrder: 10,
|
||||
name: "Old luminaire",
|
||||
displayName: "Local display name",
|
||||
phaseType: "single_phase",
|
||||
connectionKind: null,
|
||||
costGroup: null,
|
||||
category: "Lighting",
|
||||
level: null,
|
||||
roomId: null,
|
||||
roomNumberSnapshot: "1.01",
|
||||
roomNameSnapshot: "Office",
|
||||
quantity: 2,
|
||||
powerPerUnit: 0.03,
|
||||
simultaneityFactor: 1,
|
||||
cosPhi: 1,
|
||||
remark: null,
|
||||
overriddenFields: JSON.stringify(["displayName", "quantity"]),
|
||||
equipmentIdentifier: "-1F1",
|
||||
circuitDisplayName: "Office",
|
||||
circuitListId: "list1",
|
||||
circuitListName: "UV-01 Stromkreisliste",
|
||||
distributionBoardId: "db1",
|
||||
distributionBoardName: "UV-01",
|
||||
};
|
||||
}
|
||||
|
||||
function createService() {
|
||||
const rows = [linkedRow()];
|
||||
const updates: Array<Record<string, unknown>> = [];
|
||||
const service = new ProjectDeviceSyncService({
|
||||
projectDeviceRepository: {
|
||||
async findById() {
|
||||
return projectDevice() as never;
|
||||
},
|
||||
},
|
||||
deviceRowRepository: {
|
||||
async listLinkedByProjectDevice() {
|
||||
return rows as never;
|
||||
},
|
||||
async update(rowId, input) {
|
||||
updates.push({ rowId, ...input });
|
||||
Object.assign(rows[0], input);
|
||||
},
|
||||
} as never,
|
||||
});
|
||||
return { service, rows, updates };
|
||||
}
|
||||
|
||||
describe("project device synchronization", () => {
|
||||
it("shows field differences and local overrides without changing rows", async () => {
|
||||
const { service, updates } = createService();
|
||||
const preview = await service.getPreview("p1", "pd1");
|
||||
|
||||
assert.equal(updates.length, 0);
|
||||
assert.equal(preview.rows[0].equipmentIdentifier, "-1F1");
|
||||
assert.equal(preview.rows[0].differences.some((difference) => difference.field === "quantity"), true);
|
||||
assert.equal(
|
||||
preview.rows[0].differences.find((difference) => difference.field === "displayName")?.isOverridden,
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it("synchronizes only explicitly selected fields", async () => {
|
||||
const { service, rows } = createService();
|
||||
await service.synchronize("p1", "pd1", ["row1"], ["quantity", "powerPerUnit"]);
|
||||
|
||||
assert.equal(rows[0].quantity, 6);
|
||||
assert.equal(rows[0].powerPerUnit, 0.04);
|
||||
assert.equal(rows[0].displayName, "Local display name");
|
||||
assert.deepEqual(JSON.parse(rows[0].overriddenFields ?? "[]"), ["displayName"]);
|
||||
});
|
||||
|
||||
it("rejects rows that are not linked to the selected project device", async () => {
|
||||
const { service } = createService();
|
||||
await assert.rejects(
|
||||
() => service.synchronize("p1", "pd1", ["other-row"], ["quantity"]),
|
||||
/not linked/
|
||||
);
|
||||
});
|
||||
|
||||
it("disconnects selected rows without changing local values", async () => {
|
||||
const { service, updates } = createService();
|
||||
await service.disconnect("p1", "pd1", ["row1"]);
|
||||
|
||||
assert.equal(updates[0].linkedProjectDeviceId, undefined);
|
||||
assert.equal(updates[0].displayName, "Local display name");
|
||||
assert.equal(updates[0].quantity, 2);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user