feat(test): EpisodeItem tests

This commit is contained in:
Phan An 2024-06-02 15:48:18 +08:00
parent e6be6568cf
commit cc5f47f96d
3 changed files with 103 additions and 11 deletions

View file

@ -4,6 +4,7 @@ import UnitTestCase from '@/__tests__/UnitTestCase'
import Component from './EpisodeItem.vue'
import factory from '@/__tests__/factory'
import { playbackService } from '@/services'
import { preferenceStore } from '@/stores'
new class extends UnitTestCase {
private renderComponent (episode: Episode, podcast?: Podcast) {
@ -15,6 +16,11 @@ new class extends UnitTestCase {
props: {
episode,
podcast
},
global: {
stubs: {
EpisodeProgress: this.stub('episode-progress-stub')
}
}
})
}
@ -23,16 +29,87 @@ new class extends UnitTestCase {
it('pauses playback', async () => {
const pauseMock = this.mock(playbackService, 'pause')
const episode = factory('episode', {
this.renderComponent(factory('episode', {
id: 'foo',
playback_state: 'Playing'
})
this.renderComponent(episode)
}))
await this.user.click(screen.getByRole('button'))
expect(pauseMock).toHaveBeenCalled()
})
it('resumes playback', async () => {
const resumeMock = this.mock(playbackService, 'resume')
this.renderComponent(factory('episode', {
id: 'foo',
playback_state: 'Paused'
}))
await this.user.click(screen.getByRole('button'))
expect(resumeMock).toHaveBeenCalled()
})
it.each([[600, 50, 50], [600, 650, 0], [600, null, 0]])(
'plays without continuous playback', async (episodeLength, currentPosition, startPlaybackPosition) => {
preferenceStore.temporary.continuous_playback = false
const playMock = this.mock(playbackService, 'play')
const episode = factory('episode', {
length: episodeLength
})
const podcast = factory('podcast', {
id: episode.podcast_id,
state: {
current_episode: episode.id,
progresses: {
[episode.id]: currentPosition
}
}
})
this.renderComponent(episode, podcast)
await this.user.click(screen.getByRole('button'))
expect(playMock).toHaveBeenCalledWith(episode, startPlaybackPosition)
}
)
it('plays from beginning if no saved progress', async () => {
const playMock = this.mock(playbackService, 'play')
const episode = factory('episode')
this.renderComponent(episode)
await this.user.click(screen.getByRole('button'))
expect(playMock).toHaveBeenCalledWith(episode, 0)
})
it('shows progress bar if there is progress', async () => {
const episode = factory('episode', {
length: 300
})
const podcast = factory('podcast', {
id: episode.podcast_id,
state: {
current_episode: episode.id,
progresses: {
[episode.id]: 100
}
}
})
this.renderComponent(episode, podcast)
screen.getByTestId('episode-progress-stub')
})
it('does not show progress bar if no progress', async () => {
this.renderComponent(factory('episode'))
expect(screen.queryByTestId('episode-progress-stub')).toBeNull()
})
}
}

View file

@ -50,17 +50,17 @@
</template>
<script setup lang="ts">
import { faBookmark, faPause, faPlay } from '@fortawesome/free-solid-svg-icons'
import DOMPurify from 'dompurify'
import { computed, toRefs } from 'vue'
import { orderBy } from 'lodash'
import { faBookmark, faPause, faPlay } from '@fortawesome/free-solid-svg-icons'
import { computed, defineAsyncComponent, toRefs } from 'vue'
import { eventBus, secondsToHis } from '@/utils'
import { useDraggable } from '@/composables'
import { formatTimeAgo } from '@vueuse/core'
import { playbackService } from '@/services'
import EpisodeProgress from '@/components/podcast/EpisodeProgress.vue'
import { preferenceStore as preferences, queueStore, songStore as episodeStore } from '@/stores'
import { orderBy } from 'lodash'
const EpisodeProgress = defineAsyncComponent(() => import('@/components/podcast/EpisodeProgress.vue'))
const props = defineProps<{ episode: Episode, podcast: Podcast }>()
const { episode, podcast } = toRefs(props)

View file

@ -25,6 +25,7 @@ export const defaultPreferences: UserPreferences = {
}
const preferenceStore = {
_temporary: false,
initialized: ref(false),
state: reactive<UserPreferences>(defaultPreferences),
@ -53,14 +54,28 @@ const preferenceStore = {
if (this.state[key] === value) return
this.state[key] = value
http.silently.patch('me/preferences', { key, value })
if (!this._temporary) {
http.silently.patch('me/preferences', { key, value })
} else {
this._temporary = false
}
},
get (key: string) {
return this.state?.[key]
},
// Calling preferenceStore.temporary.volume = 7 won't trigger saving.
// This is useful in tests as it doesn't create stray HTTP requests.
get temporary () {
this._temporary = true
return this as unknown as ExportedType
}
}
const exported = preferenceStore as unknown as Omit<typeof preferenceStore, 'setupProxy'> & UserPreferences
type ExportedType = Omit<typeof preferenceStore, 'setupProxy' | '_temporary'> & UserPreferences
const exported = preferenceStore as unknown as ExportedType
export { exported as preferenceStore }