import * as React from 'react'; import { customRender, fireEvent } from 'test-utils'; import { TableActions } from '../index'; const MyFilterTabs = () => { const { applyFilters } = React.useContext(TableActions.Context); return (
); }; describe('TableActions', () => { describe('TableActions action bar', () => { it('should render the two slots correctly', () => { const { getByText } = customRender( renderDropdown}>
renderSearch
} rightHandActions={
renderPager
} />
, ); getByText('renderSearch'); getByText('renderPager'); // Our dropdown slot will be within a popper element // So we'll need to click on the dropdown button to view our render slot fireEvent.click(getByText('Dropdown Text')); getByText('renderDropdown'); }); }); describe('TableActions.Dropdown', () => { it('should render a list view of DropdownSection titles, but not its children', () => { const notVisibleText1 = 'Technically, this text should not be visible'; const notVisibleText2 = 'This text should not be visible either!'; const { queryByText, getByText, getByTestId } = customRender( Title of our Dropdown {notVisibleText1} {notVisibleText2} } >
renderSearch
} rightHandActions={
renderPager
} />
, ); // Open our dropdown... fireEvent.click(getByText('Dropdown Text')); // We should see the following getByText('Title of our Dropdown'); getByText('Card Type'); getByText('Animal Filter'); // Might as well test out testIds getByTestId('test-id-card-type'); getByTestId('test-id-animal-filter'); // Children of DropdownSection shouldn't be visible. // Instead, they will appear in their own details view expect(queryByText(notVisibleText1)).toBeNull(); expect(queryByText(notVisibleText2)).toBeNull(); }); it('should render a details view when we click on a DropdownSection', () => { const sectionText = 'I will only be visible once you clicked on the dropdown section'; const notVisibleText = 'I should not be rendered!'; const title = 'Title of our Dropdown'; const { queryByText, getByText } = customRender( {title} {sectionText} {notVisibleText} } >
renderSearch
} rightHandActions={
renderPager
} />
, ); // Open our dropdown... fireEvent.click(getByText('Dropdown Text')); // Let's click on the Card Type section fireEvent.click(getByText('Card Type')); // We should see the Card Type section children being rendered... expect(queryByText(sectionText)).toBeTruthy(); // And everything else hidden! expect(queryByText(notVisibleText)).toBeNull(); expect(queryByText(title)).toBeNull(); }); it('should disable the dropdown button', () => { const title = 'Title of our Dropdown'; const { getByText, queryByText } = customRender( {title} card types animals } >
renderSearch
} rightHandActions={
renderPager
} />
, ); // Try to click on our disabled button... fireEvent.click(getByText('Dropdown Text')); // Which should not even open our dropdown expect(queryByText('Title of our Dropdown')).toBeNull(); }); it('should render our custom checkbox group and apply filters', () => { const notVisibleText = 'I should not be rendered!'; const { queryByText, getByText, getByDisplayValue, getByTestId } = customRender( ( {notVisibleText}
My animal filter
{({ applyFilter }) => ( )}
)} > } rightHandActions={
renderPager
} />
, ); // No filters applied, means no tag rendered... expect(queryByText('Animals selected')).toBeNull(); // Open our dropdown... fireEvent.click(getByText('Dropdown Text')); // Let's click on the Animal Filter section fireEvent.click(getByText('Animal Filter')); const lionCheckbox = getByDisplayValue('lion') as HTMLInputElement; const tigerCheckbox = getByDisplayValue('tiger') as HTMLInputElement; const bearCheckbox = getByDisplayValue('bear') as HTMLInputElement; // By default, all checkboxes are off expect(lionCheckbox.checked).toBeFalsy(); expect(tigerCheckbox.checked).toBeFalsy(); expect(bearCheckbox.checked).toBeFalsy(); // Let's click some checkboxes... fireEvent.click(lionCheckbox); fireEvent.click(bearCheckbox); expect(lionCheckbox.checked).toBeTruthy(); expect(tigerCheckbox.checked).toBeFalsy(); expect(bearCheckbox.checked).toBeTruthy(); // We're ready! Apply our filter and then... fireEvent.click(getByText('Apply Filter')); // And since we hooked the closeDropdown function in our callback // the dropdown should not be available... expect(queryByText('Apply Filter')).toBeFalsy(); // We should now have a tag with our filter and // our tag should've been mapped to our checkbox group view fireEvent.click(getByText('Animals selected lion, bear')); // We should see our children getting rendered... expect(queryByText('My animal filter')).toBeTruthy(); // Checkboxes should match previous state expect((getByDisplayValue('lion') as HTMLInputElement).checked).toBeTruthy(); expect((getByDisplayValue('tiger') as HTMLInputElement).checked).toBeFalsy(); expect((getByDisplayValue('bear') as HTMLInputElement).checked).toBeTruthy(); // Let's deactivate the lion checkbox fireEvent.click(getByDisplayValue('lion')); fireEvent.click(getByText('Apply Filter')); // And now our Tag should've been updated with our new Text... getByText('Animals selected bear'); // Let's finish up this long long test by killing the filter... // TODO: We'll need to refactor ``'s data-testId cause this is super brittle! fireEvent.click(getByTestId('tag-remove-button')); expect(queryByText('Animals selected bear')).toBeFalsy(); // Sanity check our checkboxes as they should be all set to falsy fireEvent.click(getByText('Dropdown Text')); fireEvent.click(getByText('Animal Filter')); expect((getByDisplayValue('lion') as HTMLInputElement).checked).toBeFalsy(); expect((getByDisplayValue('tiger') as HTMLInputElement).checked).toBeFalsy(); expect((getByDisplayValue('bear') as HTMLInputElement).checked).toBeFalsy(); }); it('should apply multiple filters', () => { const notVisibleText = 'I should not be rendered!'; const { queryByText, getByText, getByDisplayValue } = customRender( ( {notVisibleText}
My animal filter
{({ applyFilter }) => ( )}
)} > } rightHandActions={
renderPager
} />
, ); fireEvent.click(getByText('Loads of animals')); expect(queryByText('Animals selected: bear, tiger')).toBeTruthy(); fireEvent.click(getByText('Dropdown Text')); // Let's click on the Animal Filter section fireEvent.click(getByText('Animal Filter')); const lionRadio = getByDisplayValue('lion') as HTMLInputElement; const tigerRadio = getByDisplayValue('tiger') as HTMLInputElement; const bearRadio = getByDisplayValue('bear') as HTMLInputElement; expect(lionRadio.checked).toBeFalsy(); expect(tigerRadio.checked).toBeTruthy(); expect(bearRadio.checked).toBeTruthy(); }); it('should render our custom radio group and apply filters', () => { const notVisibleText = 'I should not be rendered!'; const { getByText, getByDisplayValue, queryByText } = customRender( ( {notVisibleText}
My animal filter
{({ applyFilter, undoChanges }) => ( )}
)} > } rightHandActions={
renderPager
} />
, ); // Open our dropdown... fireEvent.click(getByText('Dropdown Text')); // Let's click on the Animal Filter section fireEvent.click(getByText('Animal Filter')); const lionRadio = getByDisplayValue('lion') as HTMLInputElement; const tigerRadio = getByDisplayValue('tiger') as HTMLInputElement; const bearRadio = getByDisplayValue('bear') as HTMLInputElement; fireEvent.click(lionRadio); expect(lionRadio.checked).toBeTruthy(); expect(tigerRadio.checked).toBeFalsy(); expect(bearRadio.checked).toBeFalsy(); fireEvent.click(bearRadio); // Bear should be the only one selected now since it's a radio input expect(lionRadio.checked).toBeFalsy(); expect(tigerRadio.checked).toBeFalsy(); expect(bearRadio.checked).toBeTruthy(); fireEvent.click(getByText('Apply Filter')); expect(queryByText('Animal selected: bear')).toBeTruthy(); fireEvent.click(getByText('Dropdown Text')); fireEvent.click(getByText('Animal Filter')); // Bear should still be selected expect(lionRadio.checked).toBeFalsy(); expect(tigerRadio.checked).toBeFalsy(); expect(bearRadio.checked).toBeTruthy(); fireEvent.click(getByText('Clear')); fireEvent.click(getByText('Apply Filter')); expect(queryByText('Animal selected: bear')).toBeFalsy(); }); }); describe('TableActions.Search', () => { it('should disable the input and the button', () => { const spy = jest.fn(); const placeholder = 'Search for product name'; const { getByTitle, getByPlaceholderText } = customRender( renderDropdown} onFilterChange={(filters, searchTerm) => { spy(filters, searchTerm); }} > } rightHandActions={
renderPager
} />
, ); const placeholderElement = getByPlaceholderText(placeholder) as HTMLInputElement; const searchElement = getByTitle('Search') as HTMLInputElement; expect(placeholderElement.disabled).toBeTruthy(); expect(searchElement.disabled).toBeTruthy(); }); it('should trigger a search when clicking', () => { const spy = jest.fn(); const placeholder = 'Search for product name'; const { getByTitle, getByPlaceholderText } = customRender( renderDropdown} onFilterChange={(filters, searchTerm) => { spy(filters, searchTerm); }} > } rightHandActions={
renderPager
} />
, ); fireEvent.change(getByPlaceholderText(placeholder), { target: { value: 'search string' } }); fireEvent.click(getByTitle('Search')); expect(spy).toHaveBeenCalledWith([], 'search string'); }); }); describe('TableActions.Container initial states', () => { it('should set the initial search term', () => { const mySearchTerm = 'cats and dogs and of course giraffes!'; const placeholder = 'Search for cute animals'; const { getByPlaceholderText } = customRender( renderDropdown} initialSearchTerm={mySearchTerm} > } rightHandActions={
renderPager
} />
, ); const searchElement = getByPlaceholderText(placeholder) as HTMLInputElement; expect(searchElement.value).toEqual(mySearchTerm); }); it('should set the initial filters', () => { const initialFilters = [ { key: 'animalFilter', label: 'Animals selected Lion, Bear', values: ['lion', 'bear'] }, ]; const { getByText, getByDisplayValue } = customRender( ( {({ applyFilter }) => ( )} )} > } rightHandActions={
renderPager
} />
, ); // There should be a tag with this string... getByText('Animals selected Lion, Bear'); // Let's check to see if our checkboxes have updated shall we? fireEvent.click(getByText('Dropdown Text')); fireEvent.click(getByText('Animal Filter')); // Based on the initial filters, we should've received lion and bear as checked const lionCheckbox = getByDisplayValue('lion') as HTMLInputElement; const tigerCheckbox = getByDisplayValue('tiger') as HTMLInputElement; const bearCheckbox = getByDisplayValue('bear') as HTMLInputElement; expect(lionCheckbox.checked).toBeTruthy(); expect(tigerCheckbox.checked).toBeFalsy(); expect(bearCheckbox.checked).toBeTruthy(); }); }); });