73 lines
2.8 KiB
TypeScript
73 lines
2.8 KiB
TypeScript
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||
|
|
import { render, screen, waitFor } from '@testing-library/react'
|
||
|
|
import userEvent from '@testing-library/user-event'
|
||
|
|
import { PlayerProvider, usePlayer } from '../src/player/PlayerContext.js'
|
||
|
|
import MiniBar from '../src/player/MiniBar.js'
|
||
|
|
import type { Track } from '../src/types.js'
|
||
|
|
|
||
|
|
vi.mock('../src/api.js', async (importOriginal) => {
|
||
|
|
const actual = await importOriginal<typeof import('../src/api.js')>()
|
||
|
|
return { ...actual, api: { ...actual.api, getAlbumTracks: vi.fn(), markPlayed: vi.fn() } }
|
||
|
|
})
|
||
|
|
import { api } from '../src/api.js'
|
||
|
|
|
||
|
|
const tracks: Track[] = [
|
||
|
|
{ id: 's1', title: 'Overture', duration: 200, track: 1 },
|
||
|
|
{ id: 's2', title: 'Theme de Yoyo', duration: 300, track: 2 },
|
||
|
|
]
|
||
|
|
|
||
|
|
function Loader() {
|
||
|
|
const { load } = usePlayer()
|
||
|
|
return (
|
||
|
|
<button type="button" onClick={() => void load({ id: 'a1', title: 'Motion', artist: 'TCO' })}>
|
||
|
|
load
|
||
|
|
</button>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
vi.spyOn(HTMLMediaElement.prototype, 'play').mockResolvedValue()
|
||
|
|
vi.spyOn(HTMLMediaElement.prototype, 'pause').mockReturnValue(undefined)
|
||
|
|
vi.mocked(api.getAlbumTracks).mockResolvedValue({ id: 'a1', title: 'Motion', artist: 'TCO', tracks } as never)
|
||
|
|
vi.mocked(api.markPlayed).mockResolvedValue({ ok: true } as never)
|
||
|
|
})
|
||
|
|
|
||
|
|
function renderBar() {
|
||
|
|
return render(
|
||
|
|
<PlayerProvider>
|
||
|
|
<Loader />
|
||
|
|
<MiniBar />
|
||
|
|
</PlayerProvider>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('MiniBar', () => {
|
||
|
|
it('hidden when nothing is loaded, shows controls when playing', async () => {
|
||
|
|
renderBar()
|
||
|
|
expect(screen.queryByRole('button', { name: /play or pause/i })).toBeNull()
|
||
|
|
await userEvent.click(screen.getByRole('button', { name: 'load' }))
|
||
|
|
await waitFor(() => expect(screen.getByText('Motion')).toBeTruthy())
|
||
|
|
expect(screen.getByRole('button', { name: /pause/i })).toBeTruthy()
|
||
|
|
})
|
||
|
|
|
||
|
|
it('pause/resume works from the bar', async () => {
|
||
|
|
renderBar()
|
||
|
|
await userEvent.click(screen.getByRole('button', { name: 'load' }))
|
||
|
|
const pauseBtn = await screen.findByRole('button', { name: /pause/i })
|
||
|
|
await userEvent.click(pauseBtn)
|
||
|
|
expect(screen.getByRole('button', { name: 'play' })).toBeTruthy()
|
||
|
|
})
|
||
|
|
|
||
|
|
it('expands to the track list and closes', async () => {
|
||
|
|
renderBar()
|
||
|
|
await userEvent.click(screen.getByRole('button', { name: 'load' }))
|
||
|
|
await userEvent.click(await screen.findByRole('button', { name: /expand/i }))
|
||
|
|
expect(screen.getByText(/Theme de Yoyo/)).toBeTruthy()
|
||
|
|
expect(screen.getByText(/Overture/)).toBeTruthy()
|
||
|
|
await userEvent.click(screen.getByRole('button', { name: /collapse/i }))
|
||
|
|
expect(screen.queryByText(/Theme de Yoyo/)).toBeNull()
|
||
|
|
await userEvent.click(screen.getByRole('button', { name: /close player/i }))
|
||
|
|
await waitFor(() => expect(screen.queryByText('Motion')).toBeNull())
|
||
|
|
})
|
||
|
|
})
|