import { captureException } from '@sentry/nextjs';
import { fireEvent, render, screen } from '@testing-library/react';
import { useScopedI18n } from '@/i18n/client';
import ClientError from './error';

vi.mock('@sentry/nextjs', () => ({
    ...vi.importActual('@sentry/nextjs'),
    captureException: vi.fn(),
}));

vi.mock('@/i18n/client', () => ({
    useScopedI18n: vi.fn().mockReturnValue((term: string) => term),
}));

vi.spyOn(console, 'error').mockImplementation(vi.fn());

describe('<ClientError>', () => {
    const error = new Error('Test error');
    const resetMock = vi.fn();

    describe('scoped i18n', () => {
        it('should recieve correct arguments', () => {
            render(<ClientError error={error} reset={resetMock} />);

            expect(useScopedI18n).toHaveBeenCalledWith('pages.profile');
        });
    });

    describe('Sentry', () => {
        it('should capture exception', () => {
            render(<ClientError error={error} reset={resetMock} />);

            expect(captureException).toHaveBeenCalledWith(error);
        });
    });

    it('should render title', () => {
        render(<ClientError error={error} reset={resetMock} />);

        expect(screen.getByText('error.title')).toBeVisible();
    });

    it('should render error message', () => {
        render(<ClientError error={error} reset={resetMock} />);

        expect(screen.getByText('Test error')).toBeVisible();
    });

    it('should render reset button', () => {
        render(<ClientError error={error} reset={resetMock} />);

        expect(screen.getByText('error.action')).toBeVisible();
        expect(screen.getByText('error.action')).toBeEnabled();
    });

    describe('when user clicks on button', () => {
        it('should call "reset" function', () => {
            render(<ClientError error={error} reset={resetMock} />);

            const button = screen.getByText('error.action');

            fireEvent.click(button);

            expect(resetMock).toBeCalled();
        });
    });
});
