mirror of
https://github.com/koel/koel
synced 2024-11-24 13:13:05 +00:00
fix(test): MainWrapper tests
This commit is contained in:
parent
3b0d5217d8
commit
31094fe283
9 changed files with 66 additions and 88 deletions
|
@ -1,6 +1,6 @@
|
|||
import isMobile from 'ismobilejs'
|
||||
import { expect, it } from 'vitest'
|
||||
import { fireEvent, queryAllByTestId } from '@testing-library/vue'
|
||||
import { fireEvent, queryAllByTestId, waitFor } from '@testing-library/vue'
|
||||
import { eventBus } from '@/utils'
|
||||
import factory from '@/__tests__/factory'
|
||||
import compareVersions from 'compare-versions'
|
||||
|
@ -34,9 +34,7 @@ new class extends UnitTestCase {
|
|||
expect(await queryByRole('search')).toBeNull()
|
||||
|
||||
await fireEvent.click(getByTitle('Show or hide the search form'))
|
||||
await this.tick()
|
||||
|
||||
getByRole('search')
|
||||
await waitFor(() => getByRole('search'))
|
||||
})
|
||||
|
||||
it.each([[true, true, true], [false, true, false], [true, false, false], [false, false, false]])(
|
||||
|
@ -46,7 +44,7 @@ new class extends UnitTestCase {
|
|||
|
||||
const { queryAllByTestId } = this.actingAs(factory<User>('user', { is_admin: isAdmin })).render(AppHeader)
|
||||
|
||||
expect(await queryAllByTestId('new-version')).toHaveLength(announcing ? 1 : 0)
|
||||
expect(queryAllByTestId('new-version')).toHaveLength(announcing ? 1 : 0)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import factory from '@/__tests__/factory'
|
||||
import { httpService } from '@/services'
|
||||
import { eventBus } from '@/utils'
|
||||
import { it } from 'vitest'
|
||||
import { EventName } from '@/config'
|
||||
|
@ -8,7 +7,7 @@ import ModalWrapper from './ModalWrapper.vue'
|
|||
|
||||
new class extends UnitTestCase {
|
||||
protected test () {
|
||||
it.each<[string, EventName, User | Song | any]>([
|
||||
it.each<[string, EventName, User | Song | Playlist | any]>([
|
||||
['add-user-form', 'MODAL_SHOW_ADD_USER_FORM', undefined],
|
||||
['edit-user-form', 'MODAL_SHOW_EDIT_USER_FORM', factory('user')],
|
||||
['edit-song-form', 'MODAL_SHOW_EDIT_SONG_FORM', [factory('song')]],
|
||||
|
@ -16,23 +15,7 @@ new class extends UnitTestCase {
|
|||
['edit-smart-playlist-form', 'MODAL_SHOW_EDIT_SMART_PLAYLIST_FORM', factory('playlist')],
|
||||
['about-koel', 'MODAL_SHOW_ABOUT_KOEL', undefined]
|
||||
])('shows %s modal', async (modalName: string, eventName: EventName, eventParams?: any) => {
|
||||
if (modalName === 'edit-song-form') {
|
||||
// mocking the songInfoService.fetch() request made during edit-form modal opening
|
||||
this.mock(httpService, 'request').mockReturnValue(Promise.resolve({ data: {} }))
|
||||
}
|
||||
|
||||
const { findByTestId } = this.render(ModalWrapper, {
|
||||
global: {
|
||||
stubs: {
|
||||
CreateSmartPlaylistForm: this.stub('create-smart-playlist-form'),
|
||||
EditSmartPlaylistForm: this.stub('edit-smart-playlist-form'),
|
||||
AddUserForm: this.stub('add-user-form'),
|
||||
EditUserForm: this.stub('edit-user-form'),
|
||||
EditSongForm: this.stub('edit-song-form'),
|
||||
AboutKoel: this.stub('about-koel')
|
||||
}
|
||||
}
|
||||
})
|
||||
const { findByTestId } = this.render(ModalWrapper)
|
||||
|
||||
eventBus.emit(eventName, eventParams)
|
||||
|
||||
|
|
|
@ -1,33 +1,18 @@
|
|||
<template>
|
||||
<div class="modal-wrapper" :class="{ overlay: showingModalName }">
|
||||
<CreateSmartPlaylistForm v-if="showingModalName === 'create-smart-playlist-form'" @close="close"/>
|
||||
<EditSmartPlaylistForm
|
||||
v-if="showingModalName === 'edit-smart-playlist-form'"
|
||||
:playlist="boundData.playlist"
|
||||
@close="close"
|
||||
/>
|
||||
<EditSmartPlaylistForm v-if="showingModalName === 'edit-smart-playlist-form'" @close="close"/>
|
||||
<AddUserForm v-if="showingModalName === 'add-user-form'" @close="close"/>
|
||||
<EditUserForm v-if="showingModalName === 'edit-user-form'" :user="boundData.user" @close="close"/>
|
||||
<EditSongForm
|
||||
v-if="showingModalName === 'edit-song-form'"
|
||||
:initialTab="boundData.initialTab"
|
||||
:songs="boundData.songs"
|
||||
@close="close"
|
||||
/>
|
||||
<EditUserForm v-if="showingModalName === 'edit-user-form'" @close="close"/>
|
||||
<EditSongForm v-if="showingModalName === 'edit-song-form'" @close="close"/>
|
||||
<AboutKoel v-if="showingModalName === 'about-koel'" @close="close"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineAsyncComponent, ref } from 'vue'
|
||||
import { eventBus, arrayify } from '@/utils'
|
||||
|
||||
interface ModalWrapperBoundData {
|
||||
playlist?: Playlist
|
||||
user?: User
|
||||
songs?: Song[]
|
||||
initialTab?: string
|
||||
}
|
||||
import { defineAsyncComponent, provide, ref } from 'vue'
|
||||
import { arrayify, eventBus } from '@/utils'
|
||||
import { EditSongFormInitialTabKey, PlaylistKey, SongsKey, UserKey } from '@/symbols'
|
||||
|
||||
declare type ModalName =
|
||||
| 'create-smart-playlist-form'
|
||||
|
@ -45,31 +30,37 @@ const EditSongForm = defineAsyncComponent(() => import('@/components/song/SongEd
|
|||
const AboutKoel = defineAsyncComponent(() => import('@/components/meta/AboutKoelModal.vue'))
|
||||
|
||||
const showingModalName = ref<ModalName | null>(null)
|
||||
const boundData = ref<ModalWrapperBoundData>({})
|
||||
|
||||
const close = () => {
|
||||
showingModalName.value = null
|
||||
boundData.value = {}
|
||||
}
|
||||
const close = () => (showingModalName.value = null)
|
||||
|
||||
const playlistToEdit = ref<Playlist>()
|
||||
const userToEdit = ref<User>()
|
||||
const songsToEdit = ref<Song[]>()
|
||||
const editSongFormInitialTab = ref<EditSongFormTabName>('details')
|
||||
|
||||
provide(PlaylistKey, playlistToEdit)
|
||||
provide(UserKey, userToEdit)
|
||||
provide(SongsKey, songsToEdit)
|
||||
provide(EditSongFormInitialTabKey, editSongFormInitialTab)
|
||||
|
||||
eventBus.on({
|
||||
'MODAL_SHOW_ABOUT_KOEL': () => (showingModalName.value = 'about-koel'),
|
||||
'MODAL_SHOW_ADD_USER_FORM': () => (showingModalName.value = 'add-user-form'),
|
||||
'MODAL_SHOW_CREATE_SMART_PLAYLIST_FORM': () => (showingModalName.value = 'create-smart-playlist-form'),
|
||||
|
||||
MODAL_SHOW_EDIT_SMART_PLAYLIST_FORM (playlist: Playlist) {
|
||||
boundData.value.playlist = playlist
|
||||
'MODAL_SHOW_EDIT_SMART_PLAYLIST_FORM': (playlist: Playlist) => {
|
||||
playlistToEdit.value = playlist
|
||||
showingModalName.value = 'edit-smart-playlist-form'
|
||||
},
|
||||
|
||||
MODAL_SHOW_EDIT_USER_FORM (user: User) {
|
||||
boundData.value.user = user
|
||||
'MODAL_SHOW_EDIT_USER_FORM': (user: User) => {
|
||||
userToEdit.value = user
|
||||
showingModalName.value = 'edit-user-form'
|
||||
},
|
||||
|
||||
MODAL_SHOW_EDIT_SONG_FORM (songs: Song | Song[], initialTab = 'details') {
|
||||
boundData.value.songs = arrayify(songs)
|
||||
boundData.value.initialTab = initialTab
|
||||
'MODAL_SHOW_EDIT_SONG_FORM': (songs: Song | Song[], initialTab: EditSongFormTabName = 'details') => {
|
||||
songsToEdit.value = arrayify(songs)
|
||||
editSongFormInitialTab.value = initialTab
|
||||
showingModalName.value = 'edit-song-form'
|
||||
}
|
||||
})
|
||||
|
|
|
@ -25,16 +25,12 @@ new class extends UnitTestCase {
|
|||
protected test () {
|
||||
it('has a YouTube tab if using YouTube ', () => {
|
||||
commonStore.state.use_you_tube = true
|
||||
const { getByTestId } = this.renderComponent()
|
||||
|
||||
getByTestId('extra-tab-youtube')
|
||||
this.renderComponent().getByTestId('extra-tab-youtube')
|
||||
})
|
||||
|
||||
it('does not have a YouTube tab if not using YouTube', async () => {
|
||||
it('does not have a YouTube tab if not using YouTube', () => {
|
||||
commonStore.state.use_you_tube = false
|
||||
const { queryByTestId } = this.renderComponent()
|
||||
|
||||
expect(await queryByTestId('extra-tab-youtube')).toBeNull()
|
||||
expect(this.renderComponent().queryByTestId('extra-tab-youtube')).toBeNull()
|
||||
})
|
||||
|
||||
it.each([['extra-tab-lyrics'], ['extra-tab-album'], ['extra-tab-artist']])('switches to "%s" tab', async (id) => {
|
||||
|
|
|
@ -37,16 +37,17 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, reactive, toRefs } from 'vue'
|
||||
import { computed, inject, reactive, ref, watch } from 'vue'
|
||||
import { cloneDeep, isEqual } from 'lodash'
|
||||
import { playlistStore } from '@/stores'
|
||||
import { alerts, eventBus } from '@/utils'
|
||||
import { useSmartPlaylistForm } from '@/components/playlist/smart-playlist/useSmartPlaylistForm'
|
||||
import { PlaylistKey } from '@/symbols'
|
||||
|
||||
const props = defineProps<{ playlist: Playlist }>()
|
||||
const { playlist } = toRefs(props)
|
||||
const playlist = inject(PlaylistKey, ref<Playlist>())
|
||||
let mutatedPlaylist: Playlist
|
||||
|
||||
const mutatedPlaylist = reactive<Playlist>(cloneDeep(playlist.value))
|
||||
watch(playlist, () => (mutatedPlaylist = reactive(cloneDeep(playlist.value))), { immediate: true })
|
||||
|
||||
const isPristine = computed(() => {
|
||||
return isEqual(mutatedPlaylist.rules, playlist.value.rules) && mutatedPlaylist.name.trim() === playlist.value.name
|
||||
|
|
|
@ -132,23 +132,21 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, reactive, ref, toRefs } from 'vue'
|
||||
import { computed, inject, onMounted, reactive, ref } from 'vue'
|
||||
import { isEqual } from 'lodash'
|
||||
import { alerts, arrayify, defaultCover, pluralize } from '@/utils'
|
||||
import { alerts, defaultCover, pluralize } from '@/utils'
|
||||
import { songStore } from '@/stores'
|
||||
|
||||
import Btn from '@/components/ui/Btn.vue'
|
||||
import SoundBar from '@/components/ui/SoundBar.vue'
|
||||
import { EditSongFormInitialTabKey, SongsKey } from '@/symbols'
|
||||
|
||||
type EditFormData = Pick<Song, 'title' | 'album_name' | 'artist_name' | 'album_artist_name' | 'lyrics' | 'track' | 'disc'>
|
||||
|
||||
type TabName = 'details' | 'lyrics'
|
||||
|
||||
const props = withDefaults(defineProps<{ songs: Song[], initialTab: TabName }>(), { initialTab: 'details' })
|
||||
const { songs, initialTab } = toRefs(props)
|
||||
|
||||
const mutatedSongs = ref<Song[]>([])
|
||||
const currentView = ref<TabName>()
|
||||
const initialTab = inject(EditSongFormInitialTabKey, ref<EditSongFormTabName>('details'))
|
||||
const songs = inject(SongsKey, ref<Song[]>([]))
|
||||
const mutatedSongs = computed(() => songs.value)
|
||||
const currentView = ref<EditSongFormTabName>('details')
|
||||
const loading = ref(false)
|
||||
|
||||
/**
|
||||
|
@ -197,7 +195,6 @@ const displayedAlbumName = computed(() => {
|
|||
const isPristine = computed(() => isEqual(formData, initialFormData))
|
||||
|
||||
const open = async () => {
|
||||
mutatedSongs.value = arrayify(songs.value)
|
||||
currentView.value = initialTab.value
|
||||
const firstSong = mutatedSongs.value[0]
|
||||
|
||||
|
@ -244,7 +241,7 @@ const submit = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
open()
|
||||
onMounted(async () => await open())
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -44,24 +44,29 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { isEqual } from 'lodash'
|
||||
import { reactive, ref, toRefs } from 'vue'
|
||||
import { inject, reactive, ref, watch } from 'vue'
|
||||
import { alerts, parseValidationError } from '@/utils'
|
||||
import { UpdateUserData, userStore } from '@/stores'
|
||||
|
||||
import Btn from '@/components/ui/Btn.vue'
|
||||
import SoundBar from '@/components/ui/SoundBar.vue'
|
||||
import TooltipIcon from '@/components/ui/TooltipIcon.vue'
|
||||
import { UserKey } from '@/symbols'
|
||||
|
||||
const props = defineProps<{ user: User }>()
|
||||
const { user } = toRefs(props)
|
||||
const user = inject(UserKey, ref<User>())
|
||||
|
||||
const originalData: UpdateUserData = {
|
||||
name: user.value.name,
|
||||
email: user.value.email,
|
||||
is_admin: user.value.is_admin
|
||||
}
|
||||
let originalData: UpdateUserData
|
||||
let updateData: UpdateUserData
|
||||
|
||||
const updateData = reactive<UpdateUserData>(Object.assign({}, originalData))
|
||||
watch(user, () => {
|
||||
originalData = {
|
||||
name: user.value.name,
|
||||
email: user.value.email,
|
||||
is_admin: user.value.is_admin
|
||||
}
|
||||
|
||||
updateData = reactive(Object.assign({}, originalData))
|
||||
}, { immediate: true })
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
|
|
|
@ -6,3 +6,8 @@ export const SelectedSongsKey: InjectionKey<Ref<Song[]>> = Symbol('SelectedSongs
|
|||
export const SongListConfigKey: InjectionKey<Partial<SongListConfig>> = Symbol('SongListConfig')
|
||||
export const SongListSortFieldKey: InjectionKey<Ref<SongListSortField>> = Symbol('SongListSortField')
|
||||
export const SongListSortOrderKey: InjectionKey<Ref<SortOrder>> = Symbol('SongListSortOrder')
|
||||
|
||||
export const EditSongFormInitialTabKey: InjectionKey<Ref<EditSongFormTabName>> = Symbol('EditSongFormInitialTab')
|
||||
|
||||
export const PlaylistKey: InjectionKey<Ref<Playlist>> = Symbol('Playlist')
|
||||
export const UserKey: InjectionKey<Ref<User>> = Symbol('User')
|
||||
|
|
2
resources/assets/js/types.d.ts
vendored
2
resources/assets/js/types.d.ts
vendored
|
@ -402,3 +402,5 @@ interface PaginatorResource {
|
|||
current_page: number
|
||||
}
|
||||
}
|
||||
|
||||
type EditSongFormTabName = 'details' | 'lyrics'
|
||||
|
|
Loading…
Reference in a new issue