Add tests for song-list component

This commit is contained in:
Phan An 2018-01-07 22:38:30 +01:00
parent c329c434a5
commit 3ad4b8742f
2 changed files with 211 additions and 19 deletions

View file

@ -112,14 +112,7 @@ export default {
computed: {
filteredItems () {
const { keywords, fields } = this.extractSearchData(this.q)
if (!keywords) {
return this.songRows
}
return filterBy(
this.songRows,
keywords,
...(fields.length ? fields : ['song.title', 'song.album.name', 'song.artist.name'])
)
return keywords ? filterBy(this.songRows, keywords, ...fields) : this.songRows
},
/**
@ -253,8 +246,6 @@ export default {
// Play the first song selected if we're in Queue screen.
playback.play(this.selectedSongs[0])
break
case 'favorites':
case 'playlist':
default:
//
// --------------------------------------------------------------------
@ -264,19 +255,15 @@ export default {
// Shift+Enter: Queues song to top
// Cmd/Ctrl+Enter: Queues song to bottom and play the first selected song
// Cmd/Ctrl+Shift+Enter: Queue songs to top and play the first queued song
//
// Also, if there's only one song selected, play it right away.
// --------------------------------------------------------------------
//
queueStore.queue(this.selectedSongs, false, event.shiftKey)
this.$nextTick(() => {
router.go('queue')
if (event.ctrlKey || event.metaKey) {
playback.play(this.selectedSongs[0])
}
if (event.ctrlKey || event.metaKey || this.selectedSongs.length === 1) {
playback.play(this.selectedSongs[0])
}
})
router.go('queue')
break
}
@ -477,7 +464,10 @@ export default {
})
}
}
return { keywords, fields }
return {
keywords,
fields: fields.length ? fields : ['song.title', 'song.album.name', 'song.artist.name']
}
}
},

View file

@ -0,0 +1,202 @@
import Component from '@/components/shared/song-list.vue'
import factory from '@/tests/factory'
import { event } from '@/utils'
import { songStore, queueStore } from '@/stores'
import { playback } from '@/services'
import router from '@/router'
describe('components/shared/song-list', () => {
let songs
beforeEach(() => {
songs = factory('song', 20)
})
it('renders properly', () => {
const wrapper = mount(Component, { propsData: {
items: songs,
type: 'allSongs'
}})
})
it('informs parent to update meta data', () => {
const emitStub = sinon.stub(event, 'emit')
const getLengthStub = sinon.stub(songStore, 'getFormattedLength').callsFake(() => '12:34:56')
const wrapper = mount(Component, { propsData: {
items: songs,
type: 'allSongs'
}})
getLengthStub.calledWith(songs).should.be.true
emitStub.calledWith('updateMeta', {
songCount: songs.length,
totalLength: '12:34:56'
}, undefined).should.be.true
emitStub.restore()
getLengthStub.restore()
})
it('triggers sort', () => {
const wrapper = mount(Component, { propsData: {
items: songs,
type: 'allSongs'
}})
const sortStub = sinon.stub(wrapper.vm, 'sort')
const provider = {
'.track-number': 'song.track',
'.title': 'song.title',
'.artist': ['song.album.artist.name', 'song.album.name', 'song.track'],
'.album': ['song.album.name', 'song.track'],
'.time': 'song.length'
}
for (let selector in provider) {
wrapper.find(`.song-list-header ${selector}`).trigger('click')
sortStub.calledWith(provider[selector]).should.be.true
}
})
it('sorts', () => {
const wrapper = mount(Component, { propsData: {
items: songs,
type: 'allSongs'
}})
// track number
wrapper.find('.song-list-header .track-number').trigger('click')
for (let i = 1, j = wrapper.vm.songRows.length; i < j; ++i) {
(wrapper.vm.songRows[i].song.track >= wrapper.vm.songRows[i - 1].song.track).should.be.true
}
// second sort should be descending
wrapper.find('.song-list-header .track-number').trigger('click')
for (let i = 1, j = wrapper.vm.songRows.length; i < j; ++i) {
(wrapper.vm.songRows[i].song.track <= wrapper.vm.songRows[i - 1].song.track).should.be.true
}
// track number
wrapper.find('.song-list-header .title').trigger('click')
for (let i = 1, j = wrapper.vm.songRows.length; i < j; ++i) {
(wrapper.vm.songRows[i].song.title >= wrapper.vm.songRows[i - 1].song.title).should.be.true
}
wrapper.find('.song-list-header .title').trigger('click')
for (let i = 1, j = wrapper.vm.songRows.length; i < j; ++i) {
(wrapper.vm.songRows[i].song.title <= wrapper.vm.songRows[i - 1].song.title).should.be.true
}
// artist
wrapper.find('.song-list-header .artist').trigger('click')
for (let i = 1, j = wrapper.vm.songRows.length; i < j; ++i) {
(wrapper.vm.songRows[i].song.album.artist.name >= wrapper.vm.songRows[i - 1].song.album.artist.name).should.be.true
}
wrapper.find('.song-list-header .artist').trigger('click')
for (let i = 1, j = wrapper.vm.songRows.length; i < j; ++i) {
(wrapper.vm.songRows[i].song.album.artist.name <= wrapper.vm.songRows[i - 1].song.album.artist.name).should.be.true
}
// album
wrapper.find('.song-list-header .album').trigger('click')
for (let i = 1, j = wrapper.vm.songRows.length; i < j; ++i) {
(wrapper.vm.songRows[i].song.album.name >= wrapper.vm.songRows[i - 1].song.album.name).should.be.true
}
wrapper.find('.song-list-header .album').trigger('click')
for (let i = 1, j = wrapper.vm.songRows.length; i < j; ++i) {
(wrapper.vm.songRows[i].song.album.name <= wrapper.vm.songRows[i - 1].song.album.name).should.be.true
}
})
it('takes disc into account when sort an album song list', () => {
const wrapper = mount(Component, { propsData: {
items: songs,
type: 'album'
}})
wrapper.vm.sort()
wrapper.vm.sortKey.includes('song.disc').should.be.true
})
it('extracts search data from a search query', () => {
const provider = {
'foo': { keywords: 'foo', fields: ['song.title', 'song.album.name', 'song.artist.name'] },
'foo in:title': { keywords: 'foo', fields: ['song.title'] },
'in:album foo bar': { keywords: 'foo bar', fields: ['song.album.name'] },
'foo bar in:artist': { keywords: 'foo bar', fields: ['song.artist.name'] },
'foo in:album in:artist': { keywords: 'foo', fields: ['song.album.name', 'song.artist.name'] }
}
const wrapper = shallow(Component)
for (let q in provider) {
wrapper.vm.extractSearchData(q).should.eql(provider[q])
}
})
it('plays when Enter is pressed with one selected song', () => {
const wrapper = mount(Component, { propsData: {
items: songs,
type: 'allSongs'
}})
// select one row
wrapper.vm.filteredItems[0].selected = true
const playStub = sinon.stub(playback, 'play')
wrapper.find('.song-list-wrap').trigger('keydown.enter')
playStub.calledWith(songs[0]).should.be.true
playStub.restore()
})
it('plays when Enter is pressed in Queue screen', () => {
const wrapper = mount(Component, { propsData: {
items: songs,
type: 'queue'
}})
const playStub = sinon.stub(playback, 'play')
wrapper.vm.filteredItems[0].selected = true
wrapper.vm.filteredItems[1].selected = true
wrapper.find('.song-list-wrap').trigger('keydown.enter')
playStub.calledWith(songs[0]).should.be.true
playStub.restore()
})
it('queues when Enter is pressed in other screens', () => {
const wrapper = mount(Component, { propsData: {
items: songs,
type: 'playlist'
}})
const queueStub = sinon.stub(queueStore, 'queue')
const goStub = sinon.stub(router, 'go')
const playStub = sinon.stub(playback, 'play')
// select 2 rows
wrapper.vm.filteredItems[0].selected = true
wrapper.vm.filteredItems[1].selected = true
// simple Enter adds selected songs to bottom
wrapper.find('.song-list-wrap').trigger('keydown.enter')
queueStub.calledWith(wrapper.vm.selectedSongs, false, undefined).should.be.true
// the current screen should be switched to "Queue"
goStub.calledWith('queue').should.be.true
// Shift+Enter queues to top
wrapper.find('.song-list-wrap').trigger('keydown.enter', { shiftKey: true })
queueStub.calledWith(wrapper.vm.selectedSongs, false, true).should.be.true
goStub.calledWith('queue').should.be.true
// Ctrl[+Shift]+Enter queues and plays the first song
wrapper.find('.song-list-wrap').trigger('keydown.enter', { ctrlKey: true })
playStub.calledWith(wrapper.vm.selectedSongs[0]).should.be.true
playStub.called.should.be.true
queueStub.restore()
goStub.restore()
playStub.restore()
})
it('selects all songs', () => {
const wrapper = mount(Component, { propsData: {
items: songs,
type: 'playlist'
}})
wrapper.find('.song-list-wrap').trigger('keydown.a', { ctrlKey: true })
wrapper.vm.filteredItems.forEach(item => item.selected.should.be.true)
})
})