import React from 'react';
import { render, screen } from '@testing-library/react';
import { testComponent } from 'lib/test-utils/common';
import { Field, Props, CLASS_NAME } from '../field';

describe('<Field>', () => {
    const defaultProps: Props = {
        controlId: 'email',
        labelText: 'This is a Label',
        children: <input type="text" />,
    };

    testComponent(Field, defaultProps, CLASS_NAME);

    const renderComponent = (props: Partial<Props>) =>
        render(<Field {...defaultProps} {...props} />);

    test('applies style', () => {
        const r = renderComponent({ style: { marginTop: 10 } });
        expect(r.getByTestId(CLASS_NAME)).toHaveStyle({ marginTop: '10px' });
    });

    describe('inner Label', () => {
        test('has label', () => {
            const text = 'LABEL TEXT';
            const r = renderComponent({ labelText: text });

            expect(r.getByTestId('FormLabel')).toHaveTextContent(text);
        });

        test('forward icons to Label', () => {
            const r = renderComponent({ labelIcons: ['dot', 'dot'] });

            expect(r.getAllByTestId('DotGlyphIcon')).toHaveLength(2);
        });

        test('has optional label indicator', () => {
            const r = renderComponent({ isOptional: true });

            expect(r.getByText('(Optional)')).toBeVisible();
        });
    });

    test('has note', () => {
        const noteText = 'This is a note';
        const r = renderComponent({ note: noteText });

        const noteEl = r.getByText(noteText);
        expect(noteEl).toHaveClass('FormField-note');
    });

    test('has loading message', () => {
        const r = renderComponent({ message: { type: 'loading', text: 'Loading...' } });

        const msgBlock = r.getByTestId('FormField-message');

        expect(msgBlock).toHaveClass('loading');
        expect(r.getByTestId('LoadingSpinner')).toBeVisible();
        expect(r.getByText('Loading...')).toBeVisible();
    });

    test('has warning message', () => {
        const r = renderComponent({
            message: { type: 'warning', text: 'This is a warning' },
        });

        const msgBlock = r.getByTestId('FormField-message');

        expect(msgBlock).toHaveClass('warning');
        expect(r.getByTestId('WarningGlyphIcon')).toBeVisible();
        expect(screen.getByText('This is a warning')).toBeVisible();
    });

    test('has error message', () => {
        const r = renderComponent({ message: { type: 'error', text: 'This is an error' } });
        expect(r.container.firstChild).toHaveClass('with-error');

        const msgBlock = r.getByTestId('FormField-message');

        expect(msgBlock).toHaveClass('error');
        expect(r.queryAllByTestId('GlyphIcon')).toHaveLength(0); // no icon for error
        expect(screen.getByText('This is an error')).toBeVisible();
    });

    test('children is wrapped', () => {
        const child = <span>Hello</span>;
        const r = renderComponent({ children: child });

        const cBlock = r.getByTestId('FormField-control');
        expect(cBlock.firstChild).toHaveTextContent('Hello');
    });
});
