test: add artist info unit tests

This commit is contained in:
Phan An 2022-05-04 23:01:35 +02:00
parent e2dbfd7853
commit b94c3de3b6
No known key found for this signature in database
GPG key ID: A81E4477F0BB6FDC
8 changed files with 72 additions and 88 deletions

View file

@ -41,9 +41,11 @@
"@typescript-eslint/no-non-null-assertion": 0, "@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/ban-ts-comment": 0, "@typescript-eslint/ban-ts-comment": 0,
"@typescript-eslint/no-empty-function": 0, "@typescript-eslint/no-empty-function": 0,
"vue/no-side-effects-in-computed-properties": 0,
"@typescript-eslint/explicit-module-boundary-types": 0, "@typescript-eslint/explicit-module-boundary-types": 0,
"standard/no-callback-literal": 0, "standard/no-callback-literal": 0,
"vue/valid-v-on": 0 "vue/valid-v-on": 0,
"vue/no-side-effects-in-computed-properties": 0,
"vue/max-attributes-per-line": 0,
"vue/no-v-html": 0
} }
} }

View file

@ -1,53 +0,0 @@
import Component from '@/components/artist/ArtistCard.vue'
import Thumbnail from '@/components/ui/AlbumArtistThumbnail.vue'
import factory from '@/__tests__/factory'
import { playbackService, downloadService } from '@/services'
import { commonStore } from '@/stores'
import { mock } from '@/__tests__/__helpers__'
import { mount, shallow } from '@/__tests__/adapter'
describe('components/artist/card', () => {
let artist: Artist
beforeEach(() => {
// @ts-ignore
commonStore.state = { allowDownload: true }
artist = factory<Artist>('artist', {
id: 3, // make sure it's not "Various Artists"
albums: factory<Album>('album', 4),
songs: factory<Song>('song', 16)
})
})
afterEach(() => {
jest.resetModules()
jest.clearAllMocks()
})
it('renders properly', async () => {
const wrapper = mount(Component, { propsData: { artist } })
await wrapper.vm.$nextTick()
expect(wrapper.has(Thumbnail)).toBe(true)
const html = wrapper.html()
expect(html).toMatch('4 albums')
expect(html).toMatch('16 songs')
expect(html).toMatch(artist.name)
})
it('shuffles', () => {
const wrapper = shallow(Component, { propsData: { artist } })
const playStub = mock(playbackService, 'playAllByArtist')
wrapper.click('.shuffle-artist')
expect(playStub).toHaveBeenCalledWith(artist, true)
})
it('downloads', () => {
const wrapper = shallow(Component, { propsData: { artist } })
const downloadStub = mock(downloadService, 'fromArtist')
wrapper.click('.download-artist')
expect(downloadStub).toHaveBeenCalledWith(artist)
})
})

View file

@ -12,7 +12,7 @@
@contextmenu.prevent="requestContextMenu" @contextmenu.prevent="requestContextMenu"
> >
<span class="thumbnail-wrapper"> <span class="thumbnail-wrapper">
<AlbumThumbnail :entity="album"/> <AlbumThumbnail :entity="album" />
</span> </span>
<footer> <footer>
@ -20,7 +20,7 @@
<a :href="`#!/album/${album.id}`" class="name" data-testid="name">{{ album.name }}</a> <a :href="`#!/album/${album.id}`" class="name" data-testid="name">{{ album.name }}</a>
<span class="sep text-secondary"> by </span> <span class="sep text-secondary"> by </span>
<a v-if="isNormalArtist" :href="`#!/artist/${album.artist.id}`" class="artist">{{ album.artist.name }}</a> <a v-if="isNormalArtist" :href="`#!/artist/${album.artist.id}`" class="artist">{{ album.artist.name }}</a>
<span class="artist nope" v-else>{{ album.artist.name }}</span> <span v-else class="artist nope">{{ album.artist.name }}</span>
</div> </div>
<p class="meta"> <p class="meta">
<span class="left"> <span class="left">
@ -39,7 +39,7 @@
role="button" role="button"
@click.prevent="shuffle" @click.prevent="shuffle"
> >
<i class="fa fa-random"></i> <i class="fa fa-random" />
</a> </a>
<a <a
v-if="allowDownload" v-if="allowDownload"
@ -50,7 +50,7 @@
role="button" role="button"
@click.prevent="download" @click.prevent="download"
> >
<i class="fa fa-download"></i> <i class="fa fa-download" />
</a> </a>
</span> </span>
</p> </p>

