// @vitest-environment jsdom
import { afterEach, describe, expect, it } from 'vitest'
import { mount } from '@vue/test-utils'
import AudioPlayer from '@/components/ui/AudioPlayer.vue'
let wrapper = null
function mountPlayer(props = {}) {
wrapper = mount(AudioPlayer, {
props: { src: '/api/files/track.mp3', title: 'track.mp3', ...props },
attachTo: document.body,
})
return wrapper
}
afterEach(() => {
wrapper?.unmount()
wrapper = null
})
describe('AudioPlayer', () => {
it('wraps a hidden audio element and names the track', () => {
mountPlayer()
const audio = wrapper.find('audio.ap-audio-el')
expect(audio.exists()).toBe(true)
expect(audio.attributes('src')).toBe('/api/files/track.mp3')
expect(audio.attributes('controls')).toBeUndefined()
expect(wrapper.find('.ap-title').text()).toBe('track.mp3')
})
it('renders play, seek, mute and volume controls', () => {
mountPlayer()
// play, mute — both kit icon buttons
expect(wrapper.findAll('.ap-controls .btn-icon').length).toBe(2)
// seek and volume — two kit ranges
expect(wrapper.findAll('.ap-controls .range').length).toBe(2)
})
it('tightens itself for a card body', () => {
mountPlayer({ compact: true })
expect(wrapper.find('.audio-player').classes()).toContain('is-compact')
})
it('follows a new source', async () => {
mountPlayer()
await wrapper.setProps({ src: '/api/files/other.ogg', title: 'other.ogg' })
expect(wrapper.find('audio.ap-audio-el').attributes('src')).toBe('/api/files/other.ogg')
expect(wrapper.find('.ap-title').text()).toBe('other.ogg')
})
})