mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
feat(test): song list sorter tests
This commit is contained in:
parent
2c0e3c0bc6
commit
45164a4426
6 changed files with 66 additions and 15 deletions
|
@ -185,7 +185,7 @@ watch(playlistId, async id => {
|
|||
if (playlist.value) {
|
||||
await fetchDetails()
|
||||
listConfig.collaborative = playlist.value.is_collaborative
|
||||
listConfig.hasCustomSort = !playlist.value.is_smart
|
||||
listConfig.hasCustomOrderSort = !playlist.value.is_smart
|
||||
controlsConfig.deletePlaylist = playlist.value.user_id === currentUser.value?.id
|
||||
} else {
|
||||
await triggerNotFound()
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
<SongListSorter
|
||||
v-if="config.sortable"
|
||||
:field="sortField"
|
||||
:has-custom-sort="config.hasCustomSort"
|
||||
:has-custom-order-sort="config.hasCustomOrderSort"
|
||||
:order="sortOrder"
|
||||
:content-type="contentType"
|
||||
@sort="sort"
|
||||
|
|
51
resources/assets/js/components/song/SongListSorter.spec.ts
Normal file
51
resources/assets/js/components/song/SongListSorter.spec.ts
Normal file
|
@ -0,0 +1,51 @@
|
|||
import { screen } from '@testing-library/vue'
|
||||
import { expect, it } from 'vitest'
|
||||
import UnitTestCase from '@/__tests__/UnitTestCase'
|
||||
import Component from './SongListSorter.vue'
|
||||
|
||||
new class extends UnitTestCase {
|
||||
protected test () {
|
||||
it('contains proper items for song-only lists', () => {
|
||||
this.render(Component)
|
||||
|
||||
;['Title', 'Album', 'Artist', 'Track & Disc', 'Time', 'Date Added'].forEach(text => screen.getByText(text))
|
||||
;['Podcast', 'Album or Podcast', 'Author', 'Artist or Author'].forEach(
|
||||
text => expect(screen.queryByText(text)).toBeNull()
|
||||
)
|
||||
})
|
||||
|
||||
it('contains proper items for episode-only lists', () => {
|
||||
this.render(Component, {
|
||||
props: {
|
||||
contentType: 'episodes'
|
||||
}
|
||||
})
|
||||
|
||||
;['Title', 'Podcast', 'Author', 'Time', 'Date Added'].forEach(text => screen.getByText(text))
|
||||
;['Album', 'Album or Podcast', 'Artist', 'Artist or Author'].forEach(
|
||||
text => expect(screen.queryByText(text)).toBeNull()
|
||||
)
|
||||
})
|
||||
|
||||
it('contains proper items for mixed-content lists', () => {
|
||||
this.render(Component, {
|
||||
props: {
|
||||
contentType: 'mixed'
|
||||
}
|
||||
})
|
||||
|
||||
;['Title', 'Album or Podcast', 'Artist or Author', 'Date Added'].forEach(text => screen.getByText(text))
|
||||
;['Album', 'Artist', 'Podcast', 'Author'].forEach(text => expect(screen.queryByText(text)).toBeNull())
|
||||
})
|
||||
|
||||
it('has custom order sort if so configured', () => {
|
||||
this.render(Component, {
|
||||
props: {
|
||||
hasCustomOrderSort: true
|
||||
}
|
||||
})
|
||||
|
||||
screen.getByText('Custom Order')
|
||||
})
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
<li
|
||||
v-for="item in menuItems"
|
||||
:key="item.label"
|
||||
:class="isCurrentField(item.field) && 'active'"
|
||||
:class="currentlySortedBy(item.field) && 'active'"
|
||||
class="cursor-pointer flex justify-between"
|
||||
@click="sort(item.field)"
|
||||
>
|
||||
|
@ -30,28 +30,28 @@ import { faArrowDown, faArrowUp, faCheck, faSort } from '@fortawesome/free-solid
|
|||
import { OnClickOutside } from '@vueuse/components'
|
||||
import { computed, onBeforeUnmount, onMounted, ref, toRefs } from 'vue'
|
||||
import { useFloatingUi } from '@/composables'
|
||||
import { arrayify } from '@/utils'
|
||||
import { arrayify, getPlayableCollectionContentType } from '@/utils'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
field?: MaybeArray<PlayableListSortField>
|
||||
field?: MaybeArray<PlayableListSortField> // the current field(s) being sorted by
|
||||
order?: SortOrder
|
||||
hasCustomSort?: boolean
|
||||
contentType?: 'songs' | 'episodes' | 'mixed'
|
||||
hasCustomOrderSort?: boolean // whether to provide "custom order" sort (like for playlists)
|
||||
contentType?: ReturnType<typeof getPlayableCollectionContentType>
|
||||
}>(), {
|
||||
field: 'title',
|
||||
order: 'asc',
|
||||
hasCustomSort: false,
|
||||
hasCustomOrderSort: false,
|
||||
contentType: 'songs'
|
||||
})
|
||||
|
||||
const { field, order, hasCustomSort, contentType } = toRefs(props)
|
||||
const { field, order, hasCustomOrderSort, contentType } = toRefs(props)
|
||||
|
||||
const emit = defineEmits<{ (e: 'sort', field: MaybeArray<PlayableListSortField>): void }>()
|
||||
|
||||
const button = ref<HTMLButtonElement>()
|
||||
const menu = ref<HTMLDivElement>()
|
||||
|
||||
const menuItems = computed<{ label: string, field: MaybeArray<PlayableListSortField> }[]>(() => {
|
||||
const menuItems = computed(() => {
|
||||
type MenuItems = { label: string, field: MaybeArray<PlayableListSortField> }
|
||||
|
||||
const title: MenuItems = { label: 'Title', field: 'title' }
|
||||
|
@ -69,12 +69,12 @@ const menuItems = computed<{ label: string, field: MaybeArray<PlayableListSortFi
|
|||
let items: MenuItems[] = [title, album, artist, track, time, dateAdded]
|
||||
|
||||
if (contentType.value === 'episodes') {
|
||||
items = [title, author, podcast, time, dateAdded]
|
||||
items = [title, podcast, author, time, dateAdded]
|
||||
} else if (contentType.value === 'mixed') {
|
||||
items = [title, albumOrPodcast, artistOrAuthor, time, dateAdded]
|
||||
}
|
||||
|
||||
if (hasCustomSort.value) {
|
||||
if (hasCustomOrderSort.value) {
|
||||
items.push(customOrder)
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ const sort = (field: MaybeArray<PlayableListSortField>) => {
|
|||
hide()
|
||||
}
|
||||
|
||||
const isCurrentField = (field: MaybeArray<PlayableListSortField>) => isEqual(arrayify(field), arrayify(props.field))
|
||||
const currentlySortedBy = (field: MaybeArray<PlayableListSortField>) => isEqual(arrayify(field), arrayify(props.field))
|
||||
|
||||
onMounted(() => menu.value && setup())
|
||||
onBeforeUnmount(() => teardown())
|
||||
|
|
|
@ -27,7 +27,7 @@ export const useSongList = (
|
|||
sortable: true,
|
||||
reorderable: false,
|
||||
collaborative: false,
|
||||
hasCustomSort: false
|
||||
hasCustomOrderSort: false
|
||||
}
|
||||
) => {
|
||||
const filterKeywords = ref('')
|
||||
|
|
2
resources/assets/js/types.d.ts
vendored
2
resources/assets/js/types.d.ts
vendored
|
@ -457,7 +457,7 @@ interface PlayableListConfig {
|
|||
sortable: boolean
|
||||
reorderable: boolean
|
||||
collaborative: boolean
|
||||
hasCustomSort: boolean
|
||||
hasCustomOrderSort: boolean
|
||||
}
|
||||
|
||||
type PlayableListContext = {
|
||||
|
|
Loading…
Reference in a new issue