chore: clean up obsolete tests

This commit is contained in:
Phan An 2022-05-12 11:55:13 +02:00
parent a60cf1eb94
commit 3e1c8c8d4e
No known key found for this signature in database
GPG key ID: A81E4477F0BB6FDC
26 changed files with 0 additions and 1120 deletions

View file

@ -1,54 +0,0 @@
import Component from '@/components/album/AlbumContextMenu.vue'
import factory from '@/__tests__/factory'
import { downloadService, playbackService } from '@/services'
import { commonStore } from '@/stores'
import { mock } from '@/__tests__/__helpers__'
import { mount, shallow } from '@/__tests__/adapter'
describe('components/album/ContextMenuBase', () => {
let album: Album
beforeEach(() => {
album = factory<Album>('album')
// @ts-ignore
commonStore.state = { allowDownload: true }
})
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('plays all', () => {
const wrapper = shallow(Component, { propsData: { album } })
const m = mock(playbackService, 'playAllInAlbum')
wrapper.click('[data-testid=play]')
expect(m).toHaveBeenCalledWith(album)
})
it('shuffles', () => {
const wrapper = shallow(Component, { propsData: { album } })
const m = mock(playbackService, 'playAllInAlbum')
wrapper.click('[data-testid=shuffle]')
expect(m).toHaveBeenCalledWith(album, true)
})
it('downloads', async () => {
const wrapper = mount(Component, { propsData: { album } })
await wrapper.vm.$nextTick()
await (wrapper.vm as any).open(0, 0)
const m = mock(downloadService, 'fromAlbum')
wrapper.click('[data-testid=download]')
expect(m).toHaveBeenCalledWith(album)
})
it('does not have a download item if not downloadable', () => {
// @ts-ignore
commonStore.state = { allowDownload: false }
const wrapper = shallow(Component, { propsData: { album } })
expect(wrapper.has('[data-testid=download]')).toBe(false)
})
})

View file

@ -1,54 +0,0 @@
import Component from '@/components/artist/ArtistContextMenu.vue'
import factory from '@/__tests__/factory'
import { downloadService, playbackService } from '@/services'
import { commonStore } from '@/stores'
import { mock } from '@/__tests__/__helpers__'
import { mount, shallow } from '@/__tests__/adapter'
describe('components/artist/ContextMenuBase', () => {
let artist: Artist
beforeEach(() => {
artist = factory<Artist>('artist')
// @ts-ignore
commonStore.state = { allowDownload: true }
})
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('plays all', () => {
const wrapper = shallow(Component, { propsData: { artist } })
const m = mock(playbackService, 'playAllByArtist')
wrapper.click('[data-testid=play]')
expect(m).toHaveBeenCalledWith(artist)
})
it('shuffles', () => {
const wrapper = shallow(Component, { propsData: { artist } })
const m = mock(playbackService, 'playAllByArtist')
wrapper.click('[data-testid=shuffle]')
expect(m).toHaveBeenCalledWith(artist, true)
})
it('downloads', async () => {
const wrapper = mount(Component, { propsData: { artist } })
await wrapper.vm.$nextTick()
await (wrapper.vm as any).open(0, 0)
const m = mock(downloadService, 'fromArtist')
wrapper.click('[data-testid=download]')
expect(m).toHaveBeenCalledWith(artist)
})
it('does not have a download item if not downloadable', () => {
// @ts-ignore
commonStore.state = { allowDownload: false }
const wrapper = shallow(Component, { propsData: { artist } })
expect(wrapper.has('[data-testid=download]')).toBe(false)
})
})

View file

