From 33deaa7d0bc415190db534e340949c62bae5b48d Mon Sep 17 00:00:00 2001 From: nixocio Date: Tue, 26 Jan 2021 16:01:52 -0500 Subject: [PATCH] Allow user to remove organization from credentials Allow user to remove organization from credentials. See: https://github.com/ansible/awx/issues/8707 --- .../components/Lookup/OrganizationLookup.jsx | 4 +++ .../CredentialEdit/CredentialEdit.jsx | 31 ++++++++++++++++--- .../CredentialEdit/CredentialEdit.test.jsx | 30 +++++++++++++++++- .../Credential/shared/CredentialForm.jsx | 11 ++++--- .../Credential/shared/CredentialForm.test.jsx | 21 +++++++++++++ .../Credential/shared/ExternalTestModal.jsx | 2 +- .../Inventory/InventoryEdit/InventoryEdit.jsx | 2 +- .../Inventory/shared/InventoryForm.jsx | 2 +- 8 files changed, 90 insertions(+), 13 deletions(-) diff --git a/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx b/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx index f958d8e407..3fb443426e 100644 --- a/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx +++ b/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx @@ -29,6 +29,7 @@ function OrganizationLookup({ value, history, autoPopulate, + isDisabled, }) { const autoPopulateLookup = useAutoPopulateLookup(onChange); @@ -80,6 +81,7 @@ function OrganizationLookup({ label={i18n._(t`Organization`)} > ); diff --git a/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx b/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx index 75cdeb2589..b750742a22 100644 --- a/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx +++ b/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx @@ -10,6 +10,8 @@ import { CredentialsAPI, CredentialInputSourcesAPI, CredentialTypesAPI, + OrganizationsAPI, + UsersAPI, } from '../../../api'; import CredentialEdit from './CredentialEdit'; @@ -114,6 +116,25 @@ const mockCredential = { kubernetes: false, }; +UsersAPI.readAdminOfOrganizations.mockResolvedValue({ + data: { + count: 1, + results: [ + { + id: 1, + name: 'org', + }, + ], + }, +}); + +OrganizationsAPI.read.mockResolvedValue({ + data: { + results: [{ id: 1 }], + count: 1, + }, +}); + CredentialTypesAPI.read.mockResolvedValue({ data: { results: [ @@ -310,7 +331,12 @@ describe('', () => { wrapper = mountWithContexts( , { - context: { router: { history } }, + context: { + router: { history }, + me: { + id: 1, + }, + }, } ); }); @@ -377,6 +403,7 @@ describe('', () => { expect(CredentialsAPI.update).toHaveBeenCalledWith(3, { user: 1, name: 'foo', + organization: null, description: 'bar', credential_type: '1', inputs: { @@ -439,6 +466,7 @@ describe('', () => { ).toBe('$encrypted$'); }); }); + describe('Initial GET request fails', () => { test('shows error when initial GET request fails', async () => { CredentialTypesAPI.read.mockRejectedValue(new Error()); diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx index a1e717bf24..0a33342b50 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx @@ -1,8 +1,8 @@ import React, { useCallback, useState } from 'react'; +import { func, shape } from 'prop-types'; import { Formik, useField, useFormikContext } from 'formik'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; -import { arrayOf, func, object, shape } from 'prop-types'; import { ActionGroup, Button, @@ -136,6 +136,7 @@ function CredentialFormFields({ i18n, credentialTypes }) { touched={orgMeta.touched} error={orgMeta.error} required={isGalaxyCredential} + isDisabled={initialValues.isOrgLookupDisabled} /> { @@ -311,18 +314,18 @@ function CredentialForm({ ); } -CredentialForm.proptype = { +CredentialForm.propTypes = { handleSubmit: func.isRequired, handleCancel: func.isRequired, credentialTypes: shape({}).isRequired, credential: shape({}), - inputSources: arrayOf(object), + inputSources: shape({}), submitError: shape({}), }; CredentialForm.defaultProps = { credential: {}, - inputSources: [], + inputSources: {}, submitError: null, }; diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx index ef110a7711..0cd1780b5c 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx @@ -327,6 +327,27 @@ describe('', () => { machineFieldExpects(); }); + test('organization lookup should be disabled', async () => { + await act(async () => { + wrapper = mountWithContexts( + + ); + }); + + expect( + wrapper + .find('CredentialFormFields') + .find('OrganizationLookup') + .prop('isDisabled') + ).toBe(true); + }); + test('should display form fields for source control credential properly', async () => { await act(async () => { wrapper = mountWithContexts( diff --git a/awx/ui_next/src/screens/Credential/shared/ExternalTestModal.jsx b/awx/ui_next/src/screens/Credential/shared/ExternalTestModal.jsx index b81b73142c..3e80b5e8d2 100644 --- a/awx/ui_next/src/screens/Credential/shared/ExternalTestModal.jsx +++ b/awx/ui_next/src/screens/Credential/shared/ExternalTestModal.jsx @@ -168,7 +168,7 @@ function ExternalTestModal({ ); } -ExternalTestModal.proptype = { +ExternalTestModal.propType = { credential: shape({}), credentialType: shape({}).isRequired, credentialFormValues: shape({}).isRequired, diff --git a/awx/ui_next/src/screens/Inventory/InventoryEdit/InventoryEdit.jsx b/awx/ui_next/src/screens/Inventory/InventoryEdit/InventoryEdit.jsx index 9e667a5ea6..f038ebf6fa 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryEdit/InventoryEdit.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryEdit/InventoryEdit.jsx @@ -118,7 +118,7 @@ function InventoryEdit({ inventory }) { ); } -InventoryEdit.proptype = { +InventoryEdit.propType = { inventory: object.isRequired, }; diff --git a/awx/ui_next/src/screens/Inventory/shared/InventoryForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventoryForm.jsx index 331ecd6e41..0cce85e9ca 100644 --- a/awx/ui_next/src/screens/Inventory/shared/InventoryForm.jsx +++ b/awx/ui_next/src/screens/Inventory/shared/InventoryForm.jsx @@ -138,7 +138,7 @@ function InventoryForm({ ); } -InventoryForm.proptype = { +InventoryForm.propType = { handleSubmit: func.isRequired, handleCancel: func.isRequired, instanceGroups: shape(),