import * as React from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom';

import type { FunctionComponent } from 'react';
import { ButtonHandler } from './ButtonHandler';
import Mock = jest.Mock;

const TestComponent: FunctionComponent<{ onAction: () => void; attributes?: object; children?: React.ReactNode }> = ({
    onAction,
    attributes,
    children,
}) => {
    return (
        // eslint-disable-next-line react/jsx-props-no-spreading
        <ButtonHandler onAction={onAction} {...attributes}>
            {children}
        </ButtonHandler>
    );
};

describe('ButtonHandler', () => {
    const buttonText = 'CLICK ME';
    let actionHandler: Mock;

    beforeEach(() => {
        actionHandler = jest.fn();
    });

    it('should render a button', async () => {
        const { queryByText } = render(<TestComponent onAction={actionHandler}>{buttonText}</TestComponent>);

        expect(await queryByText(buttonText)?.closest('button')).toBeTruthy();
    });

    it('should render a disabled button', async () => {
        const { queryByText } = render(
            <TestComponent onAction={actionHandler} attributes={{ disabled: true }}>
                {buttonText}
            </TestComponent>,
        );

        expect((await queryByText(buttonText))?.closest('button')).toBeDisabled();
    });

    it('should render nothing if "hidden" is true', async () => {
        const { queryByText } = render(
            <TestComponent onAction={actionHandler} attributes={{ hidden: true }}>
                {buttonText}
            </TestComponent>,
        );

        expect(await queryByText(buttonText)).toBeNull();
    });

    it('should correctly set the action handler', async () => {
        const { queryByText } = render(<TestComponent onAction={actionHandler}>{buttonText}</TestComponent>);

        await queryByText(buttonText)?.click();

        expect(actionHandler).toBeCalledTimes(1);
    });
});
