import React from 'react' import { describe, expect, it } from 'vitest' import { renderWithProviders, screen } from '../../test/utils' import { Avatar } from '.' describe('Avatar', () => { const emojiFontSize = (size: number) => { renderWithProviders() return screen.getByText(/\p{Emoji}/u) } it('scales the emoji with small (<32px) avatars so it does not overpower them', () => { expect(emojiFontSize(18)).toHaveStyle({ fontSize: '8px', lineHeight: '1' }) }) it('scales up proportionally as small avatars grow', () => { expect(emojiFontSize(20)).toHaveStyle({ fontSize: '9px' }) }) it('stays continuous with the fixed 14px step at the 32px boundary', () => { // 31 * 0.45 rounds to 14, matching the >=32px fixed size. expect(emojiFontSize(31)).toHaveStyle({ fontSize: '14px' }) }) it('keeps fixed emoji sizes for larger avatars', () => { expect(emojiFontSize(40)).toHaveStyle({ fontSize: '14px' }) }) it.each([ [32, '14px'], [55, '14px'], [56, '18px'], [119, '18px'], [120, '36px'], ])( 'uses the exact fixed font size at the %spx boundary', (size, fontSize) => { expect(emojiFontSize(size)).toHaveStyle({ fontSize }) } ) it('does not show a star by default but shows one when starred', () => { const defaultAvatar = renderWithProviders( ) expect(defaultAvatar.container.querySelector('svg')).not.toBeInTheDocument() const starredAvatar = renderWithProviders( ) expect(starredAvatar.container.querySelector('svg')).toBeInTheDocument() }) it('uses a squircle by default and a circle when explicitly requested', () => { const squircleAvatar = renderWithProviders( ) const squircleElements = squircleAvatar.container.querySelectorAll( '[style*="border-radius"]' ) expect(squircleElements).toHaveLength(3) squircleElements.forEach((element) => expect(element).toHaveStyle({ borderRadius: '1rem' }) ) const circleAvatar = renderWithProviders( ) const circleElements = circleAvatar.container.querySelectorAll( '[style*="border-radius"]' ) expect(circleElements).toHaveLength(3) circleElements.forEach((element) => expect(element).toHaveStyle({ borderRadius: '50%' }) ) }) it('only applies the AI ring when dmAgentEnabled is true', () => { const defaultAvatar = renderWithProviders( ) expect( defaultAvatar.container.querySelector('[data-testid="avatar-ring"]') ).not.toHaveStyle({ borderWidth: '2px', borderStyle: 'solid', }) const enabledAvatar = renderWithProviders( ) expect( enabledAvatar.container.querySelector('[data-testid="avatar-ring"]') ).toHaveStyle({ borderWidth: '2px', borderStyle: 'solid', borderColor: 'var(--AI-Gradient, #7F22FE)', boxShadow: 'inset 0 1px 2px 0 rgba(255, 255, 255, 0.5)', }) const smallEnabledAvatar = renderWithProviders( ) expect( smallEnabledAvatar.container.querySelector('[data-testid="avatar-ring"]') ).toHaveStyle({ borderWidth: '1px' }) }) it('renders an image instead of the emoji fallback when image is provided', () => { const fallbackAvatar = renderWithProviders() expect( fallbackAvatar.container.querySelector('img') ).not.toBeInTheDocument() expect(fallbackAvatar.container).toHaveTextContent('🍎') expect( fallbackAvatar.container.querySelector('.avatar-fallback') ).toHaveClass( 'avatar-fallback', 'flex', 'h-full', 'w-full', 'items-center', 'justify-center', 'font-semibold', 'select-none', 'transition-colors' ) const imageAvatar = renderWithProviders( ) expect(imageAvatar.container.querySelector('img')).toHaveAttribute( 'src', 'https://example.com/avatar.png' ) expect(imageAvatar.container).not.toHaveTextContent('🍎') }) it('applies the fallback background color and forwards custom classes', () => { const { container } = renderWithProviders( ) const root = container.firstElementChild const ring = container.querySelector('[data-testid="avatar-ring"]') expect(root).toHaveClass('relative', 'flex-shrink-0', 'custom-avatar') expect(ring).toHaveClass('h-full', 'w-full', 'bg-transparent') expect(root).toHaveStyle({ backgroundColor: '#FFD1DD', width: '40px', height: '40px', }) }) })