import { describe, it, expect } from 'vitest'; import { validateAvatar, avatarReference } from '../server/avatar.mjs'; import { publicUser } from '../server/auth.mjs'; const png = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4z8DwHwAFgAI/ScLbtAAAAABJRU5ErkJggg=='; describe('avatares personales', () => { it('acepta los avatares locales y permite volver a las iniciales', () => { expect(validateAvatar({ preset: 'oca' })).toEqual({ preset: 'oca' }); expect(validateAvatar({ preset: null })).toBeNull(); expect(() => validateAvatar({ preset: 'https://unknown/avatar.svg' }), ).toThrow(); expect(avatarReference({ avatar: { preset: 'gato' } })).toBe( '/avatars/gato.svg', ); }); it('guarda la imagen y devuelve solo su referencia pública, sin datos privados', () => { const avatar = validateAvatar({ image: png }); const user = publicUser({ id: 'test', nick: 'Test', password: 'private', email: 'secret', avatar, }); expect(user?.avatar).toMatch(/^\/api\/avatars\/test\?v=[a-f0-9]{16}$/); expect(JSON.stringify(user)).not.toContain('base64'); expect(user).not.toHaveProperty('password'); expect(user).not.toHaveProperty('email'); }); it('rechaza SVG, contenido falso, imágenes excesivas y dimensiones grandes', () => { for (const image of [ 'data:image/svg+xml;base64,AAAA', 'data:image/png;base64,AAAA', png + 'A'.repeat(90000), ]) expect(() => validateAvatar({ image })).toThrow(); const bytes = Buffer.from(png.slice(22), 'base64'); bytes.writeUInt32BE(4096, 16); expect(() => validateAvatar({ image: 'data:image/png;base64,' + bytes.toString('base64'), }), ).toThrow('256'); }); });