// @vitest-environment jsdom
import React from 'react';
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import UploadScreen from './UploadScreen';
import { I18nProvider } from '../i18n';
vi.mock('./TrimModal', () => ({
default: ({
file,
onClose,
onConfirm,
}: {
file: File;
onClose: () => void;
onConfirm: (file: File, startTime: number, endTime: number) => void;
}) => (
),
}));
describe('UploadScreen', () => {
const renderUploadScreen = (onUpload = () => {}) =>
render(
,
);
afterEach(() => {
cleanup();
});
it('starts from the editor default subtitle size and position and updates the preview', () => {
renderUploadScreen();
const sizeSlider = screen.getByLabelText(/subtitle initial size/i);
const positionSlider = screen.getByLabelText(/subtitle initial position/i);
const preview = screen.getByTestId('upload-subtitle-preview');
expect(sizeSlider).toHaveValue('24');
expect(positionSlider).toHaveValue('10');
expect(preview).toHaveStyle({ fontSize: '24px', bottom: '10%' });
fireEvent.change(sizeSlider, { target: { value: '32' } });
fireEvent.change(positionSlider, { target: { value: '18' } });
expect(preview).toHaveStyle({ fontSize: '32px', bottom: '18%' });
});
it('shows a fixed English subtitle language and the supported TTS languages', () => {
renderUploadScreen();
expect(screen.getByText('Subtitle Language')).toBeInTheDocument();
expect(screen.getAllByText('English')).toHaveLength(2);
expect(screen.getByText('TTS Language')).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Chinese' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Cantonese' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'French' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Indonesian' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'German' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Filipino' })).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Arabic' })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Japanese' })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Korean' })).not.toBeInTheDocument();
});
it('passes subtitle defaults through when upload is confirmed', () => {
const onUpload = vi.fn();
renderUploadScreen(onUpload);
fireEvent.change(screen.getByLabelText(/subtitle initial size/i), {
target: { value: '30' },
});
fireEvent.change(screen.getByLabelText(/subtitle initial position/i), {
target: { value: '16' },
});
fireEvent.click(screen.getByRole('button', { name: 'French' }));
fireEvent.change(screen.getByLabelText(/upload video file/i), {
target: {
files: [new File(['video'], 'clip.mp4', { type: 'video/mp4' })],
},
});
fireEvent.click(screen.getByRole('button', { name: /confirm trim/i }));
expect(onUpload).toHaveBeenCalledWith(
expect.any(File),
'English',
'French',
{
fontSize: 30,
bottomOffsetPercent: 16,
},
1,
5,
);
});
it('clears the pending upload after closing the trim preview', () => {
renderUploadScreen();
const fileInput = screen.getByLabelText(/upload video file/i);
const file = new File(['video'], 'clip.mp4', { type: 'video/mp4' });
fireEvent.change(fileInput, {
target: {
files: [file],
},
});
expect(screen.getByRole('button', { name: /close trim/i })).toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: /close trim/i }));
expect(screen.queryByRole('button', { name: /close trim/i })).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: /generate translated video/i })).toBeDisabled();
});
});