import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { beforeEach, describe, expect, it } from 'vitest'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { RouterProvider, createMemoryHistory, createRootRoute, createRouter, } from '@tanstack/react-router'; import type { ReactNode } from 'react'; import type { Track } from '../types'; import { usePlaybackStore } from '../store/usePlaybackStore'; import { VibeTimeline } from './VibeTimeline'; 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, }); /** Track titles link to their album, so rows need a router in scope. */ function renderInRouter(ui: ReactNode) { const rootRoute = createRootRoute({ component: () => ui }); const router = createRouter({ routeTree: rootRoute, history: createMemoryHistory() }); return render( ); } describe('VibeTimeline', () => { beforeEach(() => { const current = track('current'); usePlaybackStore.setState({ currentTrack: current, queue: [current, track('upcoming')], currentIndex: 0, isPlaying: true, queueOwner: 'vibe', vibeAdvanceHandler: () => undefined, }); }); it('renders upcoming plan entries as display-only so they cannot hand queue ownership to ordinary playback', async () => { const user = userEvent.setup(); renderInRouter(); const queued = await screen.findAllByRole('button', { name: 'upcoming is queued by Vibe' }); expect(queued).toHaveLength(1); expect(queued[0]).toBeDisabled(); await user.click(queued[0]); expect(usePlaybackStore.getState()).toMatchObject({ queueOwner: 'vibe', currentTrack: track('current'), }); }); });