feat(test): some remote controller tests

This commit is contained in:
Phan An 2024-06-03 14:13:55 +08:00
parent f14cbcd00a
commit 4e1838c247
5 changed files with 145 additions and 4 deletions

View file

@ -0,0 +1,46 @@
import { expect, it } from 'vitest'
import UnitTestCase from '@/__tests__/UnitTestCase'
import factory from '@/__tests__/factory'
import Component from './PlayableDetails.vue'
new class extends UnitTestCase {
private renderComponent (playable: Playable) {
return this.render(Component, {
props: {
playable
},
global: {
provide: {
state: {
playable,
volume: 7
}
}
}
})
}
protected test () {
it('renders a song', () => {
const { html } = this.renderComponent(factory('song', {
title: 'Afraid to Shoot Strangers',
album_name: 'Fear of the Dark',
artist_name: 'Iron Maiden',
album_cover: 'https://cover.site/fotd.jpg'
}))
expect(html()).toMatchSnapshot()
})
it('renders an episode', () => {
const { html } = this.renderComponent(factory('episode', {
title: 'Brahms Piano Concerto No. 1',
podcast_title: 'The Sticky Notes podcast',
podcast_author: 'Some random dudes',
episode_image: 'https://cover.site/pod.jpg'
}))
expect(html()).toMatchSnapshot()
})
}
}

View file

@ -0,0 +1,72 @@
import { screen } from '@testing-library/vue'
import { expect, it } from 'vitest'
import UnitTestCase from '@/__tests__/UnitTestCase'
import factory from '@/__tests__/factory'
import { socketService } from '@/services'
import Component from './RemoteFooter.vue'
new class extends UnitTestCase {
private renderComponent (playable?: Playable) {
playable = playable || factory('song')
this.render(Component, {
props: {
playable
},
global: {
components: {
Icon: this.stub('Icon'),
VolumeControl: this.stub('volume-control')
},
provide: {
state: {
playable,
volume: 7
}
}
}
})
}
protected test () {
it('toggles like', async () => {
const broadcastMock = this.mock(socketService, 'broadcast')
const playable = factory('song', { liked: false })
this.renderComponent(playable)
await this.user.click(screen.getByTestId('btn-toggle-favorite'))
expect(broadcastMock).toHaveBeenCalledWith('SOCKET_TOGGLE_FAVORITE')
expect(playable.liked).toBe(true)
})
it('plays previous', async () => {
const broadcastMock = this.mock(socketService, 'broadcast')
this.renderComponent()
await this.user.click(screen.getByTestId('btn-play-prev'))
expect(broadcastMock).toHaveBeenCalledWith('SOCKET_PLAY_PREV')
})
it('plays next', async () => {
const broadcastMock = this.mock(socketService, 'broadcast')
this.renderComponent()
await this.user.click(screen.getByTestId('btn-play-next'))
expect(broadcastMock).toHaveBeenCalledWith('SOCKET_PLAY_NEXT')
})
it.each<[string, PlaybackState, PlaybackState]>([
['pauses', 'Playing', 'Paused'],
['resumes', 'Paused', 'Playing'],
['starts', 'Stopped', 'Playing']
])('%s playback', async (_, currentState, newState) => {
const broadcastMock = this.mock(socketService, 'broadcast')
const playable = factory('episode', { playback_state: currentState })
this.renderComponent(playable)
await this.user.click(screen.getByTestId('btn-toggle-playback'))
expect(broadcastMock).toHaveBeenCalledWith('SOCKET_TOGGLE_PLAYBACK')
expect(playable.playback_state).toBe(newState)
})
}
}

View file

@ -2,7 +2,7 @@
<footer class="h-[18vh] w-screen flex justify-around items-center border-t border-solid border-t-white/10 py-4">
<button
class="text-[5vmin] has-[.yep]:text-k-love"
data-testid="btn-toggle-like"
data-testid="btn-toggle-favorite"
@click.prevent="toggleFavorite"
>
<Icon :class="playable.liked && 'yep'" :icon="playable.liked ? faHeart : faEmptyHeart" />

View file

@ -28,9 +28,7 @@ const closeVolumeSlider = () => (showingVolumeSlider.value = false)
const state = inject<RemoteState>('state')
watch(() => state?.volume, volume => {
volumeSlider.value?.noUiSlider?.set(volume || DEFAULT_VOLUME)
})
watch(() => state?.volume, volume => volumeSlider.value?.noUiSlider?.set(volume || DEFAULT_VOLUME))
onMounted(() => {
noUISlider.create(volumeSlider.value!, {

View file

@ -0,0 +1,25 @@
// Vitest Snapshot v1
exports[`renders a song 1`] = `
<article data-v-4daf3e78="" class="flex-1 flex flex-col items-center justify-around w-screen"><img data-v-4daf3e78="" src="https://cover.site/fotd.jpg" class="my-0 mx-auto w-[calc(70vw_+_4px)] aspect-square rounded-full border-2 border-solid border-k-text-primary object-center object-cover" alt="Cover art">
<div data-v-4daf3e78="" class="w-full flex flex-col justify-around px-6">
<div data-v-4daf3e78="">
<p data-v-4daf3e78="" class="text-[6vmin] font-bold mx-auto mb-4">Afraid to Shoot Strangers</p>
<p data-v-4daf3e78="" class="text-[5vmin] mb-2 opacity-50">Iron Maiden</p>
<p data-v-4daf3e78="" class="text-[4vmin] opacity-50">Fear of the Dark</p>
</div>
</div>
</article>
`;
exports[`renders an episode 1`] = `
<article data-v-4daf3e78="" class="flex-1 flex flex-col items-center justify-around w-screen"><img data-v-4daf3e78="" src="https://cover.site/pod.jpg" class="my-0 mx-auto w-[calc(70vw_+_4px)] aspect-square rounded-full border-2 border-solid border-k-text-primary object-center object-cover" alt="Cover art">
<div data-v-4daf3e78="" class="w-full flex flex-col justify-around px-6">
<div data-v-4daf3e78="">
<p data-v-4daf3e78="" class="text-[6vmin] font-bold mx-auto mb-4">Brahms Piano Concerto No. 1</p>
<p data-v-4daf3e78="" class="text-[5vmin] mb-2 opacity-50">Some random dudes</p>
<p data-v-4daf3e78="" class="text-[4vmin] opacity-50">The Sticky Notes podcast</p>
</div>
</div>
</article>
`;