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/); }); });