import { describe, expect, it, vi } from "vitest"; import { encodeToolcraftModelDocument } from "../model-import/canonical/model-document-codec"; import { digestToolcraftModelDocument } from "../model-import/canonical/model-document-digest"; import { createValidModelDocument } from "../model-import/canonical/model-document-test-support"; import { TOOLCRAFT_PRODUCTION_MODEL_FORMAT_ADAPTER_REGISTRY } from "../model-import/formats/production-model-format-registry"; import { createHydrationModelAsset } from "../model-import/model-persistence-hydration-test-support"; import { createToolcraftModelDocumentResourceRef, TOOLCRAFT_MODEL_DOCUMENT_CONTENT_TYPE, } from "../model-import/model-source-asset-handler-resources"; import { createToolcraftModelSourceBundleDescriptorResource } from "../model-import/model-source-bundle-codec"; import { createToolcraftModelSourceBundleSnapshot } from "../model-import/model-source-bundle"; import { createMemoryToolcraftBinaryAssetRepository } from "./repository/memory-binary-asset-repository"; import { createToolcraftSettingsAttachments, parseToolcraftSettingsAttachments, resolveToolcraftSettingsAsset, } from "./settings-media"; describe("settings model attachments", () => { it("preserves model source paths and validates both the document and source dependency availability", async () => { const repository = createMemoryToolcraftBinaryAssetRepository(); const snapshot = await createToolcraftModelSourceBundleSnapshot( [ new File([new Uint8Array([1, 2, 3, 4])], "cube.glb", { type: "model/gltf-binary", }), ], { registry: TOOLCRAFT_PRODUCTION_MODEL_FORMAT_ADAPTER_REGISTRY }, ); const descriptor = createToolcraftModelSourceBundleDescriptorResource( snapshot.bundle, ); const document = createValidModelDocument(); const documentRef = createToolcraftModelDocumentResourceRef( digestToolcraftModelDocument(document), ); const lease = await repository.beginLease("model-settings"); for (const source of snapshot.bundle.sourceFiles) { const transfer = snapshot.transfer.sourceFiles.find( ({ path }) => path === source.path, )!; await lease.put(source.resourceRef, new Uint8Array(transfer.bytes), { contentType: source.mimeType, durable: true, }); } await lease.put( descriptor.sourceBundleRef, descriptor.bytes, descriptor.stageOptions, ); await lease.put(documentRef, encodeToolcraftModelDocument(document), { contentType: TOOLCRAFT_MODEL_DOCUMENT_CONTENT_TYPE, durable: false, }); await lease.commit(); const asset = createHydrationModelAsset(documentRef, { lifecycle: "clean", sourceBundleRef: descriptor.sourceBundleRef, sourceBundleDigest: snapshot.bundle.aggregateDigest, sourcePaths: ["models/cube.glb"], }); const manifest = createToolcraftSettingsAttachments([asset]); expect(manifest[0]?.paths).toEqual(["models/cube.glb"]); const parsed = parseToolcraftSettingsAttachments(manifest)[0]?.asset; expect(parsed?.lifecycle).toBe("restoring"); expect(await resolveToolcraftSettingsAsset(parsed!, repository)).toEqual( asset, ); const get = repository.get.bind(repository); vi.spyOn(repository, "get").mockImplementation((ref) => ref === snapshot.bundle.sourceFiles[0]?.resourceRef ? Promise.resolve(null) : get(ref), ); expect(await resolveToolcraftSettingsAsset(parsed!, repository)).toBeNull(); }); });