import { type Mock, beforeEach, describe, expect, it, vi } from 'vitest'; import '@testing-library/jest-dom'; import { useAttestations } from '@/identity/hooks/useAttestations'; import { useName } from '@/identity/hooks/useName'; import { render, screen, waitFor } from '@testing-library/react'; import { base, baseSepolia, optimism } from 'viem/chains'; import { getSlicedAddress } from '../utils/getSlicedAddress'; import { Badge } from './Badge'; import { useIdentityContext } from './IdentityProvider'; import { Name } from './Name'; vi.mock('@/identity/hooks/useAttestations', () => ({ useAttestations: vi.fn(), })); vi.mock('@/identity/hooks/useName', () => ({ useName: vi.fn(), })); vi.mock('@/identity/utils/getSlicedAddress', () => ({ getSlicedAddress: vi.fn(), })); vi.mock('@/identity/components/IdentityProvider', () => ({ useIdentityContext: vi.fn(), })); describe('Name', () => { const testName = 'testname.eth'; const testIdentityProviderAddress = '0xIdentityAddress'; const testNameComponentAddress = '0xNameComponentAddress'; const mockUseName = useName as Mock; beforeEach(() => { vi.clearAllMocks(); vi.spyOn(console, 'error').mockImplementation(vi.fn()); }); it('should console.error and return null when no address is provided', () => { (useName as Mock).mockReturnValue({ data: undefined }); vi.mocked(useIdentityContext).mockReturnValue({ // @ts-expect-error - Testing undefined address case address: undefined, chain: undefined, }); const consoleErrorSpy = vi .spyOn(console, 'error') .mockImplementation(() => {}); const { container } = render(); expect(consoleErrorSpy).toHaveBeenCalledWith( 'Name: an Ethereum address must be provided to the Identity or Name component.', ); expect(container.firstChild).toBeNull(); }); it('displays ENS name when available', () => { (useIdentityContext as Mock).mockReturnValue({ schemaId: '0x123', }); mockUseName.mockReturnValue({ data: testName, isLoading: false, }); render(); expect(screen.getByText(testName)).toBeInTheDocument(); }); it('use identity context address if provided', () => { (useIdentityContext as Mock).mockReturnValue({ schemaId: '0x123', address: testIdentityProviderAddress, }); mockUseName.mockReturnValue({ data: testName, isLoading: false, }); render(); expect(mockUseName).toHaveBeenCalledWith({ address: testIdentityProviderAddress, chain: undefined, }); }); it('use identity context chain if provided', () => { (useIdentityContext as Mock).mockReturnValue({ schemaId: '0x123', chain: optimism, }); mockUseName.mockReturnValue({ data: testName, isLoading: false, }); render(); expect(mockUseName).toHaveBeenCalledWith({ address: testNameComponentAddress, chain: optimism, }); }); it('use component address over identity context if both are provided', () => { (useIdentityContext as Mock).mockReturnValue({ schemaId: '0x123', chain: optimism, address: testIdentityProviderAddress, }); mockUseName.mockReturnValue({ data: testName, isLoading: false, }); render(); expect(mockUseName).toHaveBeenCalledWith({ address: testNameComponentAddress, chain: optimism, }); }); it('use component chain over identity context if both are provided', () => { (useIdentityContext as Mock).mockReturnValue({ schemaId: '0x123', chain: optimism, address: testIdentityProviderAddress, }); mockUseName.mockReturnValue({ data: testName, isLoading: false, }); render(); expect(mockUseName).toHaveBeenCalledWith({ address: testNameComponentAddress, chain: base, }); }); it('displays custom chain ENS name when available', () => { (useIdentityContext as Mock).mockReturnValue({ schemaId: '0x123', }); mockUseName.mockReturnValue({ data: testName, isLoading: false, }); render(); expect(screen.getByText(testName)).toBeInTheDocument(); }); it('displays sliced address when ENS name is not available', () => { (useIdentityContext as Mock).mockReturnValue({ schemaId: '0x123', }); mockUseName.mockReturnValue({ data: null, isLoading: false, }); (getSlicedAddress as Mock).mockReturnValue('0xName...ess'); render(); expect(screen.getByText('0xName...ess')).toBeInTheDocument(); }); it('displays empty when ens still fetching', () => { mockUseName.mockReturnValue({ data: null, isLoading: true }); render(); expect(screen.queryByText(testName)).not.toBeInTheDocument(); expect(getSlicedAddress).toHaveBeenCalledTimes(0); }); it('renders badge when Badge is passed, user is attested and address set in Identity', async () => { (useIdentityContext as Mock).mockReturnValue({ address: testNameComponentAddress, schemaId: '0x123', }); (useAttestations as Mock).mockReturnValue(['attestation']); mockUseName.mockReturnValue({ data: 'ens_name', isLoading: false, }); render( , ); await waitFor(() => { const badge = screen.getByTestId('ockBadge'); expect(badge).toBeInTheDocument(); }); }); it('renders badge when Badge is passed, user is attested and address set in Name', async () => { (useIdentityContext as Mock).mockReturnValue({ schemaId: '0x123', }); (useAttestations as Mock).mockReturnValue(['attestation']); mockUseName.mockReturnValue({ address: testNameComponentAddress, data: 'ens_name', isLoading: false, }); render( , ); await waitFor(() => { const badge = screen.getByTestId('ockBadge'); expect(badge).toBeInTheDocument(); }); }); });