1import { afterEach, describe, expect, it, vi } from "vite-plus/test";
2
3import { playSnapShotSound } from "./snapShotSound";
4
5afterEach(() => {
6 Reflect.deleteProperty(globalThis, "Audio");
7 vi.restoreAllMocks();
8});
9
10describe("playSnapShotSound", () => {
11 it.each([
12 ["soft-pop", /snap-shot-whoosh\.mp3/],
13 ["camera-shutter", /snap-shot-click\.mp3/],
14 ] as const)("plays the %s sound from its first sample", (selection, expectedUrl) => {
15 const sound = {
16 currentTime: 3,
17 play: vi.fn().mockResolvedValue(undefined),
18 preload: "none",
19 };
20 const AudioMock = vi.fn(function AudioMock() {
21 return sound;
22 });
23 Object.defineProperty(globalThis, "Audio", {
24 configurable: true,
25 value: AudioMock,
26 });
27
28 playSnapShotSound(selection);
29
30 expect(AudioMock).toHaveBeenCalledWith(expect.stringMatching(expectedUrl));
31 expect(sound.preload).toBe("auto");
32 expect(sound.currentTime).toBe(0);
33 expect(sound.play).toHaveBeenCalledOnce();
34 });
35 it("ignores blocked playback", async () => {
36 const sound = {
37 currentTime: 0,
38 play: vi.fn().mockRejectedValue(new Error("blocked")),
39 preload: "none",
40 };
41 Object.defineProperty(globalThis, "Audio", {
42 configurable: true,
43 value: vi.fn(function AudioMock() {
44 return sound;
45 }),
46 });
47
48 expect(() => playSnapShotSound("soft-pop")).not.toThrow();
49 await vi.waitFor(() => expect(sound.play).toHaveBeenCalledOnce());
50 });
51});