import { flushPromises } from '@vue/test-utils' import type { MediaItem } from '@/composables/useMedia' import { imageOfItem, type MediaSummary } from '@/lib/mediaField' import { answerWrite, entry42, fieldWrapper, lookupNames, mountEditor, text, } from './entryEditorKit' import { fieldLibrary } from './mediaFieldKit' import { eventsWithThumbnail } from './schemaTestKit' import type { EntryWrite, SchemaMount } from './schemaTestKit' export const LIBRARY_COUNTS = { all: 48, unused: 2, duplicates: 2 } export function libraryBody(items: MediaItem[] = fieldLibrary()) { return { items, total: 48, page: 1, size: 25, counts: LIBRARY_COUNTS } } export function summaryOf(id: number): MediaSummary { const item = fieldLibrary().find((candidate) => candidate.id === id)! return imageOfItem(item) } export function entryWithThumbnail(thumbnail: number | null, media?: MediaSummary | 'none') { const shown = media === 'none' || thumbnail === null ? undefined : (media ?? summaryOf(thumbnail)) return { ...entry42, data: { ...entry42.data, thumbnail }, ...(shown ? { media: { thumbnail: shown } } : {}), } } export function answerMediaWrite(write: EntryWrite) { const answered = answerWrite(write) const id = (write.body.data as Record).thumbnail return typeof id === 'number' ? { ...answered, media: { thumbnail: summaryOf(id) } } : answered } export function mountMedia( path: string, options: SchemaMount & { required?: boolean thumbnail?: number | null media?: MediaSummary | 'none' } = {}, ) { const { required, thumbnail = null, media, ...rest } = options const type = eventsWithThumbnail({ required: required ?? false }) return mountEditor(path, { type: () => type, content: () => [type], entry: () => entryWithThumbnail(thumbnail, media), writeEntry: answerMediaWrite, library: () => libraryBody(), lookup: lookupNames, ...rest, }) } export function mediaControl() { return fieldWrapper('thumbnail').querySelector('[data-testid="media-control"]')! } export function mediaState() { const box = mediaControl() if (box.querySelector('[data-testid="media-empty"]')) { return 'empty' } return box.querySelector('[data-testid="media-filled"]') ? 'filled' : 'missing' } export function mediaText() { return text(fieldWrapper('thumbnail')) } export function mediaButton(name: string) { return [...fieldWrapper('thumbnail').querySelectorAll('button')].find( (button) => (button.getAttribute('aria-label') ?? text(button)) === name, ) } export function focusedName() { const active = document.activeElement return active?.getAttribute('aria-label') ?? text(active) } export async function pickFromLibrary(filename: string, opener = 'Change image') { mediaButton(opener)!.click() await flushPromises() await flushPromises() const tile = [...document.body.querySelectorAll('[data-picker-tile]')].find( (element) => element.getAttribute('aria-label')!.startsWith(`${filename},`), )! tile.click() await flushPromises() ;[...document.body.querySelectorAll('button')] .find((button) => text(button) === 'Use this image')! .click() await flushPromises() await flushPromises() }