import { describe, expect, it } from "vitest"; import { createHydrationModelAsset } from "../model-import/model-persistence-hydration-test-support"; import { readMediaAssets } from "./persistence-reader-media"; const cleanAnalysis = createHydrationModelAsset( "model-document:analysis", ).analysis; const repairableAnalysis = { ...cleanAnalysis, boundaryEdges: 2, outcome: "repairable" as const, repairPlanRef: "model-repair-plan:one", }; function createPersistedModel(lifecycle: "clean" | "fixed" | "repairable") { if (lifecycle === "fixed") { return createHydrationModelAsset("model-document:repaired", { analysis: cleanAnalysis, appliedRepairRecipeId: "repair-recipe:one", lifecycle, originalAnalysis: repairableAnalysis, originalDocumentRef: "model-document:original", repairedDocumentRef: "model-document:repaired", }); } const analysis = lifecycle === "repairable" ? repairableAnalysis : cleanAnalysis; return createHydrationModelAsset("model-document:original", { analysis, lifecycle, originalAnalysis: analysis, }); } function withoutProperty( value: T, key: TKey, ): Omit { const { [key]: _ignored, ...rest } = value; return rest; } describe("readMediaAssets current records", () => { it("restores exact current binary and model resource records", () => { const model = createHydrationModelAsset("model-document:active", { lifecycle: "clean", }); expect( readMediaAssets([ { assetKind: "image", fileName: "source.png", id: "image-1", layerId: "layer-image", lifecycle: "ready", mimeType: "image/png", position: { x: 4, y: 8 }, resourceRef: "media:image:source", size: { height: 64, unit: "px", width: 96 }, sourceSize: { height: 640, unit: "px", width: 960 }, }, model, ]), ).toEqual([ expect.objectContaining({ assetKind: "image", lifecycle: "restoring", resourceRef: "media:image:source", position: { x: 4, y: 8 }, size: { height: 64, unit: "px", width: 96 }, sourceSize: { height: 640, unit: "px", width: 960 }, }), expect.objectContaining({ activeDocumentRef: "model-document:active", assetKind: "model", lifecycle: "restoring", sourceBundleRef: model.sourceBundleRef, }), ]); }); it.each(["clean", "repairable", "fixed"] as const)( "restores a complete %s model record through the hydration boundary", (lifecycle) => { const model = createPersistedModel(lifecycle); expect(readMediaAssets([model])).toEqual([ expect.objectContaining({ activeDocumentRef: model.activeDocumentRef, analysis: model.analysis, assetKind: "model", lifecycle: "restoring", originalAnalysis: model.originalAnalysis, originalDocumentRef: model.originalDocumentRef, ...(lifecycle === "fixed" ? { appliedRepairRecipeId: model.appliedRepairRecipeId, repairedDocumentRef: model.repairedDocumentRef, } : {}), }), ]); }, ); it.each([ { dataUrl: "data:image/png;base64,AAAA", fileName: "missing-kind.png", id: "missing-kind", layerId: "layer-missing-kind", mimeType: "image/png", position: { x: 0, y: 0 }, }, { assetKind: "image", dataUrl: "data:image/png;base64,AAAA", fileName: "inline.png", id: "inline-image", layerId: "layer-inline", mimeType: "image/png", position: { x: 0, y: 0 }, }, { assetKind: "image", dataUrl: "data:image/png;base64,AAAA", fileName: "mixed.png", id: "mixed-image", layerId: "layer-mixed-image", mimeType: "image/png", position: { x: 0, y: 0 }, resourceRef: "media:image:mixed", }, { assetKind: "file", dataUrl: "data:application/octet-stream;base64,AAAA", fileName: "mixed.bin", id: "mixed-file", layerId: "layer-mixed-file", mimeType: "application/octet-stream", position: { x: 0, y: 0 }, resourceRef: "media:file:mixed", }, { ...createHydrationModelAsset("model-document:active"), sourceBundleRef: undefined, }, { ...createHydrationModelAsset("model-document:active"), originalAnalysis: undefined, }, { ...createHydrationModelAsset("model-document:active"), position: undefined, }, { ...createHydrationModelAsset("model-document:active"), size: undefined, }, { ...createHydrationModelAsset("model-document:active"), appliedRepairRecipeId: 42, }, { ...createHydrationModelAsset("model-document:active"), repairedDocumentRef: 42, }, { ...createHydrationModelAsset("model-document:active"), lastRepairError: { category: "resource-unavailable" }, }, { ...createHydrationModelAsset("model-document:active"), originalAnalysis: { ...createHydrationModelAsset("model-document:active").originalAnalysis, repairPlanRef: 42, }, }, ])("rejects a non-current media record %#", (record) => { expect(readMediaAssets([record])).toBeUndefined(); }); it.each([ { ...createPersistedModel("clean"), lifecycle: "restoring", }, { ...createPersistedModel("clean"), lifecycle: "unavailable", }, { ...createPersistedModel("clean"), activeDocumentRef: "model-document:other", }, { ...createPersistedModel("clean"), analysis: repairableAnalysis, }, { ...createPersistedModel("clean"), appliedRepairRecipeId: "repair-recipe:one", }, { ...createPersistedModel("clean"), appliedRepairRecipeId: "", }, { ...createPersistedModel("clean"), repairedDocumentRef: "", }, { ...createPersistedModel("repairable"), analysis: withoutProperty(repairableAnalysis, "repairPlanRef"), }, { ...createPersistedModel("repairable"), originalAnalysis: { ...repairableAnalysis, repairPlanRef: "model-repair-plan:other", }, }, { ...createPersistedModel("repairable"), repairedDocumentRef: "model-document:repaired", }, { ...createPersistedModel("repairable"), appliedRepairRecipeId: "", }, { ...createPersistedModel("repairable"), repairedDocumentRef: "", }, withoutProperty(createPersistedModel("fixed"), "appliedRepairRecipeId"), withoutProperty(createPersistedModel("fixed"), "repairedDocumentRef"), { ...createPersistedModel("fixed"), activeDocumentRef: "model-document:other", }, { ...createPersistedModel("fixed"), analysis: repairableAnalysis, }, { ...createPersistedModel("fixed"), originalAnalysis: cleanAnalysis, }, { ...createPersistedModel("fixed"), originalDocumentRef: "model-document:repaired", }, ])("rejects contradictory model lifecycle evidence %#", (record) => { expect(readMediaAssets([record])).toBeUndefined(); }); });