mirror of
https://github.com/koel/koel
synced 2024-11-10 14:44:13 +00:00
feat(test): EpisodeItem tests
This commit is contained in:
parent
e6be6568cf
commit
cc5f47f96d
3 changed files with 103 additions and 11 deletions
|
@ -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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 }
|
||||
|
|
Loading…
Reference in a new issue