import React from 'react';
import { renderAsyncTest } from '@lg-tools/test-harnesses';
import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { State, TextArea } from '../TextArea';
import { getTestUtils } from './getTestUtils';
const error = 'This is the error message';
const defaultProps = {
label: 'Test Input Label',
description: 'This is the description',
placeholder: 'This is some placeholder text',
};
const renderTextAreaAsync = () =>
renderAsyncTest(, render);
function renderTextArea(props = {}) {
const renderUtils = render(
,
);
return { ...renderUtils };
}
function renderMultipleInputs() {
render(
<>
>,
);
}
describe('packages/text-area', () => {
describe('getTestUtils', () => {
test('throws error if LG TextArea is not found', () => {
render();
try {
const _utils = getTestUtils();
} catch (error) {
expect(error).toBeInstanceOf(Error);
expect(error).toHaveProperty(
'message',
expect.stringMatching(
/Unable to find an element by: \[data-lgid="lg-text_area"\]/,
),
);
}
});
describe('single input', () => {
describe('getInput', () => {
test('is in the document', () => {
renderTextArea();
const { getInput } = getTestUtils();
expect(getInput()).toBeInTheDocument();
});
});
describe('getLabel', () => {
test('is in the document', () => {
renderTextArea();
const { getLabel } = getTestUtils();
expect(getLabel()).toBeInTheDocument();
});
test('is not in the document', () => {
renderTextArea({ label: '' });
const { getLabel } = getTestUtils();
expect(getLabel()).not.toBeInTheDocument();
});
});
describe('getDescription', () => {
test('is in the document', () => {
renderTextArea();
const { getDescription } = getTestUtils();
expect(getDescription()).toBeInTheDocument();
});
test('is not in the document', () => {
renderTextArea({ description: '' });
const { getDescription } = getTestUtils();
expect(getDescription()).not.toBeInTheDocument();
});
});
describe('getErrorMessage', () => {
test('is in the document', () => {
renderTextArea({ state: State.Error, errorMessage: error });
const { getErrorMessage } = getTestUtils();
expect(getErrorMessage()).toBeInTheDocument();
expect(getErrorMessage()).toHaveTextContent(error);
});
test('is not in the document', () => {
renderTextArea({ errorMessage: 'hey' });
const { getErrorMessage } = getTestUtils();
expect(getErrorMessage()).not.toBeInTheDocument();
});
});
describe('getInputValue', () => {
test('returns value when uncontrolled', () => {
renderTextArea();
const { getInput, getInputValue } = getTestUtils();
userEvent.type(getInput(), '123');
expect(getInputValue()).toBe('123');
});
test('returns value when controlled', () => {
renderTextArea({ value: '456' });
const { getInputValue } = getTestUtils();
expect(getInputValue()).toBe('456');
});
});
describe('isDisabled', () => {
test('is true', () => {
renderTextArea({ disabled: true });
const { isDisabled } = getTestUtils();
expect(isDisabled()).toBe(true);
});
test('is false', () => {
renderTextArea();
const { isDisabled } = getTestUtils();
expect(isDisabled()).toBe(false);
});
});
describe('isError', () => {
test('is true', () => {
renderTextArea({ state: State.Error });
const { isError } = getTestUtils();
expect(isError()).toBe(true);
});
test('is false', () => {
renderTextArea();
const { isError } = getTestUtils();
expect(isError()).toBe(false);
});
});
});
describe('multiple inputs', () => {
test('getInput', () => {
renderMultipleInputs();
const utilsOne = getTestUtils('lg-text_area-1');
const utilsTwo = getTestUtils('lg-text_area-2');
expect(utilsOne.getInput()).toBeInTheDocument();
expect(utilsTwo.getInput()).toBeInTheDocument();
});
test('getInputValue', () => {
renderMultipleInputs();
const utilsOne = getTestUtils('lg-text_area-1');
const utilsTwo = getTestUtils('lg-text_area-2');
expect(utilsOne.getInputValue()).toBe('text input 1');
expect(utilsTwo.getInputValue()).toBe('text input 2');
});
});
describe('Async component', () => {
test('find LG TextArea after awaiting an async component', async () => {
const { openButton, findByTestId, asyncTestComponentId } =
renderTextAreaAsync();
userEvent.click(openButton);
const asyncComponent = await findByTestId(asyncTestComponentId);
expect(asyncComponent).toBeInTheDocument();
// After awaiting asyncComponent, look for text area
const { getInput } = getTestUtils();
expect(getInput()).toBeInTheDocument();
});
test('find LG TextArea awaiting getTestUtils', async () => {
const { openButton } = renderTextAreaAsync();
userEvent.click(openButton);
// awaiting getTestUtils
await waitFor(() => {
const { getInput } = getTestUtils();
expect(getInput()).toBeInTheDocument();
});
});
test('Updates the value inside an async component', async () => {
const { openButton, findByTestId, asyncTestComponentId } =
renderTextAreaAsync();
userEvent.click(openButton);
const asyncComponent = await findByTestId(asyncTestComponentId);
expect(asyncComponent).toBeInTheDocument();
// After awaiting asyncComponent, look for text area
const { getInput, getInputValue } = getTestUtils();
const input = getInput();
userEvent.type(input, 'whats blue and not heavy? light blue');
expect(getInputValue()).toBe('whats blue and not heavy? light blue');
});
});
});
});