import React from 'react';
import { render } from '@testing-library/react';
import { ErrorBoundary } from '../errorBoundary';

describe('<ErrorBoundary>', () => {
    test('renders children', () => {
        const output = 'im behaving';
        const Child = () => <div>{output}</div>;
        const wrapper = render(
            <ErrorBoundary>
                <Child />
            </ErrorBoundary>
        );

        expect(wrapper.getByText(output)).toBeDefined();
    });

    describe('on error', () => {
        const output = 'im misbehaving';
        const error = new Error(output);
        const Child = () => {
            throw error;
        };

        let globalConsoleError: typeof global.console.error;

        beforeEach(() => {
            globalConsoleError = global.console.error;
            global.console.error = vi.fn();
        });

        afterEach(() => {
            global.console.error = globalConsoleError;
        });

        test('renders error message', () => {
            const wrapper = render(
                <ErrorBoundary>
                    <Child />
                </ErrorBoundary>
            );
            const errorMessage = wrapper.container.getElementsByClassName('ErrorMessage').item(0);

            expect(errorMessage).toBeVisible();
        });

        test('invokes error event handler', () => {
            const onError = vi.fn();
            render(
                <ErrorBoundary onError={onError}>
                    <Child />
                </ErrorBoundary>
            );

            expect(onError).toHaveBeenCalledWith(error, expect.any(Object));
        });
    });
});
