Merge pull request #9960 from mabashian/9955-cred-bool

Fixes bug where credential form checkboxes were erroneously checked

SUMMARY
link #9955
A couple of things going on here.

Updating initialValues.inputs was also modifying credential.inputs because initialValues.inputs was originally a reference to credential.inputs.  I changed this so that initialValues.inputs now starts off as a clone of credential.inputs.
https://github.com/ansible/awx/compare/devel...mabashian:9955-cred-bool?expand=1#diff-db8df3eaf3e3b3117f845786dea77451fba53e9d6a3f49ae367a26137039fc35L256 <- this line was erroneously evaluating to false when the value of an input was false.  We actually just want to make sure the key exists in the object before dropping in to this block.  This is what actually fixes the bug.  Before this change we would fall in to https://github.com/ansible/awx/compare/devel...mabashian:9955-cred-bool?expand=1#diff-db8df3eaf3e3b3117f845786dea77451fba53e9d6a3f49ae367a26137039fc35R268 where the checkbox value would be erroneously set.

ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME

UI

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
Reviewed-by: Tiago Góes <tiago.goes2009@gmail.com>
This commit is contained in:
softwarefactory-project-zuul[bot] 2021-04-27 13:49:14 +00:00 committed by GitHub
commit 35e778b7ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 154 additions and 34 deletions

View File

@ -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;

View File

@ -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';
@ -378,7 +379,7 @@ describe('<CredentialForm />', () => {
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(
<CredentialForm
@ -397,5 +398,34 @@ describe('<CredentialForm />', () => {
).toBe(true);
expect(wrapper.find('FormGroup[label="Credential Type"]').length).toBe(1);
});
test('should display form fields for tower credentials', async () => {
await act(async () => {
wrapper = mountWithContexts(
<CredentialForm
onCancel={onCancel}
onSubmit={onSubmit}
credential={towerCredential}
credentialTypes={credentialTypes}
/>
);
});
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);
});
});
});

View File

@ -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": {}
}
}
]

View File

@ -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
}