mirror of
https://github.com/ansible/awx.git
synced 2026-01-20 06:01:25 -03:30
Hook up Test button on Metadata step in credential plugin wizard
This commit is contained in:
parent
4b51c71220
commit
67f46b4d7e
@ -13,6 +13,8 @@ import CredentialPluginPrompt from './CredentialPluginPrompt';
|
||||
jest.mock('../../../../../../api/models/Credentials');
|
||||
jest.mock('../../../../../../api/models/CredentialTypes');
|
||||
|
||||
CredentialsAPI.test.mockResolvedValue({});
|
||||
|
||||
CredentialsAPI.read.mockResolvedValue({
|
||||
data: {
|
||||
count: 3,
|
||||
@ -234,5 +236,13 @@ describe('<CredentialPluginPrompt />', () => {
|
||||
wrapper.find('input#credential-secret_version').prop('value')
|
||||
).toBe('9000');
|
||||
});
|
||||
test('clicking Test button makes correct call', async () => {
|
||||
await act(async () => {
|
||||
wrapper.find('Button#credential-plugin-test').simulate('click');
|
||||
});
|
||||
expect(CredentialsAPI.test).toHaveBeenCalledWith(1, {
|
||||
metadata: { secret_path: '/foo/bar', secret_version: '9000' },
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -13,6 +13,7 @@ import FormField from '../../../../../../components/FormField';
|
||||
import { FormFullWidthLayout } from '../../../../../../components/FormLayout';
|
||||
import useRequest from '../../../../../../util/useRequest';
|
||||
import { required } from '../../../../../../util/validators';
|
||||
import { CredentialPluginTestAlert } from '..';
|
||||
|
||||
const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
||||
margin-left: 10px;
|
||||
@ -27,6 +28,21 @@ function MetadataStep({ i18n }) {
|
||||
const [selectedCredential] = useField('credential');
|
||||
const [inputValues] = useField('inputs');
|
||||
|
||||
const {
|
||||
result: testPluginSuccess,
|
||||
error: testPluginError,
|
||||
request: testPluginMetadata,
|
||||
} = useRequest(
|
||||
useCallback(
|
||||
async (credential, metadata) =>
|
||||
CredentialsAPI.test(credential.id, {
|
||||
metadata,
|
||||
}),
|
||||
[]
|
||||
),
|
||||
null
|
||||
);
|
||||
|
||||
const {
|
||||
result: fields,
|
||||
error,
|
||||
@ -65,10 +81,6 @@ function MetadataStep({ i18n }) {
|
||||
fetchMetadataOptions();
|
||||
}, [fetchMetadataOptions]);
|
||||
|
||||
const testMetadata = () => {
|
||||
// https://github.com/ansible/awx/issues/7126
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return <ContentLoading />;
|
||||
}
|
||||
@ -143,13 +155,21 @@ function MetadataStep({ i18n }) {
|
||||
position="right"
|
||||
>
|
||||
<TestButton
|
||||
id="credential-plugin-test"
|
||||
variant="primary"
|
||||
type="submit"
|
||||
onClick={() => testMetadata()}
|
||||
onClick={() =>
|
||||
testPluginMetadata(selectedCredential.value, inputValues.value)
|
||||
}
|
||||
>
|
||||
{i18n._(t`Test`)}
|
||||
</TestButton>
|
||||
</Tooltip>
|
||||
<CredentialPluginTestAlert
|
||||
credentialName={selectedCredential.value.name}
|
||||
successResponse={testPluginSuccess}
|
||||
errorResponse={testPluginError}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Alert,
|
||||
AlertActionCloseButton,
|
||||
AlertGroup,
|
||||
} from '@patternfly/react-core';
|
||||
|
||||
function CredentialPluginTestAlert({
|
||||
i18n,
|
||||
credentialName,
|
||||
successResponse,
|
||||
errorResponse,
|
||||
}) {
|
||||
const [testMessage, setTestMessage] = useState('');
|
||||
const [testVariant, setTestVariant] = useState(false);
|
||||
useEffect(() => {
|
||||
if (errorResponse) {
|
||||
if (errorResponse?.response?.data?.inputs) {
|
||||
if (errorResponse.response.data.inputs.startsWith('HTTP')) {
|
||||
const [
|
||||
errorCode,
|
||||
errorStr,
|
||||
] = errorResponse.response.data.inputs.split('\n');
|
||||
try {
|
||||
const errorJSON = JSON.parse(errorStr);
|
||||
setTestMessage(
|
||||
`${errorCode}${
|
||||
errorJSON?.errors[0] ? `: ${errorJSON.errors[0]}` : ''
|
||||
}`
|
||||
);
|
||||
} catch {
|
||||
setTestMessage(errorResponse.response.data.inputs);
|
||||
}
|
||||
} else {
|
||||
setTestMessage(errorResponse.response.data.inputs);
|
||||
}
|
||||
} else {
|
||||
setTestMessage(
|
||||
i18n._(
|
||||
t`Something went wrong with the request to test this credential and metadata.`
|
||||
)
|
||||
);
|
||||
}
|
||||
setTestVariant('danger');
|
||||
} else if (successResponse) {
|
||||
setTestMessage(i18n._(t`Test passed`));
|
||||
setTestVariant('success');
|
||||
}
|
||||
}, [i18n, successResponse, errorResponse]);
|
||||
|
||||
return (
|
||||
<AlertGroup isToast>
|
||||
{testMessage && testVariant && (
|
||||
<Alert
|
||||
title={
|
||||
<>
|
||||
<b id="credential-plugin-test-name">{credentialName}</b>
|
||||
<p id="credential-plugin-test-message">{testMessage}</p>
|
||||
</>
|
||||
}
|
||||
variant={testVariant}
|
||||
action={
|
||||
<AlertActionCloseButton
|
||||
onClose={() => {
|
||||
setTestMessage(null);
|
||||
setTestVariant(null);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</AlertGroup>
|
||||
);
|
||||
}
|
||||
|
||||
CredentialPluginTestAlert.propTypes = {};
|
||||
|
||||
CredentialPluginTestAlert.defaultProps = {};
|
||||
|
||||
export default withI18n()(CredentialPluginTestAlert);
|
||||
@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import { mountWithContexts } from '../../../../../testUtils/enzymeHelpers';
|
||||
import CredentialPluginTestAlert from './CredentialPluginTestAlert';
|
||||
|
||||
describe('<CredentialPluginTestAlert />', () => {
|
||||
let wrapper;
|
||||
afterEach(() => {
|
||||
wrapper.unmount();
|
||||
});
|
||||
test('renders expected content when test is successful', () => {
|
||||
wrapper = mountWithContexts(
|
||||
<CredentialPluginTestAlert
|
||||
credentialName="Foobar"
|
||||
successResponse={{}}
|
||||
errorResponse={null}
|
||||
/>
|
||||
);
|
||||
expect(wrapper.find('b#credential-plugin-test-name').text()).toBe('Foobar');
|
||||
expect(wrapper.find('p#credential-plugin-test-message').text()).toBe(
|
||||
'Test passed'
|
||||
);
|
||||
});
|
||||
test('renders expected content when test fails with the expected return string formatting', () => {
|
||||
wrapper = mountWithContexts(
|
||||
<CredentialPluginTestAlert
|
||||
credentialName="Foobar"
|
||||
successResponse={null}
|
||||
errorResponse={{
|
||||
response: {
|
||||
data: {
|
||||
inputs: `HTTP 404
|
||||
{"errors":["not found"]}
|
||||
`,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(wrapper.find('b#credential-plugin-test-name').text()).toBe('Foobar');
|
||||
expect(wrapper.find('p#credential-plugin-test-message').text()).toBe(
|
||||
'HTTP 404: not found'
|
||||
);
|
||||
});
|
||||
test('renders expected content when test fails without the expected return string formatting', () => {
|
||||
wrapper = mountWithContexts(
|
||||
<CredentialPluginTestAlert
|
||||
credentialName="Foobar"
|
||||
successResponse={null}
|
||||
errorResponse={{
|
||||
response: {
|
||||
data: {
|
||||
inputs: 'usernamee is not present at /secret/foo/bar/baz',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(wrapper.find('b#credential-plugin-test-name').text()).toBe('Foobar');
|
||||
expect(wrapper.find('p#credential-plugin-test-message').text()).toBe(
|
||||
'usernamee is not present at /secret/foo/bar/baz'
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -39,6 +39,7 @@ export default function useRequest(makeRequest, initialValue) {
|
||||
async (...args) => {
|
||||
setIsLoading(true);
|
||||
if (isMounted.current) {
|
||||
setResult(initialValue);
|
||||
setError(null);
|
||||
}
|
||||
try {
|
||||
@ -56,6 +57,7 @@ export default function useRequest(makeRequest, initialValue) {
|
||||
}
|
||||
}
|
||||
},
|
||||
/* eslint-disable-next-line react-hooks/exhaustive-deps */
|
||||
[makeRequest]
|
||||
),
|
||||
setValue: setResult,
|
||||
|
||||
@ -96,6 +96,37 @@ describe('useRequest hooks', () => {
|
||||
expect(wrapper.find('TestInner').prop('error')).toEqual(error);
|
||||
});
|
||||
|
||||
test('should reset error/result on each request', async () => {
|
||||
const error = new Error('error');
|
||||
const makeRequest = throwError => {
|
||||
if (throwError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return { data: 'foo' };
|
||||
};
|
||||
const wrapper = mount(<Test makeRequest={makeRequest} />);
|
||||
|
||||
await act(async () => {
|
||||
wrapper.find('TestInner').invoke('request')(true);
|
||||
});
|
||||
wrapper.update();
|
||||
expect(wrapper.find('TestInner').prop('result')).toEqual({});
|
||||
expect(wrapper.find('TestInner').prop('error')).toEqual(error);
|
||||
await act(async () => {
|
||||
wrapper.find('TestInner').invoke('request')();
|
||||
});
|
||||
wrapper.update();
|
||||
expect(wrapper.find('TestInner').prop('result')).toEqual({ data: 'foo' });
|
||||
expect(wrapper.find('TestInner').prop('error')).toEqual(null);
|
||||
await act(async () => {
|
||||
wrapper.find('TestInner').invoke('request')(true);
|
||||
});
|
||||
wrapper.update();
|
||||
expect(wrapper.find('TestInner').prop('result')).toEqual({});
|
||||
expect(wrapper.find('TestInner').prop('error')).toEqual(error);
|
||||
});
|
||||
|
||||
test('should not update state after unmount', async () => {
|
||||
const makeRequest = jest.fn();
|
||||
let resolve;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user