feat: media page T1
This commit is contained in:
1 parent
67d456baf6
commit
008b0dfbb9
46 files changed
+5742
-204
No files matched your search
@@ -18,7 +18,7 @@ let toastAdd: ReturnType<typeof vi.fn>
|
||||
|
||||
vi.mock('@nuxt/ui/composables', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@nuxt/ui/composables')>()
|
||||
return { ...actual, useToast: () => ({ add: toastAdd }) }
|
||||
return { ...actual, useToast: () => ({ add: toastAdd, remove: vi.fn() }) }
|
||||
})
|
||||
|
||||
type Row = [
|
||||
@@ -455,32 +455,28 @@ describe('Default, many images', () => {
|
||||
expect(document.body.querySelector('[data-testid="image-count"]')?.textContent).toBe(
|
||||
'12 images',
|
||||
)
|
||||
expect(document.body.textContent).not.toContain('Select all')
|
||||
expect(document.body.querySelector('input[type="checkbox"], [role="checkbox"]')).toBeNull()
|
||||
expect(document.body.textContent).toContain('Select all')
|
||||
expect(document.body.querySelectorAll('[role="checkbox"]')).toHaveLength(13)
|
||||
expect(searchInput()).toBeTruthy()
|
||||
expect(textOf(ariaLabel('Sort'))).toBe('Newest')
|
||||
expect(ariaLabel('Grid view').getAttribute('aria-pressed')).toBe('true')
|
||||
expect(ariaLabel('List view').getAttribute('aria-pressed')).toBe('false')
|
||||
})
|
||||
|
||||
it('renders the header Upload button disabled and inert', async () => {
|
||||
it('renders the header Upload button enabled', async () => {
|
||||
await mountPage()
|
||||
|
||||
const upload = findButton('Upload')!
|
||||
expect(upload.disabled).toBe(true)
|
||||
upload.click()
|
||||
await flushPromises()
|
||||
expect(panel()).toBeNull()
|
||||
expect(findButton('Upload')!.disabled).toBe(false)
|
||||
})
|
||||
|
||||
it('renders the mobile pinned Upload button disabled, full width, 48 px', async () => {
|
||||
it('renders the mobile pinned Upload button enabled, full width, 48 px', async () => {
|
||||
await mountPage({}, '/media', MOBILE_WIDTH)
|
||||
|
||||
const buttons = Array.from(document.body.querySelectorAll('button')).filter(
|
||||
(button) => textOf(button) === 'Upload',
|
||||
)
|
||||
expect(buttons).toHaveLength(1)
|
||||
expect(buttons[0]!.disabled).toBe(true)
|
||||
expect(buttons[0]!.disabled).toBe(false)
|
||||
expect(buttons[0]!.className).toContain('h-12')
|
||||
expect(buttons[0]!.className).toContain('inset-x-4')
|
||||
expect(document.body.querySelector('nav[aria-label="breadcrumb"]')?.className).toContain(
|
||||
@@ -614,7 +610,7 @@ describe('The query string is the source of truth', () => {
|
||||
['?q=wall', 'q=wall&filter=all&sort=newest&limit=100'],
|
||||
['?view=list', 'filter=all&sort=newest&limit=100'],
|
||||
['?filter=bogus&sort=zzz', 'filter=all&sort=newest&limit=100'],
|
||||
['?filter=duplicates', 'filter=all&sort=newest&limit=100'],
|
||||
['?filter=duplicates', 'filter=duplicates&sort=newest&limit=100'],
|
||||
])('opening /media%s requests %s', async (url, request) => {
|
||||
await mountPage({}, `/media${url}`)
|
||||
|
||||
@@ -638,7 +634,7 @@ describe('The query string is the source of truth', () => {
|
||||
document.body.innerHTML = ''
|
||||
|
||||
await mountPage({}, '/media?filter=duplicates')
|
||||
expect(tab('All').getAttribute('aria-selected')).toBe('true')
|
||||
expect(tab('Duplicates').getAttribute('aria-selected')).toBe('true')
|
||||
})
|
||||
|
||||
it('drops unknown values from the URL', async () => {
|
||||
@@ -703,23 +699,20 @@ describe('The query string is the source of truth', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('The disabled Duplicates tab', () => {
|
||||
it('does not become selected, does not navigate and sends no request', async () => {
|
||||
describe('The Duplicates tab', () => {
|
||||
it('becomes selected, writes the filter to the URL and requests the duplicates', async () => {
|
||||
await mountPage()
|
||||
const duplicates = tab('Duplicates')
|
||||
|
||||
expect(duplicates.hasAttribute('disabled')).toBe(true)
|
||||
expect(duplicates.hasAttribute('data-disabled')).toBe(true)
|
||||
expect(duplicates.hasAttribute('disabled')).toBe(false)
|
||||
duplicates.focus()
|
||||
duplicates.click()
|
||||
duplicates.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, button: 0 }))
|
||||
press(duplicates, 'Enter')
|
||||
duplicates.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, button: 0 }))
|
||||
await flushPromises()
|
||||
|
||||
expect(duplicates.getAttribute('aria-selected')).toBe('false')
|
||||
expect(tab('All').getAttribute('aria-selected')).toBe('true')
|
||||
expect(router.currentRoute.value.query).toEqual({})
|
||||
expect(listCalls()).toHaveLength(1)
|
||||
expect(tab('Duplicates').getAttribute('aria-selected')).toBe('true')
|
||||
expect(router.currentRoute.value.query).toEqual({ filter: 'duplicates' })
|
||||
expect(lastListPath()).toBe('/v1/media/?filter=duplicates&sort=newest&limit=100')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -799,7 +792,7 @@ describe('Empty library and no results', () => {
|
||||
expect(document.body.textContent).toContain(
|
||||
'Upload your first image. You can use it in any article.',
|
||||
)
|
||||
expect(findButton('Upload an image')!.disabled).toBe(true)
|
||||
expect(findButton('Upload an image')!.disabled).toBe(false)
|
||||
expect(document.body.textContent).toContain('PNG, JPEG, WEBP, SVG · max 10 MB each')
|
||||
})
|
||||
|
||||
@@ -885,7 +878,7 @@ describe('Hover, focus and keyboard', () => {
|
||||
expect(document.activeElement).toBe(list[2])
|
||||
})
|
||||
|
||||
it('opens the panel on Enter and does nothing on Space', async () => {
|
||||
it('opens the panel on Enter and Space does not open it', async () => {
|
||||
await mountPage()
|
||||
|
||||
cards()[1]!.focus()
|
||||
@@ -1000,7 +993,7 @@ describe('Detail panel', () => {
|
||||
expect(textOf(panel())).toContain('This image is safe to delete. No article shows it.')
|
||||
})
|
||||
|
||||
it('duplicate: looks up the hash, excludes the image itself and disables Review duplicates', async () => {
|
||||
it('duplicate: looks up the hash, excludes the image itself and Review duplicates opens the tab', async () => {
|
||||
await mountPage()
|
||||
|
||||
await clickCard('floorboards.jpg')
|
||||
@@ -1012,10 +1005,12 @@ describe('Detail panel', () => {
|
||||
'floorboards-copy.jpg and IMG_2208.jpg have the same content.',
|
||||
)
|
||||
const review = findButton('Review duplicates', alert)!
|
||||
expect(review.disabled).toBe(true)
|
||||
expect(review.disabled).toBe(false)
|
||||
review.click()
|
||||
await flushPromises()
|
||||
expect(router.currentRoute.value.path).toBe('/media')
|
||||
expect(router.currentRoute.value.query).toEqual({ filter: 'duplicates' })
|
||||
expect(panel()).toBeNull()
|
||||
})
|
||||
|
||||
it('duplicate: uses the singular for one other copy', async () => {
|
||||
|
||||
Reference in new issue
Block a user