feat (test): add YouTubeVideoItem component tests

This commit is contained in:
Phan An 2022-05-12 19:29:53 +02:00
parent 621c869a82
commit c73122fe5a
No known key found for this signature in database
GPG key ID: A81E4477F0BB6FDC
4 changed files with 104 additions and 43 deletions

View file

@ -0,0 +1,44 @@
import { expect, it } from 'vitest'
import ComponentTestCase from '@/__tests__/ComponentTestCase'
import YouTubeVideoItem from './YouTubeVideoItem.vue'
import { fireEvent } from '@testing-library/vue'
import { youTubeService } from '@/services'
let video: YouTubeVideo
new class extends ComponentTestCase {
private renderComponent () {
video = {
id: {
videoId: 'cLgJQ8Zj3AA'
},
snippet: {
title: 'Guess what it is',
description: 'From the LA Opening Gala 2014: John Williams Celebration',
thumbnails: {
default: {
url: 'https://i.ytimg.com/an_webp/cLgJQ8Zj3AA/mqdefault_6s.webp'
}
}
}
}
return this.render(YouTubeVideoItem, {
props: {
video
}
})
}
protected test () {
it('renders', () => expect(this.renderComponent().html()).toMatchSnapshot())
it('plays', async () => {
const mock = this.mock(youTubeService, 'play')
const { getByRole } = this.renderComponent()
await fireEvent.click(getByRole('button'))
expect(mock).toHaveBeenCalledWith(video)
})
}
}

View file

@ -0,0 +1,46 @@
<template>
<a :href="url" data-testid="youtube-search-result" role="button" @click.prevent="play">
<img :alt="video.snippet.title" :src="video.snippet.thumbnails.default.url" width="90">
<div class="meta">
<h3 class="title">{{ video.snippet.title }}</h3>
<p class="desc">{{ video.snippet.description }}</p>
</div>
</a>
</template>
<script lang="ts" setup>
import { computed, toRefs } from 'vue'
import { youTubeService } from '@/services'
const props = defineProps<{ video: YouTubeVideo }>()
const { video } = toRefs(props)
const url = computed(() => `https://youtu.be/${video.value.id.videoId}`)
const play = () => youTubeService.play(video.value)
</script>
<style lang="scss" scoped>
a {
display: flex;
padding: 12px 0;
&:hover, &:active, &:focus {
color: var(--color-text-primary);
}
}
.title {
font-size: 1.1rem;
margin-bottom: .4rem;
}
.desc {
font-size: .9rem;
}
img {
margin-right: 10px;
align-self: self-start;
}
</style>

View file

@ -1,23 +1,7 @@
<template> <template>
<div class="youtube-extra-wrapper"> <div class="youtube-extra-wrapper">
<template v-if="videos.length"> <template v-if="videos.length">
<a <YouTubeVideo v-for="video in videos" :key="video.id.videoId" :video="video"/>
v-for="video in videos"
:key="video.id.videoId"
:href="`https://youtu.be/${video.id.videoId}`"
class="video"
data-testid="youtube-search-result"
role="button"
@click.prevent="play(video)"
>
<div class="thumb">
<img :alt="video.snippet.title" :src="video.snippet.thumbnails.default.url" width="90">
</div>
<div class="meta">
<h3 class="title">{{ video.snippet.title }}</h3>
<p class="desc">{{ video.snippet.description }}</p>
</div>
</a>
<Btn v-if="!loading" class="more" data-testid="youtube-search-more-btn" @click.prevent="loadMore">Load More</Btn> <Btn v-if="!loading" class="more" data-testid="youtube-search-more-btn" @click.prevent="loadMore">Load More</Btn>
</template> </template>
@ -31,6 +15,7 @@ import { defineAsyncComponent, ref, toRefs, watchEffect } from 'vue'
import { youTubeService } from '@/services' import { youTubeService } from '@/services'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue')) const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
const YouTubeVideo = defineAsyncComponent(() => import('@/components/ui/YouTubeVideoItem.vue'))
const props = defineProps<{ song: Song }>() const props = defineProps<{ song: Song }>()
const { song } = toRefs(props) const { song } = toRefs(props)
@ -40,8 +25,6 @@ const videos = ref<YouTubeVideo[]>([])
watchEffect(() => (videos.value = song.value.youtube?.items || [])) watchEffect(() => (videos.value = song.value.youtube?.items || []))
const play = (video: YouTubeVideo) => youTubeService.play(video)
const loadMore = async () => { const loadMore = async () => {
loading.value = true loading.value = true
@ -63,30 +46,8 @@ const loadMore = async () => {
.youtube-extra-wrapper { .youtube-extra-wrapper {
overflow-x: hidden; overflow-x: hidden;
.video { a:last-of-type {
display: flex; margin-bottom: 16px;
padding: 12px 0;
.thumb {
margin-right: 10px;
}
.title {
font-size: 1.1rem;
margin-bottom: .4rem;
}
.desc {
font-size: .9rem;
}
&:hover, &:active, &:focus {
color: var(--color-text-primary);
}
&:last-of-type {
margin-bottom: 16px;
}
} }
} }
</style> </style>

View file

@ -0,0 +1,10 @@
// Vitest Snapshot v1
exports[`renders 1`] = `
<a href="https://youtu.be/cLgJQ8Zj3AA" data-testid="youtube-search-result" role="button" data-v-da3db7c2=""><img alt="Guess what it is" src="https://i.ytimg.com/an_webp/cLgJQ8Zj3AA/mqdefault_6s.webp" width="90" data-v-da3db7c2="" />
<div class="meta" data-v-da3db7c2="">
<h3 class="title" data-v-da3db7c2="">Guess what it is</h3>
<p class="desc" data-v-da3db7c2="">From the LA Opening Gala 2014: John Williams Celebration</p>
</div>
</a>
`;