166 lines
6.0 KiB
TypeScript
166 lines
6.0 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
import { createElement } from "react";
|
|
import { renderToStaticMarkup } from "react-dom/server";
|
|
import {
|
|
RevitCsvImportPlan,
|
|
RevitCsvModal,
|
|
} from "../src/frontend/components/revit-csv-modal.js";
|
|
import {
|
|
applyExternalInitialImport,
|
|
getExternalCsvConfiguration,
|
|
planExternalInitialImport,
|
|
previewExternalCsv,
|
|
updateExternalCsvConfiguration,
|
|
} from "../src/frontend/utils/api.js";
|
|
import type { ExternalInitialImportPlanDto } from "../src/frontend/types.js";
|
|
import { createDefaultExternalCsvConfiguration } from "../src/external-model/csv/external-csv-contracts.js";
|
|
import { externalCsvTestColumns } from "./fixtures/revit-csv-fixtures.js";
|
|
|
|
describe("Revit CSV frontend API", () => {
|
|
it("uses the project-scoped configuration, preview and import endpoints", async () => {
|
|
const requests: Array<{ url: string; method: string; body: unknown }> = [];
|
|
const originalFetch = globalThis.fetch;
|
|
globalThis.fetch = async (input, init) => {
|
|
requests.push({
|
|
url: String(input),
|
|
method: init?.method ?? "GET",
|
|
body: init?.body ? JSON.parse(String(init.body)) : null,
|
|
});
|
|
return new Response(JSON.stringify({ configuration: null }), {
|
|
status: 200,
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
};
|
|
const configuration = createDefaultExternalCsvConfiguration(externalCsvTestColumns);
|
|
|
|
try {
|
|
await getExternalCsvConfiguration("project-1");
|
|
await updateExternalCsvConfiguration("project-1", 7, configuration);
|
|
await previewExternalCsv("project-1", "revit.csv", "YWJj");
|
|
await planExternalInitialImport("project-1", "revit.csv", "YWJj");
|
|
await applyExternalInitialImport("project-1", {
|
|
expectedRevision: 8,
|
|
expectedConfigurationVersion: 2,
|
|
expectedSha256: "sha",
|
|
fileName: "revit.csv",
|
|
contentBase64: "YWJj",
|
|
sourceName: "Revit-Gesamtmodell",
|
|
roomDecisions: [{ sourceRoomKey: "101|büro", roomId: "room-1", defaultDistributionBoardId: "board-1" }],
|
|
familyProjectDeviceDecisions: [{ familyAndType: "Steckdose : Standard", projectDeviceId: "device-1" }],
|
|
});
|
|
} finally {
|
|
globalThis.fetch = originalFetch;
|
|
}
|
|
|
|
assert.deepEqual(requests, [
|
|
{
|
|
url: "/api/projects/project-1/external-csv/configuration",
|
|
method: "GET",
|
|
body: null,
|
|
},
|
|
{
|
|
url: "/api/projects/project-1/external-csv/configuration",
|
|
method: "PUT",
|
|
body: { expectedRevision: 7, configuration },
|
|
},
|
|
{
|
|
url: "/api/projects/project-1/external-csv/preview",
|
|
method: "POST",
|
|
body: { fileName: "revit.csv", contentBase64: "YWJj" },
|
|
},
|
|
{
|
|
url: "/api/projects/project-1/external-csv/initial-import/plan",
|
|
method: "POST",
|
|
body: { fileName: "revit.csv", contentBase64: "YWJj" },
|
|
},
|
|
{
|
|
url: "/api/projects/project-1/external-csv/initial-import/apply",
|
|
method: "POST",
|
|
body: {
|
|
expectedRevision: 8,
|
|
expectedConfigurationVersion: 2,
|
|
expectedSha256: "sha",
|
|
fileName: "revit.csv",
|
|
contentBase64: "YWJj",
|
|
sourceName: "Revit-Gesamtmodell",
|
|
roomDecisions: [{ sourceRoomKey: "101|büro", roomId: "room-1", defaultDistributionBoardId: "board-1" }],
|
|
familyProjectDeviceDecisions: [{ familyAndType: "Steckdose : Standard", projectDeviceId: "device-1" }],
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("Revit CSV modal presentation", () => {
|
|
it("uses the viewport-wide dialog variant", () => {
|
|
const markup = renderToStaticMarkup(
|
|
createElement(RevitCsvModal, {
|
|
currentRevision: 0,
|
|
onClose: () => undefined,
|
|
onRevisionChange: () => undefined,
|
|
projectId: "project-1",
|
|
})
|
|
);
|
|
|
|
assert.match(markup, /max-width:calc\(100vw - 2rem\)/);
|
|
assert.doesNotMatch(markup, /modal-lg/);
|
|
});
|
|
|
|
it("renders the initial import decisions without individual object rows", () => {
|
|
const plan: ExternalInitialImportPlanDto = {
|
|
configurationVersion: 2,
|
|
fileName: "revit.csv",
|
|
sha256: "sha",
|
|
byteLength: 100,
|
|
rowCount: 2,
|
|
objectCount: 1,
|
|
passthroughCount: 1,
|
|
suspectObjectCount: 0,
|
|
suspectRowNumbers: [],
|
|
sourceRooms: [{
|
|
sourceRoomKey: "101|büro",
|
|
roomNumber: "101",
|
|
roomName: "Büro",
|
|
objectCount: 1,
|
|
suggestedRoomId: "room-1",
|
|
matchStatus: "exact-number",
|
|
candidateRoomIds: ["room-1"],
|
|
}],
|
|
familyGroups: [{
|
|
familyAndType: "Steckdose : Standard",
|
|
objectCount: 1,
|
|
classified: true,
|
|
category: "single_phase",
|
|
connectionKind: null,
|
|
internalDeviceType: "socket",
|
|
}],
|
|
issueCounts: { unknownFamilyAndType: 0, invalidPower: 0, invalidQuantity: 0, missingRoom: 0 },
|
|
objects: [],
|
|
existing: {
|
|
floors: [{ id: "floor-1", name: "EG", sortOrder: 0 }],
|
|
rooms: [{ id: "room-1", floorId: "floor-1", roomNumber: "101", roomName: "Büro" }],
|
|
distributionBoards: [{ id: "board-1", name: "UV-01", floorId: "floor-1" }],
|
|
projectDevices: [{ id: "device-1", name: "Steckdose", displayName: "Steckdose", category: "single_phase", connectionKind: null, powerPerUnit: 100 }],
|
|
},
|
|
};
|
|
const markup = renderToStaticMarkup(createElement(RevitCsvImportPlan, {
|
|
familyLinks: { "Steckdose : Standard": "device-1" },
|
|
isApplying: false,
|
|
onApply: () => undefined,
|
|
onFamilyLinkChange: () => undefined,
|
|
onRoomDecisionChange: () => undefined,
|
|
plan,
|
|
roomDecisions: { "101|büro": { roomId: "room-1", defaultDistributionBoardId: "board-1" } },
|
|
setSourceName: () => undefined,
|
|
sourceName: "Revit-Gesamtmodell",
|
|
}));
|
|
|
|
assert.match(markup, /Erstimport vorbereiten/);
|
|
assert.match(markup, /101 · Büro/);
|
|
assert.match(markup, /Steckdose : Standard/);
|
|
assert.match(markup, /Erstimport übernehmen/);
|
|
assert.doesNotMatch(markup, /IFC-GUID/);
|
|
});
|
|
});
|