diff --git a/awx/ui_next/src/components/FormField/PasswordField.test.jsx b/awx/ui_next/src/components/FormField/PasswordField.test.jsx
index 2f2ceab52a..e2b40dbd09 100644
--- a/awx/ui_next/src/components/FormField/PasswordField.test.jsx
+++ b/awx/ui_next/src/components/FormField/PasswordField.test.jsx
@@ -1,7 +1,6 @@
import React from 'react';
import { Formik } from 'formik';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
-import { sleep } from '../../../testUtils/testUtils';
import PasswordField from './PasswordField';
describe('PasswordField', () => {
@@ -19,26 +18,4 @@ describe('PasswordField', () => {
);
expect(wrapper).toHaveLength(1);
});
-
- test('properly responds to show/hide toggles', async () => {
- const wrapper = mountWithContexts(
-
- {() => (
-
- )}
-
- );
- expect(wrapper.find('input').prop('type')).toBe('password');
- expect(wrapper.find('EyeSlashIcon').length).toBe(1);
- expect(wrapper.find('EyeIcon').length).toBe(0);
- wrapper.find('button').simulate('click');
- await sleep(1);
- expect(wrapper.find('input').prop('type')).toBe('text');
- expect(wrapper.find('EyeSlashIcon').length).toBe(0);
- expect(wrapper.find('EyeIcon').length).toBe(1);
- });
});
diff --git a/awx/ui_next/src/components/FormField/PasswordInput.test.jsx b/awx/ui_next/src/components/FormField/PasswordInput.test.jsx
new file mode 100644
index 0000000000..374ba1a6e8
--- /dev/null
+++ b/awx/ui_next/src/components/FormField/PasswordInput.test.jsx
@@ -0,0 +1,44 @@
+import React from 'react';
+import { Formik } from 'formik';
+import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
+import { sleep } from '../../../testUtils/testUtils';
+import PasswordInput from './PasswordInput';
+
+describe('PasswordInput', () => {
+ test('renders the expected content', () => {
+ const wrapper = mountWithContexts(
+
+ {() => (
+
+ )}
+
+ );
+ expect(wrapper).toHaveLength(1);
+ });
+
+ test('properly responds to show/hide toggles', async () => {
+ const wrapper = mountWithContexts(
+
+ {() => (
+
+ )}
+
+ );
+ expect(wrapper.find('input').prop('type')).toBe('password');
+ expect(wrapper.find('EyeSlashIcon').length).toBe(1);
+ expect(wrapper.find('EyeIcon').length).toBe(0);
+ wrapper.find('button').simulate('click');
+ await sleep(1);
+ expect(wrapper.find('input').prop('type')).toBe('text');
+ expect(wrapper.find('EyeSlashIcon').length).toBe(0);
+ expect(wrapper.find('EyeIcon').length).toBe(1);
+ });
+});
diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginField.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginField.test.jsx
new file mode 100644
index 0000000000..39f77b63b4
--- /dev/null
+++ b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginField.test.jsx
@@ -0,0 +1,85 @@
+import React from 'react';
+import { Formik } from 'formik';
+import { TextInput } from '@patternfly/react-core';
+import { mountWithContexts } from '../../../../../testUtils/enzymeHelpers';
+import CredentialPluginField from './CredentialPluginField';
+
+describe('', () => {
+ let wrapper;
+ describe('No plugin configured', () => {
+ beforeAll(() => {
+ wrapper = mountWithContexts(
+
+ {() => (
+
+
+
+ )}
+
+ );
+ });
+ afterAll(() => {
+ wrapper.unmount();
+ });
+ test('renders the expected content', () => {
+ expect(wrapper.find('input').length).toBe(1);
+ expect(wrapper.find('KeyIcon').length).toBe(1);
+ expect(wrapper.find('CredentialPluginSelected').length).toBe(0);
+ });
+ test('clicking plugin button shows plugin prompt', () => {
+ expect(wrapper.find('CredentialPluginPrompt').length).toBe(0);
+ wrapper.find('KeyIcon').simulate('click');
+ expect(wrapper.find('CredentialPluginPrompt').length).toBe(1);
+ });
+ });
+ describe('Plugin already configured', () => {
+ beforeAll(() => {
+ wrapper = mountWithContexts(
+
+ {() => (
+
+
+
+ )}
+
+ );
+ });
+ afterAll(() => {
+ wrapper.unmount();
+ });
+ test('renders the expected content', () => {
+ expect(wrapper.find('CredentialPluginPrompt').length).toBe(0);
+ expect(wrapper.find('input').length).toBe(0);
+ expect(wrapper.find('KeyIcon').length).toBe(1);
+ expect(wrapper.find('CredentialPluginSelected').length).toBe(1);
+ });
+ });
+});
diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.jsx
index c2cd65f212..d8a66e8426 100644
--- a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.jsx
+++ b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.jsx
@@ -1,4 +1,5 @@
import React from 'react';
+import { func } from 'prop-types';
import { Formik, useField } from 'formik';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
@@ -54,7 +55,10 @@ function CredentialPluginPrompt({ i18n, onClose, onSubmit, initialValues }) {
);
}
-CredentialPluginPrompt.propTypes = {};
+CredentialPluginPrompt.propTypes = {
+ onClose: func.isRequired,
+ onSubmit: func.isRequired,
+};
CredentialPluginPrompt.defaultProps = {};
diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx
new file mode 100644
index 0000000000..095e203f38
--- /dev/null
+++ b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import { mountWithContexts } from '../../../../../../testUtils/enzymeHelpers';
+import CredentialPluginPrompt from './CredentialPluginPrompt';
+
+describe('', () => {
+ let wrapper;
+ beforeAll(() => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ afterAll(() => {
+ wrapper.unmount();
+ });
+ test('renders the expected content', () => {
+ expect(wrapper).toHaveLength(1);
+ });
+});
diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.jsx
index 2ea3ca84d0..a7d408d49f 100644
--- a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.jsx
+++ b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.jsx
@@ -1,10 +1,12 @@
import React from 'react';
+import { func } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t, Trans } from '@lingui/macro';
import styled from 'styled-components';
import { Button, ButtonVariant, Tooltip } from '@patternfly/react-core';
import { KeyIcon } from '@patternfly/react-icons';
import CredentialChip from '../../../../components/CredentialChip';
+import { Credential } from '../../../../types';
const SelectedCredential = styled.div`
display: flex;
@@ -51,4 +53,15 @@ function CredentialPluginSelected({
);
}
+CredentialPluginSelected.propTypes = {
+ credential: Credential.isRequired,
+ onEditPlugin: func,
+ onClearPlugin: func,
+};
+
+CredentialPluginSelected.defaultProps = {
+ onEditPlugin: () => {},
+ onClearPlugin: () => {},
+};
+
export default withI18n()(CredentialPluginSelected);
diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.test.jsx
new file mode 100644
index 0000000000..ce69724904
--- /dev/null
+++ b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginSelected.test.jsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import { mountWithContexts } from '../../../../../testUtils/enzymeHelpers';
+import selectedCredential from '../data.cyberArkCredential.json';
+import CredentialPluginSelected from './CredentialPluginSelected';
+
+describe('', () => {
+ let wrapper;
+ const onClearPlugin = jest.fn();
+ const onEditPlugin = jest.fn();
+ beforeAll(() => {
+ wrapper = mountWithContexts(
+
+ );
+ });
+ afterAll(() => {
+ wrapper.unmount();
+ });
+ test('renders the expected content', () => {
+ expect(wrapper.find('CredentialChip').length).toBe(1);
+ expect(wrapper.find('KeyIcon').length).toBe(1);
+ });
+ test('clearing plugin calls expected function', () => {
+ wrapper.find('CredentialChip button').simulate('click');
+ expect(onClearPlugin).toBeCalledTimes(1);
+ });
+ test('editing plugin calls expected function', () => {
+ wrapper.find('KeyIcon').simulate('click');
+ expect(onEditPlugin).toBeCalledTimes(1);
+ });
+});
diff --git a/awx/ui_next/src/screens/Credential/shared/data.cyberArkCredential.json b/awx/ui_next/src/screens/Credential/shared/data.cyberArkCredential.json
new file mode 100644
index 0000000000..94b0bbd8fd
--- /dev/null
+++ b/awx/ui_next/src/screens/Credential/shared/data.cyberArkCredential.json
@@ -0,0 +1,85 @@
+{
+ "id": 1,
+ "type": "credential",
+ "url": "/api/v2/credentials/1/",
+ "related": {
+ "named_url": "/api/v2/credentials/CyberArk Conjur Secret Lookup++CyberArk Conjur Secret Lookup+external++/",
+ "created_by": "/api/v2/users/1/",
+ "modified_by": "/api/v2/users/1/",
+ "activity_stream": "/api/v2/credentials/1/activity_stream/",
+ "access_list": "/api/v2/credentials/1/access_list/",
+ "object_roles": "/api/v2/credentials/1/object_roles/",
+ "owner_users": "/api/v2/credentials/1/owner_users/",
+ "owner_teams": "/api/v2/credentials/1/owner_teams/",
+ "copy": "/api/v2/credentials/1/copy/",
+ "input_sources": "/api/v2/credentials/1/input_sources/",
+ "credential_type": "/api/v2/credential_types/20/",
+ "user": "/api/v2/users/1/"
+ },
+ "summary_fields": {
+ "credential_type": {
+ "id": 20,
+ "name": "CyberArk Conjur Secret Lookup",
+ "description": ""
+ },
+ "created_by": {
+ "id": 1,
+ "username": "admin",
+ "first_name": "",
+ "last_name": ""
+ },
+ "modified_by": {
+ "id": 1,
+ "username": "admin",
+ "first_name": "",
+ "last_name": ""
+ },
+ "object_roles": {
+ "admin_role": {
+ "description": "Can manage all aspects of the credential",
+ "name": "Admin",
+ "id": 27
+ },
+ "use_role": {
+ "description": "Can use the credential in a job template",
+ "name": "Use",
+ "id": 28
+ },
+ "read_role": {
+ "description": "May view settings for the credential",
+ "name": "Read",
+ "id": 29
+ }
+ },
+ "user_capabilities": {
+ "edit": true,
+ "delete": true,
+ "copy": true,
+ "use": true
+ },
+ "owners": [
+ {
+ "id": 1,
+ "type": "user",
+ "name": "admin",
+ "description": " ",
+ "url": "/api/v2/users/1/"
+ }
+ ]
+ },
+ "created": "2020-05-19T12:51:36.956029Z",
+ "modified": "2020-05-19T12:51:36.956086Z",
+ "name": "CyberArk Conjur Secret Lookup",
+ "description": "",
+ "organization": null,
+ "credential_type": 20,
+ "inputs": {
+ "url": "https://localhost",
+ "account": "adsf",
+ "api_key": "$encrypted$",
+ "username": "adsf"
+ },
+ "kind": "conjur",
+ "cloud": false,
+ "kubernetes": false
+}