@ -1,51 +0,0 @@
import Component from '@/components/meta/AboutKoelModal.vue'
import factory from '@/__tests__/factory'
import { shallow } from '@/__tests__/adapter'
describe('components/meta/AboutKoelModal', () => {
const versionPermutations = [
['v4.0.0'/* latest ver */, 'v4.0.0-beta'/* this ver */, true/* admin */, true/* show new ver notification */],
['v4.0.0', 'v4.0.0', true, false],
['v4.0.0', 'v3.9.0', false, false]
]
it.each(versionPermutations)('new version notification', (latestVersion, currentVersion, isAdmin, visible) => {
const wrapper = shallow(Component, {
data: () => ({
userState: {
current: factory('user', {
is_admin: isAdmin
})
},
sharedState: {
latestVersion,
currentVersion
}
})
})
expect(wrapper.has('.new-version')).toBe(visible)
})
const demoPermutations = [
[true, true],
[false, false]
]
it.each(demoPermutations)('builds demo version with(out) credits', (inDemoEnv, creditVisible) => {
const wrapper = shallow(Component, {
data: () => ({
userState: {
current: factory('user', {
is_admin: true
})
},
sharedState: {
latestVersion: 'v1.0.0',
currentVersion: 'v1.0.0'
},
demo: inDemoEnv
})
})
expect(wrapper.has('.demo-credits')).toBe(creditVisible)
})
})

View file

@ -1,18 +0,0 @@
import List from '@/components/screens/AlbumListScreen.vue'
import factory from '@/__tests__/factory'
import { mount } from '@/__tests__/adapter'
describe('components/screens/album-list', () => {
it('displays a list of albums', async () => {
const wrapper = mount(List, {
sync: false, // https://github.com/vuejs/vue-test-utils/issues/673,
stubs: ['album-card'],
data: () => ({
albums: factory('album', 5)
})
})
await wrapper.vm.$nextTick()
expect(wrapper.findAll('album-card-stub')).toHaveLength(5)
})
})

View file

@ -1,54 +0,0 @@
import Component from '@/components/screens/AlbumScreen.vue'
import SongList from '@/components/song/SongList.vue'
import { albumInfoService, downloadService } from '@/services'
import factory from '@/__tests__/factory'
import { mock } from '@/__tests__/__helpers__'
import { mount, shallow } from '@/__tests__/adapter'
describe('components/screens/album', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('renders properly', async () => {
const album = factory<Album>('album')
const wrapper = mount(Component, {
propsData: { album }
})
await wrapper.vm.$nextTick()
expect(wrapper.hasAll(SongList)).toBe(true)
})
it('loads info from Last.fm', async () => {
const album = factory<Album>('album', {
info: null,
songs: factory<Song>('song', 2)
})
const wrapper = await shallow(Component, {
propsData: { album },
data: () => ({
sharedState: { useLastfm: true }
})
})
const m = mock(albumInfoService, 'fetch')
wrapper.click('a.info')
expect(m).toHaveBeenCalledWith(album)
})
it('allows downloading', () => {
const album = factory<Album>('album', {
songs: factory<Song>('song', 2)
})
const wrapper = shallow(Component, {
propsData: { album },
data: () => ({
sharedState: { allowDownload: true }
})
})
const m = mock(downloadService, 'fromAlbum')
wrapper.click('a.download')
expect(m).toHaveBeenCalledWith(album)
})
})

View file

@ -1,15 +0,0 @@
import Component from '@/components/screens/AllSongsScreen.vue'
import SongList from '@/components/song/SongList.vue'
import factory from '@/__tests__/factory'
import { songStore } from '@/stores'
import { mount } from '@/__tests__/adapter'
describe('components/screens/all-songs', () => {
it('renders properly', async () => {
songStore.all = factory<Song>('song', 10)
const wrapper = mount(Component)
await wrapper.vm.$nextTick()
expect(wrapper.has(SongList)).toBe(true)
})
})

View file

@ -1,18 +0,0 @@
import List from '@/components/screens/ArtistListScreen.vue'
import factory from '@/__tests__/factory'
import { mount } from '@/__tests__/adapter'
describe('components/screens/artist-list', () => {
it('displays a list of artists', async () => {
const wrapper = mount(List, {
sync: false, // https://github.com/vuejs/vue-test-utils/issues/673
stubs: ['artist-card'],
data: () => ({
artists: factory<Artist>('artist', 5)
})
})
await wrapper.vm.$nextTick()
expect(wrapper.findAll('artist-card-stub')).toHaveLength(5)
})
})

View file

