fix: guard media controller playback transitions

This commit is contained in:
MythEclipse
2026-05-15 17:40:28 +07:00
parent dbae042279
commit b00def2d4d
2 changed files with 75 additions and 7 deletions
+52
View File
@@ -112,6 +112,58 @@ describe("MediaController", () => {
expect(state.current?.title).toBe("second.mp3");
});
it("ignores stale completion after skip starts the next item", async () => {
const first = deferred();
const second = deferred();
const third = deferred();
const musicPlayer: MusicPlayer = {
play: vi
.fn()
.mockReturnValueOnce({ done: first.promise, stop: vi.fn() })
.mockReturnValueOnce({ done: second.promise, stop: vi.fn() })
.mockReturnValueOnce({ done: third.promise, stop: vi.fn() }),
};
const controller = new MediaController({
isVoiceConnected: () => true,
isBrowserStreaming: () => false,
resolveMediaSource: async (input) => source(input),
musicPlayer,
});
await controller.queue("https://example.com/first.mp3");
await controller.queue("https://example.com/second.mp3");
await controller.queue("https://example.com/third.mp3");
await controller.skip();
first.resolve();
await new Promise((resolve) => setImmediate(resolve));
expect(controller.getState().current?.title).toBe("second.mp3");
expect(musicPlayer.play).toHaveBeenCalledTimes(2);
});
it("advances when player throws while starting an item", async () => {
const second = deferred();
const musicPlayer: MusicPlayer = {
play: vi
.fn()
.mockImplementationOnce(() => {
throw new Error("not connected");
})
.mockReturnValueOnce({ done: second.promise, stop: vi.fn() }),
};
const controller = new MediaController({
isVoiceConnected: () => true,
isBrowserStreaming: () => false,
resolveMediaSource: async (input) => source(input),
musicPlayer,
});
await controller.queue("https://example.com/first.mp3");
await controller.queue("https://example.com/second.mp3");
expect(controller.getState().current?.title).toBe("second.mp3");
});
it("stops current playback and clears the queue", async () => {
const stop = vi.fn();
const controller = new MediaController({