feat(vibe): reconcile mutable session previews in playback
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import type { Track } from '../types';
|
||||
import { usePlaybackStore } from '../store/usePlaybackStore';
|
||||
import { useVibeStore } from '../store/useVibeStore';
|
||||
|
||||
const { advancePastUnplayableVibeTrack, reportVibeEvent } = vi.hoisted(() => ({
|
||||
advancePastUnplayableVibeTrack: vi.fn().mockResolvedValue(undefined),
|
||||
reportVibeEvent: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
vi.mock('../services/vibeSession', () => ({ advancePastUnplayableVibeTrack, reportVibeEvent }));
|
||||
|
||||
import { AudioEngine } from './AudioEngine';
|
||||
|
||||
const track = (id: string): Track => ({
|
||||
id, path: `/music/${id}.mp3`, hash: id, title: id, artist: 'Artist', album_id: 'album',
|
||||
duration: 180, state: 'LIBRARY', source_type: 'MANUAL', play_count: 0, skip_count: 0, dislike_count: 0,
|
||||
});
|
||||
|
||||
describe('AudioEngine', () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(HTMLMediaElement.prototype, 'load').mockImplementation(() => undefined);
|
||||
vi.spyOn(HTMLMediaElement.prototype, 'play').mockResolvedValue(undefined);
|
||||
useVibeStore.getState().reset();
|
||||
useVibeStore.getState().setActiveSession({ sessionId: 'session-a', seedTrackId: 'song' });
|
||||
usePlaybackStore.setState({
|
||||
currentTrack: track('song'), queue: [track('song')], currentIndex: 0, isPlaying: false,
|
||||
queueOwner: 'vibe', vibeAdvanceHandler: () => undefined,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => vi.restoreAllMocks());
|
||||
|
||||
it('uses the durable unplayable advancement when a Vibe stream errors after metadata resolved', async () => {
|
||||
const { container } = render(<AudioEngine />);
|
||||
const audio = container.querySelector('audio')!;
|
||||
|
||||
audio.dispatchEvent(new Event('error'));
|
||||
audio.dispatchEvent(new Event('error'));
|
||||
|
||||
await waitFor(() => expect(advancePastUnplayableVibeTrack).toHaveBeenCalledWith('song'));
|
||||
expect(advancePastUnplayableVibeTrack).toHaveBeenCalledTimes(1);
|
||||
expect(reportVibeEvent).not.toHaveBeenCalledWith('skipped', 'song');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user