Files
familienarchiv/frontend/src/lib/components/ConversationThumbnail.svelte.spec.ts
Marcel 7090f9a0e0 feat(briefwechsel): ConversationThumbnail page badge legible at small sizes
Bumps the multi-page badge from text-xs (12px) / px-1.5 py-0.5 to
text-sm (14px) / px-2 py-1. Meets senior-legibility on a 320px phone
without crowding the 120-wide tile — the badge stays tucked in the
top-right corner.

Refs #305
Fixes @leonievoss senior-accessibility concern from PR review

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 21:38:56 +02:00

114 lines
3.2 KiB
TypeScript

import { describe, it, expect, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import ConversationThumbnail from './ConversationThumbnail.svelte';
afterEach(() => {
cleanup();
});
describe('ConversationThumbnail', () => {
it('renders the thumbnail image with a cache-busting v= query param', () => {
render(ConversationThumbnail, {
doc: {
id: '1111',
thumbnailKey: 'thumbnails/1111.jpg',
thumbnailGeneratedAt: '2026-04-10T09:00:00Z',
thumbnailAspect: 'PORTRAIT',
pageCount: 1
}
});
const img = document.querySelector('img') as HTMLImageElement | null;
expect(img).not.toBeNull();
expect(img!.getAttribute('src')).toContain('/api/documents/1111/thumbnail');
expect(img!.getAttribute('src')).toContain('v=');
});
it('uses portrait dimensions when aspect is PORTRAIT', () => {
render(ConversationThumbnail, {
doc: {
id: 'p1',
thumbnailKey: 'thumbnails/p1.jpg',
thumbnailAspect: 'PORTRAIT',
pageCount: 1
}
});
const tile = document.querySelector('[data-testid="conv-thumb-tile"]') as HTMLElement;
expect(tile.getAttribute('data-aspect')).toBe('PORTRAIT');
});
it('uses landscape dimensions when aspect is LANDSCAPE', () => {
render(ConversationThumbnail, {
doc: {
id: 'l1',
thumbnailKey: 'thumbnails/l1.jpg',
thumbnailAspect: 'LANDSCAPE',
pageCount: 1
}
});
const tile = document.querySelector('[data-testid="conv-thumb-tile"]') as HTMLElement;
expect(tile.getAttribute('data-aspect')).toBe('LANDSCAPE');
});
it('falls back to PORTRAIT when thumbnailAspect is missing', () => {
render(ConversationThumbnail, {
doc: {
id: 'n1',
thumbnailKey: 'thumbnails/n1.jpg'
}
});
const tile = document.querySelector('[data-testid="conv-thumb-tile"]') as HTMLElement;
expect(tile.getAttribute('data-aspect')).toBe('PORTRAIT');
});
it('renders the page badge when pageCount is greater than 1', () => {
render(ConversationThumbnail, {
doc: {
id: 'm1',
thumbnailKey: 'thumbnails/m1.jpg',
thumbnailAspect: 'PORTRAIT',
pageCount: 4
}
});
const badge = document.querySelector('[data-testid="conv-thumb-page-badge"]') as HTMLElement;
expect(badge).not.toBeNull();
expect(badge.textContent).toContain('4');
// Senior-readable size: text-sm (14px) rather than text-xs (12px) on a
// small tile avoids marginal legibility on a 320px phone.
expect(badge.className).toContain('text-sm');
});
it('hides the page badge when pageCount is 1 or missing', () => {
render(ConversationThumbnail, {
doc: {
id: 's1',
thumbnailKey: 'thumbnails/s1.jpg',
thumbnailAspect: 'PORTRAIT',
pageCount: 1
}
});
const badge = document.querySelector('[data-testid="conv-thumb-page-badge"]');
expect(badge).toBeNull();
});
it('renders a skeleton placeholder when no thumbnailKey is set yet', () => {
render(ConversationThumbnail, {
doc: {
id: 'blank',
thumbnailAspect: 'PORTRAIT'
}
});
expect(document.querySelector('img')).toBeNull();
const skeleton = document.querySelector('[data-testid="conv-thumb-skeleton"]');
expect(skeleton).not.toBeNull();
expect(skeleton!.className).toContain('motion-safe:animate-pulse');
});
});