From c294a63f321128b36bf3ee3e1df8457b328d4c11 Mon Sep 17 00:00:00 2001 From: mabashian Date: Fri, 8 Nov 2019 11:56:01 -0500 Subject: [PATCH] Updates a couple of team list checkbox tests to test the UI rather than state/props internals. Fixes bug where select all was selected on load. --- .../DataListCheck/DataListCheck.jsx | 1 + awx/ui_next/src/screens/Host/Host.test.jsx | 5 +- .../src/screens/Host/HostList/HostList.jsx | 2 +- .../src/screens/Inventory/Inventory.test.jsx | 5 +- .../Inventory/InventoryList/InventoryList.jsx | 2 +- .../screens/Inventory/SmartInventory.test.jsx | 5 +- .../Organization/Organization.test.jsx | 5 +- .../src/screens/Project/Project.test.jsx | 5 +- .../Project/ProjectList/ProjectList.jsx | 2 +- awx/ui_next/src/screens/Team/Team.jsx | 14 ++--- awx/ui_next/src/screens/Team/Team.test.jsx | 5 +- .../src/screens/Team/TeamList/TeamList.jsx | 2 +- .../screens/Team/TeamList/TeamList.test.jsx | 58 +++++++++++-------- .../screens/Team/TeamList/TeamListItem.jsx | 1 - .../src/screens/Template/Template.test.jsx | 3 +- 15 files changed, 58 insertions(+), 57 deletions(-) diff --git a/awx/ui_next/src/components/DataListCheck/DataListCheck.jsx b/awx/ui_next/src/components/DataListCheck/DataListCheck.jsx index 511cc8d9a8..30817989cf 100644 --- a/awx/ui_next/src/components/DataListCheck/DataListCheck.jsx +++ b/awx/ui_next/src/components/DataListCheck/DataListCheck.jsx @@ -1,6 +1,7 @@ import { DataListCheck as PFDataListCheck } from '@patternfly/react-core'; import styled from 'styled-components'; +PFDataListCheck.displayName = 'PFDataListCheck'; export default styled(PFDataListCheck)` padding-top: 18px; @media screen and (min-width: 768px) { diff --git a/awx/ui_next/src/screens/Host/Host.test.jsx b/awx/ui_next/src/screens/Host/Host.test.jsx index 94b7dee895..ca7cb6fe97 100644 --- a/awx/ui_next/src/screens/Host/Host.test.jsx +++ b/awx/ui_next/src/screens/Host/Host.test.jsx @@ -12,13 +12,13 @@ const mockMe = { is_system_auditor: false, }; -describe.only('', () => { +describe('', () => { test('initially renders succesfully', () => { HostsAPI.readDetail.mockResolvedValue({ data: mockDetails }); mountWithContexts( {}} me={mockMe} />); }); - test('should show content error when user attempts to navigate to erroneous route', async done => { + test('should show content error when user attempts to navigate to erroneous route', async () => { const history = createMemoryHistory({ initialEntries: ['/hosts/1/foobar'], }); @@ -41,6 +41,5 @@ describe.only('', () => { } ); await waitForElement(wrapper, 'ContentError', el => el.length === 1); - done(); }); }); diff --git a/awx/ui_next/src/screens/Host/HostList/HostList.jsx b/awx/ui_next/src/screens/Host/HostList/HostList.jsx index 4886cfc899..3b6f6a9ea6 100644 --- a/awx/ui_next/src/screens/Host/HostList/HostList.jsx +++ b/awx/ui_next/src/screens/Host/HostList/HostList.jsx @@ -175,7 +175,7 @@ class HostsList extends Component { const canAdd = actions && Object.prototype.hasOwnProperty.call(actions, 'POST'); - const isAllSelected = selected.length === hosts.length; + const isAllSelected = selected.length > 0 && selected.length === hosts.length; return ( diff --git a/awx/ui_next/src/screens/Inventory/Inventory.test.jsx b/awx/ui_next/src/screens/Inventory/Inventory.test.jsx index b1b7abd112..cff57dfc11 100644 --- a/awx/ui_next/src/screens/Inventory/Inventory.test.jsx +++ b/awx/ui_next/src/screens/Inventory/Inventory.test.jsx @@ -11,7 +11,7 @@ InventoriesAPI.readDetail.mockResolvedValue({ data: mockInventory, }); -describe.only('', () => { +describe('', () => { test('initially renders succesfully', async done => { const wrapper = mountWithContexts( {}} match={{ params: { id: 1 } }} /> @@ -29,7 +29,7 @@ describe.only('', () => { await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 6); done(); }); - test('should show content error when user attempts to navigate to erroneous route', async done => { + test('should show content error when user attempts to navigate to erroneous route', async () => { const history = createMemoryHistory({ initialEntries: ['/inventories/inventory/1/foobar'], }); @@ -49,6 +49,5 @@ describe.only('', () => { }, }); await waitForElement(wrapper, 'ContentError', el => el.length === 1); - done(); }); }); diff --git a/awx/ui_next/src/screens/Inventory/InventoryList/InventoryList.jsx b/awx/ui_next/src/screens/Inventory/InventoryList/InventoryList.jsx index 35d33741b4..aaef81ca21 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryList/InventoryList.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryList/InventoryList.jsx @@ -174,7 +174,7 @@ class InventoriesList extends Component { const { match, i18n } = this.props; const canAdd = actions && Object.prototype.hasOwnProperty.call(actions, 'POST'); - const isAllSelected = selected.length === inventories.length; + const isAllSelected = selected.length > 0 && selected.length === inventories.length; return ( diff --git a/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx b/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx index 1f81d26ebf..33a4035b3c 100644 --- a/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx +++ b/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx @@ -11,7 +11,7 @@ InventoriesAPI.readDetail.mockResolvedValue({ data: mockSmartInventory, }); -describe.only('', () => { +describe('', () => { test('initially renders succesfully', async done => { const wrapper = mountWithContexts( {}} match={{ params: { id: 1 } }} /> @@ -29,7 +29,7 @@ describe.only('', () => { await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 4); done(); }); - test('should show content error when user attempts to navigate to erroneous route', async done => { + test('should show content error when user attempts to navigate to erroneous route', async () => { const history = createMemoryHistory({ initialEntries: ['/inventories/smart_inventory/1/foobar'], }); @@ -52,6 +52,5 @@ describe.only('', () => { } ); await waitForElement(wrapper, 'ContentError', el => el.length === 1); - done(); }); }); diff --git a/awx/ui_next/src/screens/Organization/Organization.test.jsx b/awx/ui_next/src/screens/Organization/Organization.test.jsx index 4c78bf94ed..4fda6bcffc 100644 --- a/awx/ui_next/src/screens/Organization/Organization.test.jsx +++ b/awx/ui_next/src/screens/Organization/Organization.test.jsx @@ -33,7 +33,7 @@ async function getOrganizations(params) { }; } -describe.only('', () => { +describe('', () => { test('initially renders succesfully', () => { OrganizationsAPI.readDetail.mockResolvedValue({ data: mockOrganization }); OrganizationsAPI.read.mockImplementation(getOrganizations); @@ -77,7 +77,7 @@ describe.only('', () => { done(); }); - test('should show content error when user attempts to navigate to erroneous route', async done => { + test('should show content error when user attempts to navigate to erroneous route', async () => { const history = createMemoryHistory({ initialEntries: ['/organizations/1/foobar'], }); @@ -100,6 +100,5 @@ describe.only('', () => { } ); await waitForElement(wrapper, 'ContentError', el => el.length === 1); - done(); }); }); diff --git a/awx/ui_next/src/screens/Project/Project.test.jsx b/awx/ui_next/src/screens/Project/Project.test.jsx index 2e21629923..264e111dfa 100644 --- a/awx/ui_next/src/screens/Project/Project.test.jsx +++ b/awx/ui_next/src/screens/Project/Project.test.jsx @@ -24,7 +24,7 @@ async function getOrganizations() { }; } -describe.only('', () => { +describe('', () => { test('initially renders succesfully', () => { ProjectsAPI.readDetail.mockResolvedValue({ data: mockDetails }); OrganizationsAPI.read.mockImplementation(getOrganizations); @@ -68,7 +68,7 @@ describe.only('', () => { done(); }); - test('should show content error when user attempts to navigate to erroneous route', async done => { + test('should show content error when user attempts to navigate to erroneous route', async () => { const history = createMemoryHistory({ initialEntries: ['/projects/1/foobar'], }); @@ -91,6 +91,5 @@ describe.only('', () => { } ); await waitForElement(wrapper, 'ContentError', el => el.length === 1); - done(); }); }); diff --git a/awx/ui_next/src/screens/Project/ProjectList/ProjectList.jsx b/awx/ui_next/src/screens/Project/ProjectList/ProjectList.jsx index 1e46ce6760..b6c112fd0b 100644 --- a/awx/ui_next/src/screens/Project/ProjectList/ProjectList.jsx +++ b/awx/ui_next/src/screens/Project/ProjectList/ProjectList.jsx @@ -141,7 +141,7 @@ class ProjectsList extends Component { const canAdd = actions && Object.prototype.hasOwnProperty.call(actions, 'POST'); - const isAllSelected = selected.length === projects.length; + const isAllSelected = selected.length > 0 && selected.length === projects.length; return ( diff --git a/awx/ui_next/src/screens/Team/Team.jsx b/awx/ui_next/src/screens/Team/Team.jsx index abcae4913b..1ebbe5b7b9 100644 --- a/awx/ui_next/src/screens/Team/Team.jsx +++ b/awx/ui_next/src/screens/Team/Team.jsx @@ -15,6 +15,13 @@ import TeamDetail from './TeamDetail'; import TeamEdit from './TeamEdit'; import { TeamsAPI } from '@api'; +const CardHeader = styled(PFCardHeader)` +--pf-c-card--first-child--PaddingTop: 0; +--pf-c-card--child--PaddingLeft: 0; +--pf-c-card--child--PaddingRight: 0; +position: relative; +`; + class Team extends Component { constructor(props) { super(props); @@ -73,13 +80,6 @@ class Team extends Component { { name: i18n._(t`Access`), link: `${match.url}/access`, id: 2 }, ]; - const CardHeader = styled(PFCardHeader)` - --pf-c-card--first-child--PaddingTop: 0; - --pf-c-card--child--PaddingLeft: 0; - --pf-c-card--child--PaddingRight: 0; - position: relative; - `; - let cardHeader = ( ', () => { +describe('', () => { test('initially renders succesfully', () => { TeamsAPI.readDetail.mockResolvedValue({ data: mockTeam }); TeamsAPI.read.mockImplementation(getTeams); mountWithContexts( {}} me={mockMe} />); }); - test('should show content error when user attempts to navigate to erroneous route', async done => { + test('should show content error when user attempts to navigate to erroneous route', async () => { const history = createMemoryHistory({ initialEntries: ['/teams/1/foobar'], }); @@ -63,6 +63,5 @@ describe.only('', () => { } ); await waitForElement(wrapper, 'ContentError', el => el.length === 1); - done(); }); }); diff --git a/awx/ui_next/src/screens/Team/TeamList/TeamList.jsx b/awx/ui_next/src/screens/Team/TeamList/TeamList.jsx index ac60f0c8ae..97b5c4fc15 100644 --- a/awx/ui_next/src/screens/Team/TeamList/TeamList.jsx +++ b/awx/ui_next/src/screens/Team/TeamList/TeamList.jsx @@ -139,7 +139,7 @@ class TeamsList extends Component { const canAdd = actions && Object.prototype.hasOwnProperty.call(actions, 'POST'); - const isAllSelected = selected.length === teams.length; + const isAllSelected = selected.length > 0 && selected.length === teams.length; return ( diff --git a/awx/ui_next/src/screens/Team/TeamList/TeamList.test.jsx b/awx/ui_next/src/screens/Team/TeamList/TeamList.test.jsx index 92b2df06d0..b043e73740 100644 --- a/awx/ui_next/src/screens/Team/TeamList/TeamList.test.jsx +++ b/awx/ui_next/src/screens/Team/TeamList/TeamList.test.jsx @@ -53,10 +53,7 @@ describe('', () => { beforeEach(() => { TeamsAPI.read = () => Promise.resolve({ - data: { - count: 0, - results: [], - }, + data: mockAPITeamsList.data, }); TeamsAPI.readOptions = () => Promise.resolve({ @@ -73,32 +70,43 @@ describe('', () => { mountWithContexts(); }); - test('Puts 1 selected Team in state when handleSelect is called.', () => { - wrapper = mountWithContexts().find('TeamsList'); - - wrapper.setState({ - teams: mockAPITeamsList.data.results, - itemCount: 3, - isInitialized: true, - }); + test('Selects one team when row is checked', async () => { + wrapper = mountWithContexts(); + await waitForElement( + wrapper, + 'TeamsList', + el => el.state('hasContentLoading') === false + ); + expect(wrapper.find('input[type="checkbox"]').findWhere(n => n.prop('checked') === true).length).toBe(0); + wrapper + .find('TeamListItem').at(0) + .find('DataListCheck') + .props() + .onChange(true); wrapper.update(); - expect(wrapper.state('selected').length).toBe(0); - wrapper.instance().handleSelect(mockAPITeamsList.data.results.slice(0, 1)); - expect(wrapper.state('selected').length).toBe(1); + expect(wrapper.find('input[type="checkbox"]').findWhere(n => n.prop('checked') === true).length).toBe(1); }); - test('Puts all Teams in state when handleSelectAll is called.', () => { + test('Select all checkbox selects and unselects all rows', async () => { wrapper = mountWithContexts(); - const list = wrapper.find('TeamsList'); - list.setState({ - teams: mockAPITeamsList.data.results, - itemCount: 3, - isInitialized: true, - }); - expect(list.state('selected').length).toBe(0); - list.instance().handleSelectAll(true); + await waitForElement( + wrapper, + 'TeamsList', + el => el.state('hasContentLoading') === false + ); + expect(wrapper.find('input[type="checkbox"]').findWhere(n => n.prop('checked') === true).length).toBe(0); + wrapper + .find('Checkbox#select-all') + .props() + .onChange(true); wrapper.update(); - expect(list.state('selected').length).toEqual(list.state('teams').length); + expect(wrapper.find('input[type="checkbox"]').findWhere(n => n.prop('checked') === true).length).toBe(4); + wrapper + .find('Checkbox#select-all') + .props() + .onChange(false); + wrapper.update(); + expect(wrapper.find('input[type="checkbox"]').findWhere(n => n.prop('checked') === true).length).toBe(0); }); test('api is called to delete Teams for each team in selected.', () => { diff --git a/awx/ui_next/src/screens/Team/TeamList/TeamListItem.jsx b/awx/ui_next/src/screens/Team/TeamList/TeamListItem.jsx index 73ddbcad14..b024ed85c8 100644 --- a/awx/ui_next/src/screens/Team/TeamList/TeamListItem.jsx +++ b/awx/ui_next/src/screens/Team/TeamList/TeamListItem.jsx @@ -45,7 +45,6 @@ class TeamListItem extends React.Component { {team.name} diff --git a/awx/ui_next/src/screens/Template/Template.test.jsx b/awx/ui_next/src/screens/Template/Template.test.jsx index a76309ccb9..c4f0a36af5 100644 --- a/awx/ui_next/src/screens/Template/Template.test.jsx +++ b/awx/ui_next/src/screens/Template/Template.test.jsx @@ -88,7 +88,7 @@ describe('