mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
test: add artist info unit tests
This commit is contained in:
parent
e2dbfd7853
commit
b94c3de3b6
8 changed files with 72 additions and 88 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
})
|
|
||||||
})
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 © <a :href="album.info?.url" rel="noopener" target="_blank">Last.fm</a></footer>
|
<footer>Data © <a :href="album.info?.url" rel="noopener" target="_blank">Last.fm</a></footer>
|
||||||
</template>
|
</template>
|
||||||
|
|
42
resources/assets/js/components/artist/ArtistInfo.spec.ts
Normal file
42
resources/assets/js/components/artist/ArtistInfo.spec.ts
Normal 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)
|
||||||
|
})
|
|
@ -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 © <a :href="artist.info?.url" rel="openener" target="_blank">Last.fm</a></footer>
|
<footer>Data © <a :href="artist.info?.url" rel="openener" target="_blank">Last.fm</a></footer>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue