diff --git a/tests/unit/audio-assets.test.ts b/tests/unit/audio-assets.test.ts new file mode 100644 index 00000000..33561a12 --- /dev/null +++ b/tests/unit/audio-assets.test.ts @@ -0,0 +1,71 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { createInMemoryProjectAssetStorage } from "../../src/assets/project-asset-storage"; +import { importAudioAssetFromFile, loadAudioAssetFromStorage } from "../../src/assets/audio-assets"; + +describe("audio asset import and storage", () => { + afterEach(() => { + vi.unstubAllGlobals(); + }); + + it("persists audio through the generic project asset storage and reloads decoded buffers", async () => { + const decodedBuffer = { + duration: 2.5, + numberOfChannels: 2, + sampleRate: 44100 + } as AudioBuffer; + const decodeCalls: ArrayBuffer[] = []; + const closeCalls: number[] = []; + + class MockAudioContext { + readonly state = "running" as const; + + async decodeAudioData(bytes: ArrayBuffer): Promise { + decodeCalls.push(bytes); + return decodedBuffer; + } + + async close(): Promise { + closeCalls.push(1); + } + } + + vi.stubGlobal("AudioContext", MockAudioContext); + vi.stubGlobal("webkitAudioContext", MockAudioContext); + + const storage = createInMemoryProjectAssetStorage(); + const fileBytes = new Uint8Array([1, 2, 3, 4]).buffer; + const file = new File([fileBytes], "lobby-loop.ogg", { type: "audio/ogg" }); + + const importedAudio = await importAudioAssetFromFile(file, storage); + const storedAsset = await storage.getAsset(importedAudio.asset.storageKey); + const reloadedAudio = await loadAudioAssetFromStorage(storage, importedAudio.asset); + + expect(importedAudio.asset).toMatchObject({ + kind: "audio", + sourceName: "lobby-loop.ogg", + mimeType: "audio/ogg", + byteLength: fileBytes.byteLength + }); + expect(importedAudio.asset.metadata).toMatchObject({ + kind: "audio", + durationSeconds: 2.5, + channelCount: 2, + sampleRateHz: 44100 + }); + expect(storedAsset).toEqual({ + files: { + "lobby-loop.ogg": { + bytes: fileBytes, + mimeType: "audio/ogg" + } + } + }); + expect(reloadedAudio.assetId).toBe(importedAudio.asset.id); + expect(reloadedAudio.storageKey).toBe(importedAudio.asset.storageKey); + expect(reloadedAudio.metadata).toEqual(importedAudio.asset.metadata); + expect(reloadedAudio.buffer).toBe(decodedBuffer); + expect(decodeCalls).toHaveLength(2); + expect(closeCalls).toHaveLength(2); + }); +});