import { describe, expect, it } from "@suaveplan/testing/runner"; import { AUDIO_FX_CODES, AudioFxError } from "../error-codes/error-codes.js"; import { assertPresetMatchesPluginType, assertPresetVersionSupported, PresetSnapshotSchema, parsePresetSnapshot, } from "./preset.js"; describe("preset: parsePresetSnapshot", () => { it("accepts a minimal valid envelope", { timeout: 5_000 }, () => { const parsed = parsePresetSnapshot({ schemaVersion: 1, pluginType: "eq", parameters: { gain: 0 }, }); expect(parsed.schemaVersion).toBe(1); expect(parsed.pluginType).toBe("eq"); expect(parsed.parameters.gain).toBe(0); expect(parsed.data).toBeUndefined(); }); it("accepts an envelope with plugin-specific data blob", { timeout: 5_000, }, () => { const parsed = parsePresetSnapshot({ schemaVersion: 2, pluginType: "eq", parameters: {}, data: { bands: [{ freq: 100, gain: 3 }] }, }); expect(parsed.data).toEqual({ bands: [{ freq: 100, gain: 3 }] }); }); it("rejects missing required fields with AUDIO_FX.INVALID_PRESET", { timeout: 5_000, }, () => { try { parsePresetSnapshot({ pluginType: "eq", parameters: {} }); } catch (error) { expect(error).toBeInstanceOf(AudioFxError); const fxError = error as AudioFxError; expect(fxError.code).toBe(AUDIO_FX_CODES.INVALID_PRESET); expect(fxError.context?.issues).toBeDefined(); return; } throw new Error("expected parsePresetSnapshot to throw"); }); it("rejects negative schemaVersion", { timeout: 5_000 }, () => { try { parsePresetSnapshot({ schemaVersion: -1, pluginType: "eq", parameters: {}, }); } catch (error) { expect((error as AudioFxError).code).toBe( AUDIO_FX_CODES.INVALID_PRESET ); return; } throw new Error("expected parsePresetSnapshot to throw"); }); it("rejects non-number parameter values", { timeout: 5_000 }, () => { try { parsePresetSnapshot({ schemaVersion: 1, pluginType: "eq", parameters: { gain: "loud" }, }); } catch (error) { expect((error as AudioFxError).code).toBe( AUDIO_FX_CODES.INVALID_PRESET ); return; } throw new Error("expected parsePresetSnapshot to throw"); }); it("rejects empty pluginType", { timeout: 5_000 }, () => { try { parsePresetSnapshot({ schemaVersion: 1, pluginType: "", parameters: {}, }); } catch (error) { expect((error as AudioFxError).code).toBe( AUDIO_FX_CODES.INVALID_PRESET ); return; } throw new Error("expected parsePresetSnapshot to throw"); }); }); describe("preset: PresetSnapshotSchema direct usage", () => { it("exposes the same schema for callers that want safeParse directly", { timeout: 5_000, }, () => { const ok = PresetSnapshotSchema.safeParse({ schemaVersion: 1, pluginType: "eq", parameters: {}, }); expect(ok.success).toBe(true); }); }); describe("preset: assertPresetVersionSupported", () => { it("passes when preset version <= supported", { timeout: 5_000, }, () => { const preset = parsePresetSnapshot({ schemaVersion: 1, pluginType: "eq", parameters: {}, }); expect(() => assertPresetVersionSupported(preset, 1)).not.toThrow(); expect(() => assertPresetVersionSupported(preset, 2)).not.toThrow(); }); it("throws AUDIO_FX.PRESET_VERSION_UNSUPPORTED when preset version > supported", { timeout: 5_000, }, () => { const preset = parsePresetSnapshot({ schemaVersion: 3, pluginType: "eq", parameters: {}, }); try { assertPresetVersionSupported(preset, 1); } catch (error) { const fxError = error as AudioFxError; expect(fxError.code).toBe( AUDIO_FX_CODES.PRESET_VERSION_UNSUPPORTED ); expect(fxError.context?.presetVersion).toBe(3); expect(fxError.context?.supported).toBe(1); return; } throw new Error("expected assertPresetVersionSupported to throw"); }); }); describe("preset: assertPresetMatchesPluginType", () => { it("passes when pluginType matches", { timeout: 5_000 }, () => { const preset = parsePresetSnapshot({ schemaVersion: 1, pluginType: "eq", parameters: {}, }); expect(() => assertPresetMatchesPluginType(preset, "eq")).not.toThrow(); }); it("throws AUDIO_FX.INVALID_PRESET when pluginType differs", { timeout: 5_000, }, () => { const preset = parsePresetSnapshot({ schemaVersion: 1, pluginType: "reverb", parameters: {}, }); try { assertPresetMatchesPluginType(preset, "eq"); } catch (error) { const fxError = error as AudioFxError; expect(fxError.code).toBe(AUDIO_FX_CODES.INVALID_PRESET); expect(fxError.context?.presetPluginType).toBe("reverb"); expect(fxError.context?.expected).toBe("eq"); return; } throw new Error("expected assertPresetMatchesPluginType to throw"); }); });