@ -1,63 +0,0 @@
import Component from '@/components/screens/ArtistScreen.vue'
import SongList from '@/components/song/SongList.vue'
import { artistInfoService, downloadService } from '@/services'
import factory from '@/__tests__/factory'
import { mock } from '@/__tests__/__helpers__'
import { mount, shallow } from '@/__tests__/adapter'
describe('components/screens/artist', () => {
let artist: Artist
beforeEach(() => {
artist = factory('artist')
const album = factory<Album>('album', {
artist,
artist_id: artist.id
})
artist.albums = [album]
artist.songs = factory<Song>('song', 5, {
artist,
album,
artist_id: artist.id,
album_id: album.id
})
})
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('renders upon receiving event', async () => {
const wrapper = mount(Component, {
propsData: { artist }
})
await wrapper.vm.$nextTick()
expect(wrapper.has(SongList)).toBe(true)
})
it('loads info from Last.fm', () => {
artist.info = null
const wrapper = shallow(Component, {
propsData: { artist },
data: () => ({
sharedState: { useLastfm: true }
})
})
const m = mock(artistInfoService, 'fetch')
wrapper.click('a.info')
expect(m).toHaveBeenCalledWith(artist)
})
it('allows downloading', () => {
const wrapper = shallow(Component, {
propsData: { artist },
data: () => ({
sharedState: { allowDownload: true }
})
})
const m = mock(downloadService, 'fromArtist')
wrapper.click('a.download')
expect(m).toHaveBeenCalledWith(artist)
})
})

View file

@ -1,60 +0,0 @@
import Component from '@/components/screens/FavoritesScreen.vue'
import SongList from '@/components/song/SongList.vue'
import SongListControls from '@/components/songSongListControls.vue'
import { downloadService } from '@/services'
import factory from '@/__tests__/factory'
import { mock } from '@/__tests__/__helpers__'
import { mount, shallow } from '@/__tests__/adapter'
describe('components/screens/favorites', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('displays the song list if there are favorites', async () => {
const wrapper = mount(Component, {
data: () => ({
state: {
songs: factory('song', 5)
}
})
})
await wrapper.vm.$nextTick()
expect(wrapper.hasAll(SongList, SongListControls)).toBe(true)
expect(wrapper.findAll('div.none')).toHaveLength(0)
})
it('displays a fallback message if there are no favorites', async () => {
const wrapper = mount(Component, {
data: () => ({
state: {
songs: []
}
})
})
await wrapper.vm.$nextTick()
expect(wrapper.has('[data-testid=screen-empty-state]')).toBe(true)
})
it('allows downloading', () => {
const m = mock(downloadService, 'fromFavorites')
shallow(Component, {
data: () => ({
state: {
songs: factory('song', 5)
},
sharedState: { allowDownload: true },
meta: {
songCount: 5,
totalLength: '12:34'
}
})
}).click('a.download')
expect(m).toHaveBeenCalled()
})
})

View file

@ -1,22 +0,0 @@
import Home from '@/components/screens/HomeScreen.vue'
import factory from '@/__tests__/factory'
import { eventBus } from '@/utils'
import { mock } from '@/__tests__/__helpers__'
import { mount } from '@/__tests__/adapter'
describe('components/screens/HomeScreen', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('refreshes when a new song is played', async () => {
const wrapper = mount(Home)
await wrapper.vm.$nextTick()
// @ts-ignore
const m = mock(wrapper.vm, 'refreshDashboard')
eventBus.emit('SONG_STARTED', factory('song'))
expect(m).toHaveBeenCalled()
})
})

View file

@ -1,52 +0,0 @@
import Component from '@/components/screens/PlaylistScreen.vue'
import SongList from '@/components/song/SongList.vue'
import factory from '@/__tests__/factory'
import { eventBus } from '@/utils'
import { playlistStore } from '@/stores'
import { mock } from '@/__tests__/__helpers__'
import { mount, shallow } from '@/__tests__/adapter'
describe('components/screens/playlist', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('renders properly', async () => {
const playlist = factory<Playlist>('playlist', { populated: true })
const wrapper = mount(Component, { data: () => ({ playlist }) })
await wrapper.vm.$nextTick()
expect(wrapper.has(SongList)).toBe(true)
})
it('fetch and populate playlist content on demand', () => {
const playlist = factory('playlist', { songs: [] })
shallow(Component)
const m = mock(playlistStore, 'fetchSongs')
eventBus.emit('LOAD_MAIN_CONTENT', 'Playlist', playlist)
expect(m).toHaveBeenCalledWith(playlist)
})
it('displays a fallback message if the playlist is empty', async () => {
const wrapper = mount(Component, {
data: () => ({
playlist: factory('playlist', {
populated: true,
songs: []
})
})
})
await wrapper.vm.$nextTick()
expect(wrapper.has('[data-testid=screen-empty-state]')).toBe(true)
})
it('emits an event to delete the playlist', () => {
const playlist = factory('playlist', { populated: true })
const wrapper = shallow(Component, { data: () => ({ playlist }) })
const emitMock = mock(eventBus, 'emit')
wrapper.click('.btn-delete-playlist')
expect(emitMock).toHaveBeenCalledWith('PLAYLIST_DELETE', playlist)
})
})

