import sharp from 'sharp'; import { describe, expect, it } from 'vitest'; import { BUILD_SOCIAL_CARD_HEIGHT, BUILD_SOCIAL_CARD_WIDTH, buildBuildSocialCardSvg, renderBuildSocialCardPng, type BuildSocialCardInput, } from './build-social-card'; const input: BuildSocialCardInput = { title: 'Vanguard Counter-Offensive', author: 'Agent Kelso', primaryWeapon: 'Police M4', secondaryWeapon: 'Super 90', firepower: 1280, toughness: 940, engineering: 615, supportingAttributes: [ { label: 'Critical Hit Chance', value: '18.5%' }, { label: 'Headshot Damage', value: '42%' }, { label: 'Armor', value: '12,400' }, ], visibility: 'public', directUrl: 'shd.build/builds/vanguard-counter-offensive', }; describe('build social card', () => { it('escapes XML injection and keeps inputs out of markup and URLs', () => { const attack = ``; const svg = buildBuildSocialCardSvg({ ...input, title: attack, author: `A\u0000gent <&> "one" 'two'`, directUrl: `javascript:alert(1)\n${attack}`, supportingAttributes: [{ label: attack, value: attack }], }); expect(svg).not.toContain(']+\s(?:href|xlink:href)\s*=/gu); }); it('wraps and truncates long Unicode text without splitting graphemes', () => { const family = '👨‍👩‍👧‍👦'; const svg = buildBuildSocialCardSvg({ ...input, title: `${family.repeat(31)} ${family.repeat(31)} ${family.repeat(31)}`, author: `Zoë ${'e\u0301'.repeat(60)}`, directUrl: `shd.build/builds/${'路'.repeat(130)}`, }); const titleBlock = svg.match(/(.*?)<\/text>/u)?.[1] ?? ''; expect(titleBlock.match(/ { const withExtraFacts = { ...input, supportingAttributes: [ ...input.supportingAttributes!, { label: 'Must not render', value: '999' }, ], }; const first = buildBuildSocialCardSvg(withExtraFacts); const second = buildBuildSocialCardSvg(withExtraFacts); expect(first).toBe(second); expect(first).toContain('width="1200" height="630"'); expect(first).toContain('SHD { const png = await renderBuildSocialCardPng(input); const metadata = await sharp(png).metadata(); expect(png.subarray(0, 8)).toEqual( Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]), ); expect(metadata.format).toBe('png'); expect(metadata.width).toBe(BUILD_SOCIAL_CARD_WIDTH); expect(metadata.height).toBe(BUILD_SOCIAL_CARD_HEIGHT); expect(png.byteLength).toBeLessThan(1_000_000); }); });