mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 08:21:39 -06:00
070201e163
The Book Dock discarded every upload failure, so a rejected file looked like nothing happened. List failed files with a translated reason, offer retry where it can help, and stop a failed token refresh, abort or timeout from stalling the upload queue. Dropped files of unsupported types are reported instead of ignored. Refs #1739
92 lines
3.5 KiB
TypeScript
92 lines
3.5 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import { shallowMount } from '@vue/test-utils'
|
|
import { ref } from 'vue'
|
|
import BookDockView from '../BookDockView.vue'
|
|
|
|
const apiMock = vi.fn<(url: string) => Promise<Response>>(
|
|
async (_url: string) =>
|
|
({
|
|
ok: true,
|
|
json: async () => ({ items: [], total: 7000, page: 1, size: 20 }),
|
|
}) as Response,
|
|
)
|
|
|
|
vi.mock('@/lib/api', () => ({ api: (url: string) => apiMock(url) }))
|
|
vi.mock('@/features/auth/composables/usePermissions', () => ({
|
|
usePermissions: () => ({ isDemoRestrictedAccount: ref(false), hasPermission: () => false }),
|
|
}))
|
|
vi.mock('@/features/book-dock/composables/useBookDockSummary', () => ({
|
|
useBookDockSummary: () => ({
|
|
summary: ref({ total: 7000, paused: false }),
|
|
fetchSummary: vi.fn<() => void>(),
|
|
subscribe: vi.fn<() => void>(),
|
|
onBookDockChange: () => vi.fn<() => void>(),
|
|
socketConnected: ref(true),
|
|
}),
|
|
}))
|
|
vi.mock('@/features/book-dock/composables/useBookDockStatistics', () => ({
|
|
useBookDockStatistics: () => ({ statistics: ref(null), fetchStatistics: vi.fn<() => void>() }),
|
|
}))
|
|
const { addFilesMock } = vi.hoisted(() => ({ addFilesMock: vi.fn<(files: FileList | File[]) => void>() }))
|
|
|
|
vi.mock('@/features/book-dock/composables/useBookDockUpload', () => ({
|
|
useBookDockUpload: () => ({ addFiles: addFilesMock, isUploading: ref(false) }),
|
|
SUPPORTED_FORMATS: ['epub'],
|
|
SUPPORTED_FORMATS_ACCEPT: '.epub',
|
|
}))
|
|
vi.mock('@/features/book-dock/composables/useBookDockConflicts', () => ({
|
|
useBookDockConflicts: () => ({ conflicts: ref([]), scheduleConflicts: vi.fn<() => void>(), cancelConflicts: vi.fn<() => void>() }),
|
|
}))
|
|
|
|
describe('BookDockView pagination', () => {
|
|
it('keeps a 7000-file dock navigable without rendering hundreds of buttons', async () => {
|
|
const wrapper = shallowMount(BookDockView, { global: { stubs: { PaginationNav: false } } })
|
|
await vi.waitFor(() => expect(wrapper.findAll('nav button')).toHaveLength(6))
|
|
|
|
expect(
|
|
wrapper
|
|
.findAll('nav button')
|
|
.map((button) => button.text())
|
|
.filter(Boolean),
|
|
).toEqual(['1', '2', '349', '350'])
|
|
expect(wrapper.get('[aria-current="page"]').text()).toBe('1')
|
|
expect(String(apiMock.mock.calls[0]?.[0])).toContain('limit=20')
|
|
|
|
await wrapper.get('[aria-label="Go to page 350"]').trigger('click')
|
|
await vi.waitFor(() => expect(String(apiMock.mock.calls.at(-1)?.[0])).toContain('page=350'))
|
|
expect(wrapper.get('[aria-current="page"]').text()).toBe('350')
|
|
wrapper.unmount()
|
|
})
|
|
})
|
|
|
|
describe('BookDockView uploads', () => {
|
|
it('shows the upload failures panel on the page', () => {
|
|
const wrapper = shallowMount(BookDockView)
|
|
|
|
expect(wrapper.findComponent({ name: 'BookDockUploadFailures' }).exists()).toBe(true)
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('hands every dropped file to the uploader, including ones it will refuse, so the refusal is reported', async () => {
|
|
addFilesMock.mockClear()
|
|
const wrapper = shallowMount(BookDockView)
|
|
const files = [new File(['x'], 'dune.epub'), new File(['x'], 'notes.docx')]
|
|
|
|
await wrapper.get('main').trigger('drop', { dataTransfer: { files } })
|
|
|
|
expect(addFilesMock).toHaveBeenCalledTimes(1)
|
|
expect([...addFilesMock.mock.calls[0]![0]].map((file) => file.name)).toEqual(['dune.epub', 'notes.docx'])
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('ignores a drop that carries no files', async () => {
|
|
addFilesMock.mockClear()
|
|
const wrapper = shallowMount(BookDockView)
|
|
|
|
await wrapper.get('main').trigger('drop', { dataTransfer: { files: [] } })
|
|
|
|
expect(addFilesMock).not.toHaveBeenCalled()
|
|
wrapper.unmount()
|
|
})
|
|
})
|