From ebd09883fea7900648807c9099a124218a1bebc2 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Tue, 11 Dec 2018 12:58:08 -0500 Subject: [PATCH 1/4] update DataListToolbar component and tests --- __tests__/components/DataListToolbar.test.jsx | 126 +++++++++++++++++- .../DataListToolbar/DataListToolbar.jsx | 3 +- 2 files changed, 127 insertions(+), 2 deletions(-) diff --git a/__tests__/components/DataListToolbar.test.jsx b/__tests__/components/DataListToolbar.test.jsx index c1c3a4e3af..e4e5591e60 100644 --- a/__tests__/components/DataListToolbar.test.jsx +++ b/__tests__/components/DataListToolbar.test.jsx @@ -4,7 +4,6 @@ import { I18nProvider } from '@lingui/react'; import DataListToolbar from '../../src/components/DataListToolbar'; describe('', () => { - const columns = [{ name: 'Name', key: 'name', isSortable: true }]; let toolbar; afterEach(() => { @@ -15,6 +14,8 @@ describe('', () => { }); test('it triggers the expected callbacks', () => { + const columns = [{ name: 'Name', key: 'name', isSortable: true }]; + const search = 'button[aria-label="Search"]'; const searchTextInput = 'input[aria-label="Search text input"]'; const selectAll = 'input[aria-label="Select all"]'; @@ -55,4 +56,127 @@ describe('', () => { expect(onSearch).toHaveBeenCalledTimes(1); expect(onSearch).toBeCalledWith('test-321'); }); + + test('dropdown items sortable columns work', () => { + const multipleColumns = [ + { name: 'Foo', key: 'foo', isSortable: true }, + { name: 'Bar', key: 'bar', isSortable: true }, + { name: 'Bakery', key: 'bakery', isSortable: true }, + { name: 'Baz', key: 'baz' } + ]; + + const onSearch = jest.fn(); + const onSort = jest.fn(); + const onSelectAll = jest.fn(); + toolbar = mount( + + ); + const sortdropdownToggle = toolbar.find('.pf-l-toolbar__group.sortDropdownGroup .pf-l-toolbar__item button'); + expect(sortdropdownToggle.length).toBe(2); + sortdropdownToggle.at(1).simulate('click'); + sortdropdownToggle.at(0).simulate('click'); + toolbar.update(); + const sortDropdownItems = toolbar.find('.pf-l-toolbar__group.sortDropdownGroup button.pf-c-dropdown__menu-item'); + expect(sortDropdownItems.length).toBe(2); + const mockedSortEvent = { target: { innerText: 'Bar' } }; + sortDropdownItems.at(0).simulate('click', mockedSortEvent); + toolbar = mount( + + ); + toolbar.update(); + const sortdropdownToggleDescending = toolbar.find('.pf-l-toolbar__group.sortDropdownGroup .pf-l-toolbar__item button'); + expect(sortdropdownToggleDescending.length).toBe(2); + sortdropdownToggleDescending.at(1).simulate('click'); + sortdropdownToggleDescending.at(0).simulate('click'); + toolbar.update(); + const sortDropdownItemsDescending = toolbar.find('.pf-l-toolbar__group.sortDropdownGroup button.pf-c-dropdown__menu-item'); + expect(sortDropdownItemsDescending.length).toBe(2); + const mockedSortEventDescending = { target: { innerText: 'Bar' } }; + sortDropdownItems.at(0).simulate('click', mockedSortEventDescending); + toolbar.update(); + const searchDropdownToggle = toolbar.find('.pf-c-dropdown.searchKeyDropdown button.pf-c-dropdown__toggle'); + expect(searchDropdownToggle.length).toBe(1); + searchDropdownToggle.at(0).simulate('click'); + toolbar.update(); + const searchDropdownItems = toolbar.find('.pf-c-dropdown.searchKeyDropdown button.pf-c-dropdown__menu-item'); + expect(searchDropdownItems.length).toBe(3); + const mockedSearchEvent = { target: { innerText: 'Bar' } }; + searchDropdownItems.at(0).simulate('click', mockedSearchEvent); + }); + + test('it displays correct sort icon', () => { + const numericColumns = [{ name: 'ID', key: 'id', isSortable: true, isNumeric: true }]; + const alphaColumns = [{ name: 'Name', key: 'name', isSortable: true, isNumeric: false }]; + const onSearch = jest.fn(); + const onSort = jest.fn(); + const onSelectAll = jest.fn(); + toolbar = mount( + + ); + const downNumericIcon = toolbar.find('SortNumericDownIcon'); + expect(downNumericIcon.length).toBe(1); + toolbar = mount( + + ); + const upNumericIcon = toolbar.find('SortNumericUpIcon'); + expect(upNumericIcon.length).toBe(1); + toolbar = mount( + + ); + const downAlphaIcon = toolbar.find('SortAlphaDownIcon'); + expect(downAlphaIcon.length).toBe(1); + toolbar = mount( + + ); + const upAlphaIcon = toolbar.find('SortAlphaUpIcon'); + expect(upAlphaIcon.length).toBe(1); + }); }); diff --git a/src/components/DataListToolbar/DataListToolbar.jsx b/src/components/DataListToolbar/DataListToolbar.jsx index e1d2ea6842..51bf9f782c 100644 --- a/src/components/DataListToolbar/DataListToolbar.jsx +++ b/src/components/DataListToolbar/DataListToolbar.jsx @@ -152,6 +152,7 @@ class DataListToolbar extends React.Component {
- + Date: Tue, 11 Dec 2018 16:53:17 -0500 Subject: [PATCH 2/4] update app and towerlogo tests and remove stale code --- __tests__/App.test.jsx | 29 +++++++------------------ __tests__/components/TowerLogo.test.jsx | 14 ------------ src/App.jsx | 7 +----- src/components/TowerLogo/TowerLogo.jsx | 7 +----- 4 files changed, 10 insertions(+), 47 deletions(-) diff --git a/__tests__/App.test.jsx b/__tests__/App.test.jsx index 7b98adafff..cbffd97f86 100644 --- a/__tests__/App.test.jsx +++ b/__tests__/App.test.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { HashRouter as Router } from 'react-router-dom'; +import { MemoryRouter } from 'react-router-dom'; import { shallow, mount } from 'enzyme'; import App from '../src/App'; import api from '../src/api'; @@ -7,10 +7,6 @@ import { API_LOGOUT } from '../src/endpoints'; import Dashboard from '../src/pages/Dashboard'; import Login from '../src/pages/Login'; -import { asyncFlush } from '../jest.setup'; - -const DEFAULT_ACTIVE_GROUP = 'views_group'; -const DEFAULT_ACTIVE_ITEM = 'views_group_dashboard'; describe('', () => { test('renders without crashing', () => { @@ -22,7 +18,7 @@ describe('', () => { api.isAuthenticated = jest.fn(); api.isAuthenticated.mockReturnValue(false); - const appWrapper = mount(); + const appWrapper = mount(); const login = appWrapper.find(Login); expect(login.length).toBe(1); @@ -34,7 +30,7 @@ describe('', () => { api.isAuthenticated = jest.fn(); api.isAuthenticated.mockReturnValue(true); - const appWrapper = mount(); + const appWrapper = mount(); const dashboard = appWrapper.find(Dashboard); expect(dashboard.length).toBe(1); @@ -49,24 +45,15 @@ describe('', () => { expect(appWrapper.state().isNavOpen).toBe(false); }); - test('onLogoClick sets selected nav back to defaults', () => { - const appWrapper = shallow(); - appWrapper.setState({ activeGroup: 'foo', activeItem: 'bar' }); - expect(appWrapper.state().activeItem).toBe('bar'); - expect(appWrapper.state().activeGroup).toBe('foo'); - appWrapper.instance().onLogoClick(); - expect(appWrapper.state().activeGroup).toBe(DEFAULT_ACTIVE_GROUP); - }); - test('api.logout called from logout button', async () => { + const logOutButtonSelector = 'button[aria-label="Logout"]'; api.get = jest.fn().mockImplementation(() => Promise.resolve({})); - const appWrapper = shallow(); - appWrapper.instance().onDevLogout(); + const appWrapper = mount(); + const logOutButton = appWrapper.find(logOutButtonSelector); + expect(logOutButton.length).toBe(1); + logOutButton.simulate('click'); appWrapper.setState({ activeGroup: 'foo', activeItem: 'bar' }); expect(api.get).toHaveBeenCalledTimes(1); expect(api.get).toHaveBeenCalledWith(API_LOGOUT); - await asyncFlush(); - expect(appWrapper.state().activeItem).toBe(DEFAULT_ACTIVE_ITEM); - expect(appWrapper.state().activeGroup).toBe(DEFAULT_ACTIVE_GROUP); }); }); diff --git a/__tests__/components/TowerLogo.test.jsx b/__tests__/components/TowerLogo.test.jsx index 3bd40afaee..10e3461443 100644 --- a/__tests__/components/TowerLogo.test.jsx +++ b/__tests__/components/TowerLogo.test.jsx @@ -43,20 +43,6 @@ describe('', () => { expect(towerLogoElem.props().history.length).toBe(2); }); - test('gracefully handles not being passed click handler', () => { - logoWrapper = mount( - - - - - - ); - findChildren(); - expect(towerLogoElem.props().history.length).toBe(1); - logoWrapper.simulate('click'); - expect(towerLogoElem.props().history.length).toBe(1); - }); - test('handles mouse over and out state.hover changes', () => { const onLogoClick = jest.fn(); logoWrapper = mount( diff --git a/src/App.jsx b/src/App.jsx index 38465599d8..3b03de3382 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -81,13 +81,8 @@ class App extends React.Component { this.setState(({ isNavOpen }) => ({ isNavOpen: !isNavOpen })); }; - onLogoClick = () => { - this.setState({ activeGroup: 'views_group' }); - } - onDevLogout = async () => { await api.get(API_LOGOUT); - this.setState({ activeGroup: 'views_group', activeItem: 'views_group_dashboard' }); } render () { @@ -134,7 +129,7 @@ class App extends React.Component { } + logo={} toolbar={PageToolbar} showNavToggle onNavToggle={this.onNavToggle} diff --git a/src/components/TowerLogo/TowerLogo.jsx b/src/components/TowerLogo/TowerLogo.jsx index 082777ba7e..6b9d0e3a30 100644 --- a/src/components/TowerLogo/TowerLogo.jsx +++ b/src/components/TowerLogo/TowerLogo.jsx @@ -15,13 +15,8 @@ class TowerLogo extends Component { } onClick = () => { - const { history, onClick: handleClick } = this.props; - - if (!handleClick) return; - + const { history } = this.props; history.push('/'); - - handleClick(); }; onHover = () => { From e48c734925ed414aa2411d94d18e0544c0412056 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Tue, 11 Dec 2018 16:53:33 -0500 Subject: [PATCH 3/4] update datelisttoolbar test --- __tests__/components/DataListToolbar.test.jsx | 179 +++++++++++------- 1 file changed, 109 insertions(+), 70 deletions(-) diff --git a/__tests__/components/DataListToolbar.test.jsx b/__tests__/components/DataListToolbar.test.jsx index e4e5591e60..1c1a3d8b04 100644 --- a/__tests__/components/DataListToolbar.test.jsx +++ b/__tests__/components/DataListToolbar.test.jsx @@ -58,6 +58,11 @@ describe('', () => { }); test('dropdown items sortable columns work', () => { + const sortDropdownToggleSelector = '.pf-l-toolbar__group.sortDropdownGroup .pf-l-toolbar__item button'; + const sortDropdownItemsSelector = '.pf-l-toolbar__group.sortDropdownGroup button.pf-c-dropdown__menu-item'; + const searchDropdownToggleSelector = '.pf-c-dropdown.searchKeyDropdown .pf-c-dropdown__toggle'; + const searchDropdownItemsSelector = '.pf-c-dropdown.searchKeyDropdown button.pf-c-dropdown__menu-item'; + const multipleColumns = [ { name: 'Foo', key: 'foo', isSortable: true }, { name: 'Bar', key: 'bar', isSortable: true }, @@ -68,115 +73,149 @@ describe('', () => { const onSearch = jest.fn(); const onSort = jest.fn(); const onSelectAll = jest.fn(); + toolbar = mount( - + + + ); - const sortdropdownToggle = toolbar.find('.pf-l-toolbar__group.sortDropdownGroup .pf-l-toolbar__item button'); - expect(sortdropdownToggle.length).toBe(2); - sortdropdownToggle.at(1).simulate('click'); - sortdropdownToggle.at(0).simulate('click'); + const sortDropdownToggle = toolbar.find(sortDropdownToggleSelector); + expect(sortDropdownToggle.length).toBe(2); + sortDropdownToggle.at(1).simulate('click'); + sortDropdownToggle.at(0).simulate('click'); toolbar.update(); - const sortDropdownItems = toolbar.find('.pf-l-toolbar__group.sortDropdownGroup button.pf-c-dropdown__menu-item'); + + const sortDropdownItems = toolbar.find(sortDropdownItemsSelector); expect(sortDropdownItems.length).toBe(2); + const mockedSortEvent = { target: { innerText: 'Bar' } }; sortDropdownItems.at(0).simulate('click', mockedSortEvent); toolbar = mount( - + + + ); toolbar.update(); - const sortdropdownToggleDescending = toolbar.find('.pf-l-toolbar__group.sortDropdownGroup .pf-l-toolbar__item button'); - expect(sortdropdownToggleDescending.length).toBe(2); - sortdropdownToggleDescending.at(1).simulate('click'); - sortdropdownToggleDescending.at(0).simulate('click'); + + const sortDropdownToggleDescending = toolbar.find(sortDropdownToggleSelector); + expect(sortDropdownToggleDescending.length).toBe(2); + sortDropdownToggleDescending.at(1).simulate('click'); + sortDropdownToggleDescending.at(0).simulate('click'); toolbar.update(); - const sortDropdownItemsDescending = toolbar.find('.pf-l-toolbar__group.sortDropdownGroup button.pf-c-dropdown__menu-item'); + + const sortDropdownItemsDescending = toolbar.find(sortDropdownItemsSelector); expect(sortDropdownItemsDescending.length).toBe(2); + const mockedSortEventDescending = { target: { innerText: 'Bar' } }; sortDropdownItems.at(0).simulate('click', mockedSortEventDescending); toolbar.update(); - const searchDropdownToggle = toolbar.find('.pf-c-dropdown.searchKeyDropdown button.pf-c-dropdown__toggle'); + + const searchDropdownToggle = toolbar.find(searchDropdownToggleSelector); expect(searchDropdownToggle.length).toBe(1); searchDropdownToggle.at(0).simulate('click'); toolbar.update(); - const searchDropdownItems = toolbar.find('.pf-c-dropdown.searchKeyDropdown button.pf-c-dropdown__menu-item'); + + const searchDropdownItems = toolbar.find(searchDropdownItemsSelector); expect(searchDropdownItems.length).toBe(3); + const mockedSearchEvent = { target: { innerText: 'Bar' } }; searchDropdownItems.at(0).simulate('click', mockedSearchEvent); }); test('it displays correct sort icon', () => { + const downNumericIconSelector = 'SortNumericDownIcon'; + const upNumericIconSelector = 'SortNumericUpIcon'; + const downAlphaIconSelector = 'SortAlphaDownIcon'; + const upAlphaIconSelector = 'SortAlphaUpIcon'; + const numericColumns = [{ name: 'ID', key: 'id', isSortable: true, isNumeric: true }]; const alphaColumns = [{ name: 'Name', key: 'name', isSortable: true, isNumeric: false }]; const onSearch = jest.fn(); const onSort = jest.fn(); const onSelectAll = jest.fn(); + toolbar = mount( - + + + ); - const downNumericIcon = toolbar.find('SortNumericDownIcon'); + + const downNumericIcon = toolbar.find(downNumericIconSelector); expect(downNumericIcon.length).toBe(1); + toolbar = mount( - + + + ); - const upNumericIcon = toolbar.find('SortNumericUpIcon'); + + const upNumericIcon = toolbar.find(upNumericIconSelector); expect(upNumericIcon.length).toBe(1); + toolbar = mount( - + + + ); - const downAlphaIcon = toolbar.find('SortAlphaDownIcon'); + + const downAlphaIcon = toolbar.find(downAlphaIconSelector); expect(downAlphaIcon.length).toBe(1); + toolbar = mount( - + + + ); - const upAlphaIcon = toolbar.find('SortAlphaUpIcon'); + + const upAlphaIcon = toolbar.find(upAlphaIconSelector); expect(upAlphaIcon.length).toBe(1); }); }); From 11583dbff0170c0aacfd78c791920a4f9c34a148 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Tue, 11 Dec 2018 16:53:44 -0500 Subject: [PATCH 4/4] update pagination tests --- __tests__/components/Pagination.test.jsx | 93 ++++++++++++++++++++++++ src/components/Pagination/Pagination.jsx | 23 +++--- 2 files changed, 102 insertions(+), 14 deletions(-) diff --git a/__tests__/components/Pagination.test.jsx b/__tests__/components/Pagination.test.jsx index 93dbead8ec..6360098c7a 100644 --- a/__tests__/components/Pagination.test.jsx +++ b/__tests__/components/Pagination.test.jsx @@ -72,4 +72,97 @@ describe('', () => { expect(onSetPage).toHaveBeenCalledTimes(2); expect(onSetPage).toBeCalledWith(1, 5); }); + + test('previous button does not work on page 1', () => { + const previous = 'button[aria-label="First"]'; + const onSetPage = jest.fn(); + + pagination = mount( + + + + ); + pagination.find(previous).simulate('click'); + expect(onSetPage).toHaveBeenCalledTimes(0); + }); + + test('changing pageSize works', () => { + const pageSizeDropdownToggleSelector = 'DropdownToggle DropdownToggle[className="togglePageSize"]'; + const pageSizeDropdownItemsSelector = 'DropdownItem'; + const onSetPage = jest.fn(); + + pagination = mount( + + + + ); + const pageSizeDropdownToggle = pagination.find(pageSizeDropdownToggleSelector); + expect(pageSizeDropdownToggle.length).toBe(1); + pageSizeDropdownToggle.at(0).simulate('click'); + + const pageSizeDropdownItems = pagination.find(pageSizeDropdownItemsSelector); + expect(pageSizeDropdownItems.length).toBe(3); + pageSizeDropdownItems.at(1).simulate('click'); + }); + + test('submit a new page by typing in input works', () => { + const textInputSelector = '.pf-l-split__item.pf-m-main .pf-c-form-control'; + const submitFormSelector = '.pf-l-split__item.pf-m-main form'; + + const onSetPage = jest.fn(); + + pagination = mount( + + + + ); + const textInput = pagination.find(textInputSelector); + expect(textInput.length).toBe(1); + textInput.simulate('change'); + pagination.setProps({ page: 2 }); + + const submitForm = pagination.find(submitFormSelector); + expect(submitForm.length).toBe(1); + submitForm.simulate('submit'); + pagination.setState({ value: 'invalid' }); + submitForm.simulate('submit'); + }); + + test('text input page change is disabled when only 1 page', () => { + const onSetPage = jest.fn(); + + pagination = mount( + + + + ); + }); }); diff --git a/src/components/Pagination/Pagination.jsx b/src/components/Pagination/Pagination.jsx index d48f69e72c..001f02f504 100644 --- a/src/components/Pagination/Pagination.jsx +++ b/src/components/Pagination/Pagination.jsx @@ -7,14 +7,9 @@ import { DropdownDirection, DropdownItem, DropdownToggle, - Form, - FormGroup, Level, LevelItem, TextInput, - Toolbar, - ToolbarGroup, - ToolbarItem, Split, SplitItem, } from '@patternfly/react-core'; @@ -32,7 +27,7 @@ class Pagination extends Component { const { page } = this.props; if (prevProps.page !== page) { - this.setState({ value: page }); + this.onPageChange(page); } } @@ -51,13 +46,13 @@ class Pagination extends Component { if (isValid) { onSetPage(value, page_size); - } else{ + } else { this.setState({ value: page }); } }; onFirst = () => { - const { onSetPage, page_size} = this.props; + const { onSetPage, page_size } = this.props; onSetPage(1, page_size); }; @@ -67,7 +62,7 @@ class Pagination extends Component { const previousPage = page - 1; if (previousPage >= 1) { - onSetPage(previousPage, page_size) + onSetPage(previousPage, page_size); } }; @@ -76,7 +71,7 @@ class Pagination extends Component { const nextPage = page + 1; if (nextPage <= pageCount) { - onSetPage(nextPage, page_size) + onSetPage(nextPage, page_size); } }; @@ -139,18 +134,18 @@ class Pagination extends Component { direction={up} isOpen={isOpen} toggle={( - + { page_size } - )}> + )} + > {opts.map(option => ( { option } ))} - Per Page + Per Page