View file

@ -1,90 +0,0 @@
import Component from '@/components/screens/QueueScreen.vue'
import SongList from '@/components/song/SongList.vue'
import factory from '@/__tests__/factory'
import { queueStore, songStore } from '@/stores'
import { playbackService } from '@/services'
import { mock } from '@/__tests__/__helpers__'
import { mount, shallow } from '@/__tests__/adapter'
describe('components/screens/queue', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('renders properly', async () => {
const wrapper = mount(Component, {
data: () => ({
state: {
songs: factory<Song>('song', 10)
}
})
})
await wrapper.vm.$nextTick()
expect(wrapper.has(SongList)).toBe(true)
})
it('prompts to shuffle all songs if there are songs and current queue is empty', async () => {
songStore.state.songs = factory<Song>('song', 10)
const wrapper = mount(Component, {
data: () => ({
state: { songs: [] }
})
})
await wrapper.vm.$nextTick()
expect(wrapper.find('a.start').text()).toMatch('shuffling all songs')
})
it('doesn\'t prompt to shuffle all songs if there is no song', async () => {
songStore.state.songs = []
const wrapper = mount(Component, {
data: () => ({
state: { songs: [] }
})
})
await wrapper.vm.$nextTick()
expect(wrapper.has('a.start')).toBe(false)
})
it('shuffles all songs in the queue if any', () => {
const m = mock(playbackService, 'queueAndPlay')
const songs = factory<Song>('song', 10)
const wrapper = mount(Component, {
data: () => ({
state: { songs }
})
})
wrapper.click('button.btn-shuffle-all')
expect(m).toHaveBeenCalledWith(songs, true)
})
it('shuffles all available songs if there are no songs queued', () => {
const songs = factory<Song>('song', 10)
songStore.state.songs = songs
const m = mock(playbackService, 'queueAndPlay')
const c = shallow(Component, {
data: () => ({
state: {
songs: []
}
})
})
c.click('a.start')
expect(m).toHaveBeenCalledWith(songs, true)
})
it('clears the queue', () => {
const m = mock(queueStore, 'clear')
mount(Component, {
data: () => ({
state: { songs: factory('song', 10) }
})
}).click('button.btn-clear-queue')
expect(m).toHaveBeenCalled()
})
})

View file

@ -1,34 +0,0 @@
import Component from '@/components/screens/RecentlyPlayedScreen.vue'
import SongList from '@/components/song/SongList.vue'
import factory from '@/__tests__/factory'
import { recentlyPlayedStore } from '@/stores'
import { eventBus } from '@/utils'
import { mock } from '@/__tests__/__helpers__'
import { mount, shallow } from '@/__tests__/adapter'
describe('components/screens/recently-played', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('renders properly', async () => {
const wrapper = mount(Component, {
data: () => ({
state: {
songs: factory('song', 5)
}
})
})
await wrapper.vm.$nextTick()
expect(wrapper.has(SongList)).toBe(true)
})
it('fetch and populate content on demand', () => {
shallow(Component)
const m = mock(recentlyPlayedStore, 'fetchAll')
eventBus.emit('LOAD_MAIN_CONTENT', 'RecentlyPlayed')
expect(m).toHaveBeenCalled()
})
})

View file

