From df3b60421c9693c17195a59cc9484a2e21b47b8a Mon Sep 17 00:00:00 2001 From: Kersom <9053044+nixocio@users.noreply.github.com> Date: Wed, 23 Sep 2020 12:44:08 -0400 Subject: [PATCH] Update usage of summary_fields for execution environments (#8217) Update usage of summary_fields for execution environments. Also, update unit-tests to cover this change. See: https://github.com/ansible/awx/issues/8216 --- .../PaginatedDataList/ToolbarDeleteButton.jsx | 27 +++++-- .../ExecutionEnviromentList.test.jsx | 77 +++++++++++++++++++ .../shared/ExecutionEnvironmentForm.test.jsx | 2 +- 3 files changed, 97 insertions(+), 9 deletions(-) diff --git a/awx/ui_next/src/components/PaginatedDataList/ToolbarDeleteButton.jsx b/awx/ui_next/src/components/PaginatedDataList/ToolbarDeleteButton.jsx index 394d8a612a26..1f2d5be8e021 100644 --- a/awx/ui_next/src/components/PaginatedDataList/ToolbarDeleteButton.jsx +++ b/awx/ui_next/src/components/PaginatedDataList/ToolbarDeleteButton.jsx @@ -20,11 +20,11 @@ const WarningMessage = styled(Alert)` margin-top: 10px; `; -const requireNameOrUsername = props => { - const { name, username } = props; - if (!name && !username) { +const requiredField = props => { + const { name, username, image } = props; + if (!name && !username && !image) { return new Error( - `One of 'name' or 'username' is required by ItemToDelete component.` + `One of 'name', 'username' or 'image' is required by ItemToDelete component.` ); } if (name) { @@ -47,13 +47,24 @@ const requireNameOrUsername = props => { 'ItemToDelete' ); } + if (image) { + checkPropTypes( + { + image: string, + }, + { image: props.image }, + 'prop', + 'ItemToDelete' + ); + } return null; }; const ItemToDelete = shape({ id: number.isRequired, - name: requireNameOrUsername, - username: requireNameOrUsername, + name: requiredField, + username: requiredField, + image: requiredField, summary_fields: shape({ user_capabilities: shape({ delete: bool.isRequired, @@ -62,7 +73,7 @@ const ItemToDelete = shape({ }); function cannotDelete(item) { - return !item.summary_fields?.user_capabilities?.delete; + return !item.summary_fields.user_capabilities.delete; } function ToolbarDeleteButton({ @@ -174,7 +185,7 @@ function ToolbarDeleteButton({
{i18n._(t`This action will delete the following:`)}
{itemsToDelete.map(item => ( - {item.name || item.username} + {item.name || item.username || item.image}
))} diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnviromentList.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnviromentList.test.jsx index 4371d4c72709..475dd1a8b56c 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnviromentList.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnviromentList.test.jsx @@ -20,6 +20,7 @@ const executionEnvironments = { organization: null, credential: null, url: '/api/v2/execution_environments/1/', + summary_fields: { user_capabilities: { edit: true, delete: true } }, }, { id: 2, @@ -27,6 +28,7 @@ const executionEnvironments = { organization: null, credential: null, url: '/api/v2/execution_environments/2/', + summary_fields: { user_capabilities: { edit: false, delete: true } }, }, ], count: 2, @@ -67,6 +69,81 @@ describe('', () => { expect(ExecutionEnvironmentsAPI.readOptions).toBeCalled(); }); + test('should delete item successfully', async () => { + ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments); + ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options); + + await act(async () => { + wrapper = mountWithContexts(); + }); + await waitForElement( + wrapper, + 'ExecutionEnvironmentList', + el => el.length > 0 + ); + + wrapper + .find('input#select-execution-environment-1') + .simulate('change', executionEnvironments.data.results[0]); + wrapper.update(); + + expect( + wrapper.find('input#select-execution-environment-1').prop('checked') + ).toBe(true); + + await act(async () => { + wrapper.find('Button[aria-label="Delete"]').prop('onClick')(); + }); + wrapper.update(); + + await act(async () => { + wrapper.find('Button[aria-label="confirm delete"]').prop('onClick')(); + }); + + expect(ExecutionEnvironmentsAPI.destroy).toBeCalledWith( + executionEnvironments.data.results[0].id + ); + }); + + test('should render deletion error modal', async () => { + ExecutionEnvironmentsAPI.destroy.mockRejectedValue( + new Error({ + response: { + config: { + method: 'DELETE', + url: '/api/v2/execution_environments', + }, + data: 'An error occurred', + }, + }) + ); + ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments); + ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options); + await act(async () => { + wrapper = mountWithContexts(); + }); + waitForElement(wrapper, 'ExecutionEnvironmentList', el => el.length > 0); + + wrapper + .find('input#select-execution-environment-1') + .simulate('change', 'a'); + wrapper.update(); + expect( + wrapper.find('input#select-execution-environment-1').prop('checked') + ).toBe(true); + + await act(async () => + wrapper.find('Button[aria-label="Delete"]').prop('onClick')() + ); + wrapper.update(); + + await act(async () => + wrapper.find('Button[aria-label="confirm delete"]').prop('onClick')() + ); + wrapper.update(); + expect(wrapper.find('ErrorDetail').length).toBe(1); + }); + test('should thrown content error', async () => { ExecutionEnvironmentsAPI.read.mockRejectedValue( new Error({ diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx index 717b26435496..98164b6964ae 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx @@ -62,7 +62,7 @@ describe('', () => { }); test('should display form fields properly', () => { - expect(wrapper.find('FormGroup[label="Image"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="Image name"]').length).toBe(1); expect(wrapper.find('FormGroup[label="Description"]').length).toBe(1); expect(wrapper.find('CredentialLookup').length).toBe(1); });