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

import type { FunctionComponent } from 'react';

import { LinkHandler } from './LinkHandler';

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

describe('LinkHandler', () => {
    const linkUrl = 'https://example.com';
    const linkText = 'CLICK ME';

    it('should render a link', async () => {
        const { queryByText } = render(<TestComponent url={linkUrl}>{linkText}</TestComponent>);

        expect((await queryByText(linkText))?.closest('a')).toBeTruthy();
    });

    it('should render a link containing the url', async () => {
        const { queryByText } = render(<TestComponent url={linkUrl}>{linkText}</TestComponent>);

        expect((await queryByText(linkText))?.closest('a')).toHaveAttribute('href', linkUrl);
    });

    it('should render a disabled link', async () => {
        const { queryByText } = render(
            <TestComponent url={linkUrl} attributes={{ disabled: true }}>
                {linkText}
            </TestComponent>,
        );

        expect((await queryByText(linkText))?.closest('a')).toHaveAttribute('disabled');
    });

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

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

    it('should correctly set the action handler', async () => {
        const spy = jest.fn();
        const { queryByText } = render(
            <TestComponent url={linkUrl} attributes={{ onAction: spy }}>
                {linkText}
            </TestComponent>,
        );

        await queryByText(linkText)?.click();

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