@ -1,36 +0,0 @@
import Component from '@/components/screens/SettingsScreen.vue'
import { commonStore, settingStore } from '@/stores'
import { alerts } from '@/utils'
import { mock } from '@/__tests__/__helpers__'
import { shallow } from '@/__tests__/adapter'
describe('components/screens/settings', () => {
beforeEach(() => {
settingStore.state = {
settings: {
media_path: '/foo/'
}
}
})
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('warns if changing a non-empty media path', () => {
commonStore.state.originalMediaPath = '/bar'
const m = mock(alerts, 'confirm')
shallow(Component).submit('form')
expect(m).toHaveBeenCalled()
})
it("doesn't warn if changing an empty media path", () => {
commonStore.state.originalMediaPath = ''
const confirmMock = mock(alerts, 'confirm')
const updateMock = mock(settingStore, 'update')
shallow(Component).submit('form')
expect(confirmMock).not.toHaveBeenCalled()
expect(updateMock).toHaveBeenCalled()
})
})

View file

@ -1,39 +0,0 @@
import Component from '@/components/screens/UserListScreen.vue'
import UserCard from '@/components/user/UserCard.vue'
import factory from '@/__tests__/factory'
import { userStore } from '@/stores'
import { eventBus } from '@/utils'
import { mock } from '@/__tests__/__helpers__'
import { mount } from '@/__tests__/adapter'
describe('components/screens/UserListScreen', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('displays the users', async () => {
userStore.all = factory<User>('user', 10)
const wrapper = mount(Component)
await wrapper.vm.$nextTick()
expect(wrapper.findAll(UserCard)).toHaveLength(10)
})
it('adds new user', async () => {
const emitMock = mock(eventBus, 'emit')
const wrapper = mount(Component)
await wrapper.vm.$nextTick()
wrapper.click('.btn-add')
expect(emitMock).toHaveBeenCalledWith('MODAL_SHOW_ADD_USER_FORM')
})
it('edits a user', () => {
userStore.all = factory<User>('user', 10)
const emitMock = mock(eventBus, 'emit')
mount(Component).click('.btn-edit')
expect(emitMock).toHaveBeenCalledWith('MODAL_SHOW_EDIT_USER_FORM', userStore.all[0])
})
})

View file

@ -1,97 +0,0 @@
import Component from '@/components/song/SongContextMenu.vue'
import { downloadService } from '@/services'
import { songStore, playlistStore, queueStore, favoriteStore, commonStore, userStore } from '@/stores'
import { eventBus } from '@/utils'
import factory from '@/__tests__/factory'
import { mock } from '@/__tests__/__helpers__'
import { mount, Wrapper } from '@/__tests__/adapter'
import FunctionPropertyNames = jest.FunctionPropertyNames
describe('components/song/ContextMenuBase', () => {
let songs: Song[], wrapper: Wrapper
beforeEach(() => {
userStore.current.is_admin = true
commonStore.state.allowDownload = true
songs = factory<Song>('song', 2)
wrapper = mount(Component, {
propsData: { songs },
data: () => ({ copyable: true })
})
})
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('renders properly', async () => {
const selectors = [
'.playback',
'.go-to-album',
'.go-to-artist',
'.after-current',
'.bottom-queue',
'.top-queue',
'.favorite'
]
await (wrapper.vm as any).open(0, 0)
expect(wrapper.hasAll(...selectors)).toBe(true)
})
it.each<[string, string, FunctionPropertyNames<typeof queueStore>]>([
['after current', '.after-current', 'queueAfterCurrent'],
['to bottom', '.bottom-queue', 'queue'],
['to top', '.top-queue', 'queueToTop']
])('queues songs %s when "%s" is clicked', async (to, selector, queueFunc) => {
const m = mock(queueStore, queueFunc)
await (wrapper.vm as any).open(0, 0)
wrapper.click(selector)
expect(m).toHaveBeenCalledWith(songs)
})
it('adds songs to favorite', async () => {
const m = mock(favoriteStore, 'like')
await (wrapper.vm as any).open(0, 0)
wrapper.click('.favorite')
expect(m).toHaveBeenCalledWith(songs)
})
it('adds songs to existing playlist', async () => {
playlistStore.all = factory<Playlist>('playlist', 5)
const m = mock(playlistStore, 'addSongs')
await (wrapper.vm as any).open(0, 0)
const html = wrapper.html()
playlistStore.all.forEach(playlist => expect(html).toMatch(playlist.name))
wrapper.click('.playlist')
expect(m).toHaveBeenCalledWith(playlistStore.all[0], songs)
})
it('opens the edit form', async () => {
const m = mock(eventBus, 'emit')
userStore.current.is_admin = true
await (wrapper.vm as any).open(0, 0)
wrapper.click('.open-edit-form')
expect(m).toHaveBeenCalledWith('MODAL_SHOW_EDIT_SONG_FORM', songs)
})
it('downloads', async () => {
const m = mock(downloadService, 'fromSongs')
await (wrapper.vm as any).open(0, 0)
wrapper.click('.download')
expect(m).toHaveBeenCalledWith(songs)
})
it('copies URL', async () => {
const getShareableUrlMock = mock(songStore, 'getShareableUrl')
const execCommandMock = mock(document, 'execCommand')
const song = factory('song')
await (wrapper.vm as any).open(0, 0)
wrapper.setProps({ songs: [song] })
wrapper.click('.copy-url')
expect(getShareableUrlMock).toHaveBeenCalledWith(song)
expect(execCommandMock).toHaveBeenCalledWith('copy')
})
})

