// @vitest-environment jsdom import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { en } from '../i18n/en'; import { ResultView } from './ResultView'; const share = vi.hoisted( () => ( { composeShareImage: vi.fn(), downloadShareImage: vi.fn(), copyText: vi.fn(), } ) ); vi.mock('../share', async original => ({ ...await original(), ...share })); describe( 'ResultView', () => { beforeEach( () => { vi.clearAllMocks(); share.composeShareImage.mockResolvedValue( new Blob( [ 'BRANDED' ], { type: 'image/png' } ) ); vi.spyOn( Date, 'now' ).mockReturnValue( 1234 ); } ); afterEach( () => { cleanup(); vi.restoreAllMocks(); } ); it( 'switches between result and comparison and runs all shopper actions', async () => { const onTryAnother = vi.fn(); const onClose = vi.fn(); render( ); expect( screen.getByRole( 'img', { name: 'Result' } ) ).toBeTruthy(); fireEvent.click( screen.getByRole( 'button', { name: 'Compare' } ) ); expect( screen.getByRole( 'img', { name: 'Original' } ).getAttribute( 'src' ) ).toContain( 'garment' ); expect( screen.getByRole( 'img', { name: 'Try-On' } ).getAttribute( 'src' ) ).toContain( 'result' ); fireEvent.click( screen.getByRole( 'button', { name: 'Result' } ) ); expect( screen.queryByRole( 'button', { name: en.result.viralShare.downloadImage } ) ).toBeNull(); fireEvent.click( screen.getByRole( 'button', { name: en.result.viralShare.title } ) ); const download = await screen.findByRole( 'button', { name: en.result.viralShare.downloadImage } ); await waitFor( () => expect( download.hasAttribute( 'disabled' ) ).toBe( false ) ); fireEvent.click( download ); fireEvent.click( screen.getByRole( 'button', { name: 'Try Different Photo' } ) ); fireEvent.click( screen.getByRole( 'button', { name: 'Continue Shopping' } ) ); await waitFor( () => expect( share.downloadShareImage ).toHaveBeenCalledOnce() ); expect( share.downloadShareImage ).not.toHaveBeenCalledWith( 'data:image/png;base64,result', expect.anything() ); expect( screen.getByText( en.result.viralShare.downloaded ) ).toBeDefined(); expect(share.composeShareImage).toHaveBeenCalledWith('data:image/png;base64,result', expect.objectContaining({brandName:'Fixture Store',productImage:'https://shop.test/garment.png',itemName:'Blue Dress'})); expect( onTryAnother ).toHaveBeenCalledOnce(); expect( onClose ).toHaveBeenCalledOnce(); expect( screen.getByText( 'Trying on: Blue Dress' ) ).toBeTruthy(); const shareButton = screen.getByRole( 'button', { name: en.result.viralShare.title } ); const uploadButton = screen.getByRole( 'button', { name: en.result.tryDifferent } ); expect( shareButton.textContent ).toBe( '' ); expect( uploadButton.textContent ).toBe( '' ); expect( shareButton.closest( '.aisthetix-result-actions' ) ).toBe( uploadButton.closest( '.aisthetix-result-actions' ) ); } ); it( 'renders the result-only variant and still composes before download', async () => { render( ); expect( screen.queryByRole( 'button', { name: 'Compare' } ) ).toBeNull(); fireEvent.click( screen.getByRole( 'button', { name: en.result.viralShare.title } ) ); const download = await screen.findByRole( 'button', { name: en.result.viralShare.downloadImage } ); await waitFor( () => expect( download.hasAttribute( 'disabled' ) ).toBe( false ) ); fireEvent.click( download ); await waitFor( () => expect( share.downloadShareImage ).toHaveBeenCalledOnce() ); } ); it( 'reports branded export failure without falling back to the raw render', async () => { share.composeShareImage.mockRejectedValue( new Error( 'tainted canvas' ) ); render( ); fireEvent.click( screen.getByRole( 'button', { name: en.result.viralShare.title } ) ); expect( await screen.findByText( en.result.viralShare.unavailable ) ).toBeTruthy(); expect( screen.getByRole( 'button', { name: en.result.viralShare.downloadImage } ).hasAttribute( 'disabled' ) ).toBe( true ); expect( share.downloadShareImage ).not.toHaveBeenCalled(); } ); } );