feat: media page T1
This commit is contained in:
1 parent
67d456baf6
commit
008b0dfbb9
46 files changed
+5742
-204
No files matched your search
@@ -0,0 +1,98 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { MediaItem } from '@/composables/useMedia'
|
||||
import { groupDuplicates, mergeArticleCount } from '../mediaDuplicates'
|
||||
|
||||
function copy(id: number, usedIn: number, createdAt: string, overrides: Partial<MediaItem> = {}) {
|
||||
return {
|
||||
id,
|
||||
filename: `copy-${id}.jpg`,
|
||||
url: `/media/copy-${id}.jpg`,
|
||||
size: 2516582,
|
||||
content_type: 'image/jpeg',
|
||||
width: 3600,
|
||||
height: 2400,
|
||||
sha256: 'aa',
|
||||
uploaded_by: 'Inès Duarte',
|
||||
created_at: createdAt,
|
||||
used_in: usedIn,
|
||||
duplicate: true,
|
||||
...overrides,
|
||||
} satisfies MediaItem
|
||||
}
|
||||
|
||||
describe('groupDuplicates', () => {
|
||||
it.each([
|
||||
[
|
||||
'the most used copy',
|
||||
[
|
||||
copy(1, 4, '2026-06-14T12:00:00Z'),
|
||||
copy(2, 3, '2026-09-02T12:00:00Z'),
|
||||
copy(3, 2, '2026-08-30T12:00:00Z'),
|
||||
],
|
||||
1,
|
||||
],
|
||||
[
|
||||
'the oldest copy at equal use',
|
||||
[copy(1, 2, '2026-08-29T12:00:00Z'), copy(2, 2, '2026-08-21T12:00:00Z')],
|
||||
2,
|
||||
],
|
||||
[
|
||||
'the oldest unused copy',
|
||||
[copy(1, 0, '2026-09-03T12:00:00Z'), copy(2, 0, '2026-09-01T12:00:00Z')],
|
||||
2,
|
||||
],
|
||||
[
|
||||
'the lowest id at equal use and date',
|
||||
[copy(9, 1, '2026-09-03T12:00:00Z'), copy(4, 1, '2026-09-03T12:00:00Z')],
|
||||
4,
|
||||
],
|
||||
])('suggests %s', (_name, copies, suggestedId) => {
|
||||
const [group] = groupDuplicates(copies)
|
||||
|
||||
expect(group!.suggested.id).toBe(suggestedId)
|
||||
expect(group!.copies[0]!.id).toBe(suggestedId)
|
||||
})
|
||||
|
||||
it('groups by sha256, orders copies and puts the oldest suggested copy first', () => {
|
||||
const groups = groupDuplicates([
|
||||
copy(7, 2, '2026-08-29T12:00:00Z', { sha256: 'bb', size: 3250585 }),
|
||||
copy(5, 3, '2026-09-02T12:00:00Z'),
|
||||
copy(9, 1, '2026-08-21T12:00:00Z', { sha256: 'bb', size: 3250585 }),
|
||||
copy(12, 4, '2026-06-14T12:00:00Z'),
|
||||
copy(6, 2, '2026-08-30T12:00:00Z'),
|
||||
])
|
||||
|
||||
expect(groups.map((group) => group.copies.map((item) => item.id))).toEqual([
|
||||
[12, 5, 6],
|
||||
[7, 9],
|
||||
])
|
||||
expect(groups.map((group) => group.header)).toEqual([
|
||||
'3 identical images · 2.4 MB each · 3600 × 2400',
|
||||
'2 identical images · 3.1 MB each · 3600 × 2400',
|
||||
])
|
||||
})
|
||||
|
||||
it('reads Vector for SVG groups and ignores single copies', () => {
|
||||
const groups = groupDuplicates([
|
||||
copy(1, 0, '2026-09-01T12:00:00Z', { width: null, height: null, size: 8192 }),
|
||||
copy(2, 0, '2026-09-02T12:00:00Z', { width: null, height: null, size: 8192 }),
|
||||
copy(3, 0, '2026-09-02T12:00:00Z', { sha256: 'zz' }),
|
||||
])
|
||||
|
||||
expect(groups).toHaveLength(1)
|
||||
expect(groups[0]!.header).toBe('2 identical images · 8 KB each · Vector')
|
||||
})
|
||||
})
|
||||
|
||||
describe('mergeArticleCount', () => {
|
||||
it('sums the use of every copy except the kept one', () => {
|
||||
const copies = [
|
||||
copy(12, 4, '2026-06-14T12:00:00Z'),
|
||||
copy(5, 3, '2026-09-02T12:00:00Z'),
|
||||
copy(6, 2, '2026-08-30T12:00:00Z'),
|
||||
]
|
||||
|
||||
expect(mergeArticleCount(copies, 12)).toBe(5)
|
||||
expect(mergeArticleCount(copies, 6)).toBe(7)
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user