View file

@ -1,134 +0,0 @@
import Component from '@/components/song/SongEditForm.vue'
import Typeahead from '@/components/ui/typeahead.vue'
import factory from '@/__tests__/factory'
import { songStore } from '@/stores'
import { songInfoService } from '@/services/info'
import { mock } from '@/__tests__/__helpers__'
import { mount } from '@/__tests__/adapter'
describe('components/song/edit-form', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('supports editing a single song', async () => {
const song = factory<Song>('song', { infoRetrieved: true })
const wrapper = mount(Component, {
propsData: { songs: song }
})
await wrapper.vm.$nextTick()
const metaHtml = wrapper.find('.meta').html()
expect(metaHtml).toMatch(song.title)
expect(metaHtml).toMatch(song.album.name)
expect(metaHtml).toMatch(song.artist.name)
await (wrapper.vm as any).open()
expect(wrapper.has(Typeahead)).toBe(true)
expect(wrapper.find('input[name=title]').value).toBe(song.title)
expect(wrapper.find('input[name=album]').value).toBe(song.album.name)
expect(wrapper.find('input[name=artist]').value).toBe(song.artist.name)
expect(wrapper.find('input[name=track]').value).toBe(song.track.toString())
wrapper.click('#editSongTabLyrics')
expect(wrapper.find('textarea[name=lyrics]').value).toBe(song.lyrics)
})
it('fetches song information on demand', () => {
const song = factory('song', { infoRetrieved: false })
const fetchMock = mock(songInfoService, 'fetch')
mount(Component, {
propsData: { songs: song }
})
expect(fetchMock).toHaveBeenCalledWith(song)
})
it('supports editing multiple songs of multiple artists', () => {
const wrapper = mount(Component, {
propsData: {
songs: factory('song', 3)
}
})
const metaHtml = wrapper.find('.meta').html()
expect(metaHtml).toMatch('3 songs selected')
expect(metaHtml).toMatch('Mixed Artists')
expect(metaHtml).toMatch('Mixed Albums')
expect(wrapper.find('input[name=artist]').value).toBe('')
expect(wrapper.find('input[name=album]').value).toBe('')
expect(wrapper.has('.tabs .tab-lyrics')).toBe(false)
})
it('supports editing multiple songs of same artist and different albums', () => {
const artist = factory<Artist>('artist')
const wrapper = mount(Component, {
propsData: {
songs: factory('song', 5, {
artist,
artist_id: artist.id
})
}
})
const metaHtml = wrapper.find('.meta').html()
expect(metaHtml).toMatch('5 songs selected')
expect(metaHtml).toMatch(artist.name)
expect(metaHtml).toMatch('Mixed Albums')
expect(wrapper.find('input[name=artist]').value).toBe(artist.name)
expect(wrapper.find('input[name=album]').value).toBe('')
expect(wrapper.has('.tabs .tab-lyrics')).toBe(false)
})
it('supports editing multiple songs in same album', () => {
const album = factory<Album>('album')
const wrapper = mount(Component, {
propsData: {
songs: factory('song', 4, {
album,
album_id: album.id,
artist: album.artist,
artist_id: album.artist.id
})
}
})
const metaHtml = wrapper.find('.meta').html()
expect(metaHtml).toMatch('4 songs selected')
expect(metaHtml).toMatch(album.name)
expect(metaHtml).toMatch(album.artist.name)
expect(wrapper.find('input[name=artist]').value).toBe(album.artist.name)
expect(wrapper.find('input[name=album]').value).toBe(album.name)
expect(wrapper.has('.tabs .tab-lyrics')).toBe(false)
})
it('saves', async () => {
const updateStub = mock(songStore, 'update')
const songs = factory('song', 3)
const formData = { foo: 'bar' }
const wrapper = mount(Component, {
data: () => ({ formData }),
propsData: {
songs
}
})
wrapper.submit('form')
await wrapper.vm.$nextTick()
expect(updateStub).toHaveBeenCalledWith(songs, formData)
})
it('closes', async () => {
const wrapper = mount(Component, {
propsData: {
songs: factory('song', 3)
}
})
await wrapper.vm.$nextTick()
wrapper.click('.btn-cancel')
expect(wrapper.hasEmitted('close')).toBe(true)
})
})

