mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-09-14 17:42:17 +00:00
ca7f9c0e48
Adds loadSharedPokedex unit tests and a share preview case for every badge, restoring the branch coverage gate. Gives the offline sync BDD poll 30s so a full Living Dex snapshot can finish caching on CI.
69 lines
2.0 KiB
TypeScript
69 lines
2.0 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import sharp from 'sharp';
|
|
import {
|
|
buildSharePreviewSvg,
|
|
escapeXml,
|
|
renderSharePreview,
|
|
SHARE_PREVIEW_HEIGHT,
|
|
SHARE_PREVIEW_WIDTH,
|
|
truncatePreviewText
|
|
} from '$lib/services/SharePreviewService';
|
|
import type { SharedPokedexData } from '$lib/models/SharedPokedex';
|
|
|
|
const shared: SharedPokedexData = {
|
|
name: 'Johto & <Friends>',
|
|
description: 'A shared collection',
|
|
isLivingDex: true,
|
|
isShinyDex: false,
|
|
isOriginDex: false,
|
|
isFormDex: false,
|
|
gameScope: null,
|
|
dexScopes: [],
|
|
combinedData: [],
|
|
total: 100,
|
|
caught: 42,
|
|
completionPercentage: 42
|
|
};
|
|
|
|
describe('share preview rendering', () => {
|
|
it('escapes XML and truncates normalized user text', () => {
|
|
expect(escapeXml(`<tag attr="x">Tom & Jerry's</tag>`)).toBe(
|
|
'<tag attr="x">Tom & Jerry's</tag>'
|
|
);
|
|
expect(truncatePreviewText(' lots of\nspace ', 20)).toBe('lots of space');
|
|
expect(truncatePreviewText('abcdefghij', 6)).toBe('abcde…');
|
|
});
|
|
|
|
it('builds a branded progress card without raw user markup', () => {
|
|
const svg = buildSharePreviewSvg(shared);
|
|
expect(svg).toContain('Johto & <Friends>');
|
|
expect(svg).not.toContain('Johto & <Friends>');
|
|
expect(svg).toContain('42 of 100 Pokémon caught');
|
|
expect(svg).toContain('42%');
|
|
});
|
|
|
|
it('lists every enabled dex badge and omits an empty description', () => {
|
|
const svg = buildSharePreviewSvg({
|
|
...shared,
|
|
description: '',
|
|
isShinyDex: true,
|
|
isOriginDex: true,
|
|
isFormDex: true,
|
|
gameScope: 'Scarlet'
|
|
});
|
|
for (const badge of ['Living', 'Shiny', 'Origin', 'Form', 'Scarlet']) {
|
|
expect(svg).toContain(`class="badge">${badge}</text>`);
|
|
}
|
|
expect(svg).not.toContain('All Games');
|
|
expect(svg).not.toContain('class="description"');
|
|
});
|
|
|
|
it('renders a valid 1200 by 630 PNG', async () => {
|
|
const png = await renderSharePreview(shared);
|
|
const metadata = await sharp(png).metadata();
|
|
expect(metadata.format).toBe('png');
|
|
expect(metadata.width).toBe(SHARE_PREVIEW_WIDTH);
|
|
expect(metadata.height).toBe(SHARE_PREVIEW_HEIGHT);
|
|
});
|
|
});
|