View file

@ -1,27 +1,16 @@
import { beforeEach, expect, it, vi } from 'vitest' import { beforeEach, expect, it } from 'vitest'
import { mockHelper, render } from '@/__tests__/__helpers__' import { render } from '@/__tests__/__helpers__'
import { cleanup, fireEvent } from '@testing-library/vue' import { cleanup, fireEvent } from '@testing-library/vue'
import factory from '@/__tests__/factory' import factory from '@/__tests__/factory'
import AlbumInfo from '@/components/album/AlbumInfo.vue' import AlbumInfo from './AlbumInfo.vue'
import AlbumThumbnail from '@/components/ui/AlbumArtistThumbnail.vue' import AlbumThumbnail from '@/components/ui/AlbumArtistThumbnail.vue'
let album: Album beforeEach(() => cleanup())
beforeEach(() => {
vi.restoreAllMocks()
mockHelper.restoreAllMocks()
cleanup()
album = factory<Album>('album', {
name: 'IV',
songs: factory<Song>('song', 10)
})
})
it.each([['sidebar'], ['full']])('renders in %s mode', async (mode: string) => { it.each([['sidebar'], ['full']])('renders in %s mode', async (mode: string) => {
const { getByTestId } = render(AlbumInfo, { const { getByTestId } = render(AlbumInfo, {
props: { props: {
album, album: factory<Album>('album'),
mode mode
}, },
global: { global: {
@ -31,13 +20,15 @@ it.each([['sidebar'], ['full']])('renders in %s mode', async (mode: string) => {
} }
}) })
getByTestId('album-thumbnail') getByTestId('album-artist-thumbnail')
const element = getByTestId<HTMLElement>('album-info') const element = getByTestId<HTMLElement>('album-info')
expect(element.classList.contains(mode)).toBe(true) expect(element.classList.contains(mode)).toBe(true)
}) })
it('triggers showing full wiki', async () => { it('triggers showing full wiki', async () => {
const album = factory<Album>('album')
const { getByText } = render(AlbumInfo, { const { getByText } = render(AlbumInfo, {
props: { props: {
album album

View file

@ -3,24 +3,24 @@
<h1 class="name"> <h1 class="name">
<span>{{ album.name }}</span> <span>{{ album.name }}</span>
<button :title="`Shuffle all songs in ${album.name}`" class="shuffle control" @click.prevent="shuffleAll"> <button :title="`Shuffle all songs in ${album.name}`" class="shuffle control" @click.prevent="shuffleAll">
<i class="fa fa-random"></i> <i class="fa fa-random" />
</button> </button>
</h1> </h1>
<main> <main>
<AlbumThumbnail :entity="album"/> <AlbumThumbnail :entity="album" />
<template v-if="album.info"> <template v-if="album.info">
<div class="wiki" v-if="album.info?.wiki?.summary"> <div v-if="album.info?.wiki?.summary" class="wiki">
<div v-if="showSummary" class="summary" v-html="album.info?.wiki?.summary"></div> <div v-if="showSummary" class="summary" v-html="album.info?.wiki?.summary" />
<div v-if="showFull" class="full" v-html="album.info?.wiki?.full"></div> <div v-if="showFull" class="full" v-html="album.info?.wiki?.full" />
<button v-if="showSummary" class="more" data-testid="more-btn" @click.prevent="showingFullWiki = true"> <button v-if="showSummary" class="more" data-testid="more-btn" @click.prevent="showingFullWiki = true">
Full Wiki Full Wiki
</button> </button>
</div> </div>
<TrackList v-if="album.info?.tracks?.length" :album="album" data-testid="album-info-tracks"/> <TrackList v-if="album.info?.tracks?.length" :album="album" data-testid="album-info-tracks" />
<footer>Data &copy; <a :href="album.info?.url" rel="noopener" target="_blank">Last.fm</a></footer> <footer>Data &copy; <a :href="album.info?.url" rel="noopener" target="_blank">Last.fm</a></footer>
</template> </template>

View file

@ -0,0 +1,42 @@
import { beforeEach, expect, it } from 'vitest'
import { render } from '@/__tests__/__helpers__'
import { cleanup, fireEvent } from '@testing-library/vue'
import factory from '@/__tests__/factory'
import ArtistInfo from './ArtistInfo.vue'
import ArtistThumbnail from '@/components/ui/AlbumArtistThumbnail.vue'
let artist: Artist
beforeEach(() => cleanup())
it.each([['sidebar'], ['full']])('renders in %s mode', async (mode: string) => {
const { getByTestId } = render(ArtistInfo, {
props: {
artist: factory<Artist>('artist'),
mode
},
global: {
stubs: {
ArtistThumbnail
}
}
})
getByTestId('album-artist-thumbnail')
const element = getByTestId<HTMLElement>('artist-info')
expect(element.classList.contains(mode)).toBe(true)
})
it('triggers showing full wiki', async () => {
const artist = factory<Artist>('artist')
const { getByText } = render(ArtistInfo, {
props: {
artist
}
})
await fireEvent.click(getByText('Full Bio'))
getByText(artist.info!.bio!.full)
})

View file

@ -3,23 +3,25 @@
<h1 class="name"> <h1 class="name">
<span>{{ artist.name }}</span> <span>{{ artist.name }}</span>
<button :title="`Shuffle all songs by ${artist.name}`" class="shuffle control" @click.prevent="shuffleAll"> <button :title="`Shuffle all songs by ${artist.name}`" class="shuffle control" @click.prevent="shuffleAll">
<i class="fa fa-random"></i> <i class="fa fa-random" />
</button> </button>
</h1> </h1>
<main v-if="artist.info"> <main v-if="artist.info">
<ArtistThumbnail :entity="artist"/> <ArtistThumbnail :entity="artist" />
<template v-if="artist.info"> <template v-if="artist.info">
<div v-if="artist.info?.bio?.summary" class="bio"> <div v-if="artist.info?.bio?.summary" class="bio">
<div v-if="showSummary" class="summary" v-html="artist.info?.bio?.summary"></div> <div v-if="showSummary" class="summary" v-html="artist.info?.bio?.summary" />
<div v-if="showFull" class="full" v-html="artist.info?.bio?.full"></div> <div v-if="showFull" class="full" v-html="artist.info?.bio?.full" />
<button v-show="showSummary" class="more" data-testid="more-btn" @click.prevent="showingFullBio = true"> <button v-show="showSummary" class="more" data-testid="more-btn" @click.prevent="showingFullBio = true">
Full Bio Full Bio
</button> </button>
</div> </div>
<p v-else class="text-secondary none">This artist has no Last.fm biography yet.</p> <p v-else class="text-secondary none">
This artist has no Last.fm biography yet.
</p>
<footer>Data &copy; <a :href="artist.info?.url" rel="openener" target="_blank">Last.fm</a></footer> <footer>Data &copy; <a :href="artist.info?.url" rel="openener" target="_blank">Last.fm</a></footer>
</template> </template>

View file

@ -3,7 +3,7 @@
:class="{ droppable }" :class="{ droppable }"
:style="{ backgroundImage: `url(${image})` }" :style="{ backgroundImage: `url(${image})` }"
class="cover" class="cover"
data-testid="album-thumbnail" data-testid="album-artist-thumbnail"
> >
<a <a
class="control control-play font-size-0" class="control control-play font-size-0"