View file

@ -1,85 +0,0 @@
import FunctionPropertyNames = jest.FunctionPropertyNames
import Component from '@/components/song/SongListItem.vue'
import factory from '@/__tests__/factory'
import { playbackService } from '@/services'
import { queueStore } from '@/stores'
import { mock } from '@/__tests__/__helpers__'
import { shallow, Wrapper } from '@/__tests__/adapter'
describe('components/song/SongListItem', () => {
let item: SongRow, song: Song, artist: Artist, album: Album, wrapper: Wrapper
beforeEach(() => {
artist = factory<Artist>('artist')
album = factory<Album>('album', {
artist,
artist_id: artist.id
})
song = factory<Song>('song', {
artist,
album,
artist_id: artist.id,
album_id: album.id,
fmtLength: '04:56'
})
item = { song, selected: false }
wrapper = shallow(Component, {
propsData: {
item,
columns: ['track', 'title', 'artist', 'album', 'length']
}
})
})
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('renders properly', () => {
const html = wrapper.html()
expect(html).toMatch(song.track.toString())
expect(html).toMatch(song.title)
expect(html).toMatch(artist.name)
expect(html).toMatch(album.name)
expect(html).toMatch('04:56')
})
it('does not render some information if so configured', () => {
wrapper = shallow(Component, {
propsData: {
item,
columns: ['track', 'title', 'length']
}
})
expect(wrapper.has('.album')).toBe(false)
expect(wrapper.has('.artist')).toBe(false)
})
it.each([[true, false], [false, true]])('queuing and playing behavior', (shouldQueue, queued) => {
const containsStub = mock(queueStore, 'contains', queued)
const queueStub = mock(queueStore, 'queueAfterCurrent')
const playStub = mock(playbackService, 'play')
wrapper.dblclick('tr')
expect(containsStub).toHaveBeenCalledWith(song)
if (queued) {
expect(queueStub).not.toHaveBeenCalled()
} else {
expect(queueStub).toHaveBeenCalledWith(song)
}
expect(playStub).toHaveBeenCalledWith(song)
})
it.each<[PlaybackState, FunctionPropertyNames<typeof playbackService>]>([
['Stopped', 'play'],
['Playing', 'pause'],
['Paused', 'resume']
])('if state is currently "%s", %s', (state, action) => {
const m = mock(playbackService, action)
song.playbackState = state
wrapper.click('.play')
expect(m).toHaveBeenCalled()
})
})

View file

@ -1,3 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/song/list-controls-toggler renders properly 1`] = `<span class="controls-toggler text-orange"><i class="fa fa-angle-up toggler"></i></span>`;

View file

@ -1,6 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/ui/ScrollToTopButton renders properly 1`] = `
<div class="to-top-btn-wrapper" style="display: none;" name="fade"><button title="Scroll to top"><i class="fa fa-arrow-circle-up"></i> Top
</button></div>
`;

