From 9540ed436486b1a3e3b246d0619920c9c623355a Mon Sep 17 00:00:00 2001 From: mabashian Date: Tue, 20 Apr 2021 13:00:44 -0400 Subject: [PATCH 1/2] Fixes bug where credential form checkboxes were erroneously checked --- .../Credential/shared/CredentialForm.jsx | 4 +- .../Credential/shared/CredentialForm.test.jsx | 30 +++++++ .../shared/data.credentialTypes.json | 67 ++++++++------- .../shared/data.towerCredential.json | 85 +++++++++++++++++++ 4 files changed, 153 insertions(+), 33 deletions(-) create mode 100644 awx/ui_next/src/screens/Credential/shared/data.towerCredential.json diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx index fa24a5ffd4..25ae4ac23a 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx @@ -244,7 +244,7 @@ function CredentialForm({ description: credential.description || '', organization: credential?.summary_fields?.organization || null, credential_type: credentialTypes[initialTypeId]?.name || '', - inputs: credential?.inputs || {}, + inputs: { ...credential?.inputs }, passwordPrompts: {}, isOrgLookupDisabled: isOrgLookupDisabled || false, }; @@ -253,7 +253,7 @@ function CredentialForm({ const fields = credentialType.inputs.fields || []; fields.forEach( ({ ask_at_runtime, type, id, choices, default: defaultValue }) => { - if (credential?.inputs && credential.inputs[id]) { + if (credential?.inputs && id in credential.inputs) { if (ask_at_runtime) { initialValues.passwordPrompts[id] = credential.inputs[id] === 'ASK' || false; 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 0cd1780b5c..326655453c 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx @@ -5,6 +5,7 @@ import machineCredential from './data.machineCredential.json'; import gceCredential from './data.gceCredential.json'; import scmCredential from './data.scmCredential.json'; import galaxyCredential from './data.galaxyCredential.json'; +import towerCredential from './data.towerCredential.json'; import credentialTypesArr from './data.credentialTypes.json'; import CredentialForm from './CredentialForm'; @@ -397,5 +398,34 @@ describe('', () => { ).toBe(true); expect(wrapper.find('FormGroup[label="Credential Type"]').length).toBe(1); }); + + test('should display from fields for tower credentials', async () => { + await act(async () => { + wrapper = mountWithContexts( + + ); + }); + expect(wrapper.find('FormGroup[label="Name"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="Description"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="Organization"]').length).toBe(1); + expect( + wrapper.find('FormGroup[label="Organization"]').prop('isRequired') + ).toBe(false); + expect(wrapper.find('FormGroup[label="Credential Type"]').length).toBe(1); + expect( + wrapper.find('FormGroup[label="Ansible Tower Hostname"]').length + ).toBe(1); + expect(wrapper.find('FormGroup[label="Username"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="Password"]').length).toBe(1); + expect(wrapper.find('FormGroup[label="OAuth Token"]').length).toBe(1); + expect( + wrapper.find('Checkbox#credential-verify_ssl').prop('isChecked') + ).toBe(false); + }); }); }); diff --git a/awx/ui_next/src/screens/Credential/shared/data.credentialTypes.json b/awx/ui_next/src/screens/Credential/shared/data.credentialTypes.json index d3e048dbd7..2fbc4f90a9 100644 --- a/awx/ui_next/src/screens/Credential/shared/data.credentialTypes.json +++ b/awx/ui_next/src/screens/Credential/shared/data.credentialTypes.json @@ -85,6 +85,13 @@ "type": "string", "secret": true }, + { + "id": "oauth_token", + "label": "OAuth Token", + "type": "string", + "secret": true, + "help_text": "An OAuth token to use to authenticate to Tower with.This should not be set if username/password are being used." + }, { "id": "verify_ssl", "label": "Verify SSL", @@ -1280,14 +1287,14 @@ "type": "credential_type", "url": "/api/v2/credential_types/42/", "related": { - "credentials": "/api/v2/credential_types/42/credentials/", - "activity_stream": "/api/v2/credential_types/42/activity_stream/" + "credentials": "/api/v2/credential_types/42/credentials/", + "activity_stream": "/api/v2/credential_types/42/activity_stream/" }, "summary_fields": { - "user_capabilities": { - "edit": true, - "delete": true - } + "user_capabilities": { + "edit": true, + "delete": true + } }, "created": "2020-11-11T00:18:31.928286Z", "modified": "2020-11-11T00:19:00.851597Z", @@ -1297,31 +1304,29 @@ "namespace": "galaxy_api_token", "managed_by_tower": true, "inputs": { - "fields": [ - { - "id": "url", - "label": "Galaxy Server URL", - "type": "string", - "help_text": "The URL of the Galaxy instance to connect to." - }, - { - "id": "auth_url", - "label": "Auth Server URL", - "type": "string", - "help_text": "The URL of a Keycloak server token_endpoint, if using SSO auth." - }, - { - "id": "token", - "label": "API Token", - "type": "string", - "secret": true, - "help_text": "A token to use for authentication against the Galaxy instance." - } - ], - "required": [ - "url" - ] + "fields": [ + { + "id": "url", + "label": "Galaxy Server URL", + "type": "string", + "help_text": "The URL of the Galaxy instance to connect to." + }, + { + "id": "auth_url", + "label": "Auth Server URL", + "type": "string", + "help_text": "The URL of a Keycloak server token_endpoint, if using SSO auth." + }, + { + "id": "token", + "label": "API Token", + "type": "string", + "secret": true, + "help_text": "A token to use for authentication against the Galaxy instance." + } + ], + "required": ["url"] }, "injectors": {} -} + } ] diff --git a/awx/ui_next/src/screens/Credential/shared/data.towerCredential.json b/awx/ui_next/src/screens/Credential/shared/data.towerCredential.json new file mode 100644 index 0000000000..bfa544a5ed --- /dev/null +++ b/awx/ui_next/src/screens/Credential/shared/data.towerCredential.json @@ -0,0 +1,85 @@ +{ + "id": 4, + "type": "credential", + "url": "/api/v2/credentials/4/", + "related": { + "named_url": "/api/v2/credentials/Tower cred++Ansible Tower+cloud++/", + "created_by": "/api/v2/users/2/", + "modified_by": "/api/v2/users/2/", + "activity_stream": "/api/v2/credentials/4/activity_stream/", + "access_list": "/api/v2/credentials/4/access_list/", + "object_roles": "/api/v2/credentials/4/object_roles/", + "owner_users": "/api/v2/credentials/4/owner_users/", + "owner_teams": "/api/v2/credentials/4/owner_teams/", + "copy": "/api/v2/credentials/4/copy/", + "input_sources": "/api/v2/credentials/4/input_sources/", + "credential_type": "/api/v2/credential_types/15/", + "user": "/api/v2/users/2/" + }, + "summary_fields": { + "credential_type": { + "id": 16, + "name": "Ansible Tower", + "description": "" + }, + "created_by": { + "id": 2, + "username": "test", + "first_name": "", + "last_name": "" + }, + "modified_by": { + "id": 2, + "username": "test", + "first_name": "", + "last_name": "" + }, + "object_roles": { + "admin_role": { + "description": "Can manage all aspects of the credential", + "name": "Admin", + "id": 37 + }, + "use_role": { + "description": "Can use the credential in a job template", + "name": "Use", + "id": 38 + }, + "read_role": { + "description": "May view settings for the credential", + "name": "Read", + "id": 39 + } + }, + "user_capabilities": { + "edit": true, + "delete": true, + "copy": true, + "use": true + }, + "owners": [ + { + "id": 2, + "type": "user", + "name": "test", + "description": " ", + "url": "/api/v2/users/2/" + } + ] + }, + "created": "2021-04-20T14:05:16.538312Z", + "modified": "2021-04-20T14:05:26.177919Z", + "name": "Tower cred", + "description": "", + "organization": null, + "credential_type": 16, + "managed_by_tower": false, + "inputs": { + "host": "https://localhost", + "username": "", + "verify_ssl": false + }, + "kind": "tower", + "cloud": true, + "kubernetes": false +} From 07d08b57d11335a68465cd4af377468094aeec01 Mon Sep 17 00:00:00 2001 From: mabashian Date: Tue, 20 Apr 2021 13:12:31 -0400 Subject: [PATCH 2/2] Fixes typo --- .../src/screens/Credential/shared/CredentialForm.test.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 326655453c..8d77e90b3d 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx @@ -379,7 +379,7 @@ describe('', () => { gceFieldExpects(); }); - test('should display from fields for galaxy/automation hub credentials', async () => { + test('should display form fields for galaxy/automation hub credentials', async () => { await act(async () => { wrapper = mountWithContexts( ', () => { expect(wrapper.find('FormGroup[label="Credential Type"]').length).toBe(1); }); - test('should display from fields for tower credentials', async () => { + test('should display form fields for tower credentials', async () => { await act(async () => { wrapper = mountWithContexts(