View file

@ -1,23 +0,0 @@
import factory from '@/__tests__/factory'
import Component from '@/components/ui/AlbumArtOverlay.vue'
import { shallow } from '@/__tests__/adapter'
import { mock } from '@/__tests__/__helpers__'
import { albumStore, preferenceStore } from '@/stores'
describe('components/ui/AlbumArtOverlay', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('requests album thumbnail', async () => {
preferenceStore.state.showAlbumArtOverlay = true
const getCoverThumbnailMock = mock(albumStore, 'getThumbnail').mockResolvedValue('http://localhost/foo_thumb.jpg')
const song = factory<Song>('song')
const wrapper = shallow(Component)
wrapper.setProps({ song })
expect(getCoverThumbnailMock).toHaveBeenCalledWith(song.album)
expect(wrapper).toMatchSnapshot()
})
})

View file

@ -1,10 +0,0 @@
import Component from '@/components/ui/BtnCloseModal.vue'
import { mount } from '@/__tests__/adapter'
describe('components/ui/BtnCloseModal', () => {
it('emits a click event', () => {
const wrapper = mount(Component)
wrapper.click('button')
expect(wrapper.hasEmitted('click'))
})
})

View file

@ -1,21 +0,0 @@
import Lyrics from '@/components/ui/LyricsPane'
import factory from '@/__tests__/factory'
import { shallow } from '@/__tests__/adapter'
describe('components/ui/lyrics', () => {
it('displays lyrics if the song has lyrics', () => {
expect(shallow(Lyrics, {
propsData: {
song: factory('song', { lyrics: 'Foo and bar' })
}
})).toMatchSnapshot()
})
it('displays a fallback message if the song has no lyrics', () => {
expect(shallow(Lyrics, {
propsData: {
song: factory('song', { lyrics: '' })
}
})).toMatchSnapshot()
})
})

View file

@ -1,38 +0,0 @@
import Component from '@/components/ui/Overlay.vue'
import { mount } from '@/__tests__/adapter'
describe('components/shared/Overlay', () => {
it('shows with default options', async () => {
const wrapper = mount(Component)
;(wrapper.vm as any).show()
await wrapper.vm.$nextTick()
expect(wrapper).toMatchSnapshot()
})
it('allows option overriding', async () => {
const wrapper = mount(Component)
;(wrapper.vm as any).show({
dismissible: true,
type: 'warning',
message: 'Foo'
})
await wrapper.vm.$nextTick()
expect(wrapper).toMatchSnapshot()
})
it.each([['show'], ['hide']])('%ss', methodName => {
const wrapper = mount(Component)
;(wrapper.vm as any)[methodName]()
expect(wrapper).toMatchSnapshot()
})
it('dismisses', () => {
const wrapper = mount(Component)
;(wrapper.vm as any).show({ dismissible: true })
expect(wrapper.has('.display')).toBe(true)
wrapper.click('button.btn-dismiss')
expect(wrapper.has('.display')).toBe(false)
})
})

View file

@ -1,22 +0,0 @@
import Component from '@/components/ui/SearchForm.vue'
import { mock } from '@/__tests__/__helpers__'
import { shallow } from '@/__tests__/adapter'
import { eventBus } from '@/utils'
describe('components/ui/SearchForm', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('emits an event to filter', async done => {
const emitStub = mock(eventBus, 'emit')
const wrapper = shallow(Component)
wrapper.find('[type=search]').setValue('foo').input()
setTimeout(() => {
expect(emitStub).toHaveBeenCalledWith('SEARCH_KEYWORDS_CHANGED', 'foo')
done()
}, 500) // because of debounce
})
})

View file

@ -1,21 +0,0 @@
import Component from '../../../components/ui/BtnScrollToTop.vue'
import { $ } from '@/utils'
import { mock } from '@/__tests__/__helpers__'
import { shallow } from '@/__tests__/adapter'
describe('components/ui/ScrollToTopButton', () => {
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('renders properly', () => {
expect(shallow(Component)).toMatchSnapshot()
})
it('scrolls to top', () => {
const m = mock($, 'scrollTo')
shallow(Component).click('button')
expect(m).toHaveBeenCalled()
})
})