Adds a bit more unit test coverage around credential add/edit save functionality, making sure that we're making the correct calls with the correct payloads.

This commit is contained in:
mabashian 2020-06-09 13:58:40 -04:00
parent 9d63b679f9
commit 9180334908
2 changed files with 237 additions and 190 deletions

View File

@ -6,7 +6,11 @@ import {
waitForElement,
} from '../../../../testUtils/enzymeHelpers';
import { CredentialsAPI, CredentialTypesAPI } from '../../../api';
import {
CredentialsAPI,
CredentialInputSourcesAPI,
CredentialTypesAPI,
} from '../../../api';
import CredentialAdd from './CredentialAdd';
jest.mock('../../../api');
@ -14,58 +18,6 @@ jest.mock('../../../api');
CredentialTypesAPI.read.mockResolvedValue({
data: {
results: [
{
id: 2,
type: 'credential_type',
url: '/api/v2/credential_types/2/',
related: {
credentials: '/api/v2/credential_types/2/credentials/',
activity_stream: '/api/v2/credential_types/2/activity_stream/',
},
summary_fields: {
user_capabilities: {
edit: false,
delete: false,
},
},
created: '2020-02-12T19:42:43.551238Z',
modified: '2020-02-12T19:43:03.164800Z',
name: 'Source Control',
description: '',
kind: 'scm',
namespace: 'scm',
managed_by_tower: true,
inputs: {
fields: [
{
id: 'username',
label: 'Username',
type: 'string',
},
{
id: 'password',
label: 'Password',
type: 'string',
secret: true,
},
{
id: 'ssh_key_data',
label: 'Source Control Private Key',
type: 'string',
format: 'ssh_private_key',
secret: true,
multiline: true,
},
{
id: 'ssh_key_unlock',
label: 'Private Key Passphrase',
type: 'string',
secret: true,
},
],
},
injectors: {},
},
{
id: 1,
type: 'credential_type',
@ -156,59 +108,98 @@ describe('<CredentialAdd />', () => {
let wrapper;
let history;
beforeEach(async () => {
history = createMemoryHistory({ initialEntries: ['/credentials'] });
await act(async () => {
wrapper = mountWithContexts(<CredentialAdd />, {
context: { router: { history } },
describe('Initial GET request succeeds', () => {
beforeEach(async () => {
history = createMemoryHistory({ initialEntries: ['/credentials'] });
await act(async () => {
wrapper = mountWithContexts(<CredentialAdd />, {
context: { router: { history } },
});
});
});
});
afterEach(() => {
wrapper.unmount();
});
afterEach(() => {
wrapper.unmount();
});
test('Initially renders successfully', () => {
expect(wrapper.length).toBe(1);
});
test('handleSubmit should call the api and redirect to details page', async () => {
await waitForElement(wrapper, 'isLoading', el => el.length === 0);
await act(async () => {
wrapper.find('CredentialForm').prop('onSubmit')({
test('handleSubmit should call the api and redirect to details page', async () => {
await waitForElement(wrapper, 'isLoading', el => el.length === 0);
await act(async () => {
wrapper.find('CredentialForm').prop('onSubmit')({
user: 1,
organization: null,
name: 'foo',
description: 'bar',
credential_type: '1',
inputs: {
username: {
credential: {
id: 1,
name: 'Some cred',
},
inputs: {
foo: 'bar',
},
},
password: 'foo',
ssh_key_data: 'bar',
ssh_public_key_data: 'baz',
ssh_key_unlock: 'foobar',
become_method: '',
become_username: '',
become_password: '',
},
passwordPrompts: {
become_password: true,
},
});
});
expect(CredentialsAPI.create).toHaveBeenCalledWith({
user: 1,
organization: null,
name: 'foo',
description: 'bar',
credential_type: '2',
credential_type: '1',
inputs: {
username: '',
password: '',
ssh_key_data: '',
ssh_key_unlock: '',
password: 'foo',
ssh_key_data: 'bar',
ssh_public_key_data: 'baz',
ssh_key_unlock: 'foobar',
become_method: '',
become_username: '',
become_password: 'ASK',
},
passwordPrompts: {},
});
expect(CredentialInputSourcesAPI.create).toHaveBeenCalledWith({
input_field_name: 'username',
metadata: {
foo: 'bar',
},
source_credential: 1,
target_credential: 13,
});
expect(history.location.pathname).toBe('/credentials/13/details');
});
expect(CredentialsAPI.create).toHaveBeenCalledWith({
user: 1,
organization: null,
name: 'foo',
description: 'bar',
credential_type: '2',
inputs: {
username: '',
password: '',
ssh_key_data: '',
ssh_key_unlock: '',
},
test('handleCancel should return the user back to the inventories list', async () => {
await waitForElement(wrapper, 'isLoading', el => el.length === 0);
wrapper.find('Button[aria-label="Cancel"]').simulate('click');
expect(history.location.pathname).toEqual('/credentials');
});
expect(history.location.pathname).toBe('/credentials/13/details');
});
test('handleCancel should return the user back to the inventories list', async () => {
await waitForElement(wrapper, 'isLoading', el => el.length === 0);
wrapper.find('Button[aria-label="Cancel"]').simulate('click');
expect(history.location.pathname).toEqual('/credentials');
describe('Initial GET request fails', () => {
test('shows error when initial GET request fails', async () => {
CredentialTypesAPI.read.mockRejectedValue(new Error());
history = createMemoryHistory({ initialEntries: ['/credentials'] });
await act(async () => {
wrapper = mountWithContexts(<CredentialAdd />, {
context: { router: { history } },
});
});
wrapper.update();
expect(wrapper.find('ContentError').length).toBe(1);
wrapper.unmount();
});
});
});

View File

@ -6,7 +6,11 @@ import {
waitForElement,
} from '../../../../testUtils/enzymeHelpers';
import { CredentialsAPI, CredentialTypesAPI } from '../../../api';
import {
CredentialsAPI,
CredentialInputSourcesAPI,
CredentialTypesAPI,
} from '../../../api';
import CredentialEdit from './CredentialEdit';
jest.mock('../../../api');
@ -107,58 +111,6 @@ const mockCredential = {
CredentialTypesAPI.read.mockResolvedValue({
data: {
results: [
{
id: 2,
type: 'credential_type',
url: '/api/v2/credential_types/2/',
related: {
credentials: '/api/v2/credential_types/2/credentials/',
activity_stream: '/api/v2/credential_types/2/activity_stream/',
},
summary_fields: {
user_capabilities: {
edit: false,
delete: false,
},
},
created: '2020-02-12T19:42:43.551238Z',
modified: '2020-02-12T19:43:03.164800Z',
name: 'Source Control',
description: '',
kind: 'scm',
namespace: 'scm',
managed_by_tower: true,
inputs: {
fields: [
{
id: 'username',
label: 'Username',
type: 'string',
},
{
id: 'password',
label: 'Password',
type: 'string',
secret: true,
},
{
id: 'ssh_key_data',
label: 'Source Control Private Key',
type: 'string',
format: 'ssh_private_key',
secret: true,
multiline: true,
},
{
id: 'ssh_key_unlock',
label: 'Private Key Passphrase',
type: 'string',
secret: true,
},
],
},
injectors: {},
},
{
id: 1,
type: 'credential_type',
@ -244,69 +196,173 @@ CredentialTypesAPI.read.mockResolvedValue({
});
CredentialsAPI.update.mockResolvedValue({ data: { id: 3 } });
CredentialsAPI.readInputSources.mockResolvedValue({ data: { results: [] } });
CredentialsAPI.readInputSources.mockResolvedValue({
data: {
results: [
{
id: 34,
summary_fields: {
source_credential: {
id: 20,
name: 'CyberArk Conjur Secret Lookup',
description: '',
kind: 'conjur',
cloud: false,
credential_type_id: 20,
},
},
input_field_name: 'password',
metadata: {
secret_path: 'a',
secret_version: 'b',
},
source_credential: 20,
},
{
id: 35,
summary_fields: {
source_credential: {
id: 20,
name: 'CyberArk Conjur Secret Lookup',
description: '',
kind: 'conjur',
cloud: false,
credential_type_id: 20,
},
},
input_field_name: 'become_username',
metadata: {
secret_path: 'foo',
secret_version: 'bar',
},
source_credential: 20,
},
],
},
});
describe('<CredentialEdit />', () => {
let wrapper;
let history;
beforeEach(async () => {
history = createMemoryHistory({ initialEntries: ['/credentials'] });
await act(async () => {
wrapper = mountWithContexts(
<CredentialEdit credential={mockCredential} />,
{
context: { router: { history } },
}
);
describe('Initial GET request succeeds', () => {
beforeEach(async () => {
history = createMemoryHistory({ initialEntries: ['/credentials'] });
await act(async () => {
wrapper = mountWithContexts(
<CredentialEdit credential={mockCredential} />,
{
context: { router: { history } },
}
);
});
});
});
afterEach(() => {
wrapper.unmount();
});
afterEach(() => {
wrapper.unmount();
});
test('initially renders successfully', async () => {
expect(wrapper.find('CredentialEdit').length).toBe(1);
});
test('initially renders successfully', async () => {
expect(wrapper.find('CredentialEdit').length).toBe(1);
});
test('handleCancel returns the user to credential detail', async () => {
await waitForElement(wrapper, 'isLoading', el => el.length === 0);
wrapper.find('Button[aria-label="Cancel"]').simulate('click');
expect(history.location.pathname).toEqual('/credentials/3/details');
});
test('handleCancel returns the user to credential detail', async () => {
await waitForElement(wrapper, 'isLoading', el => el.length === 0);
wrapper.find('Button[aria-label="Cancel"]').simulate('click');
expect(history.location.pathname).toEqual('/credentials/3/details');
});
test('handleSubmit should post to the api', async () => {
await waitForElement(wrapper, 'isLoading', el => el.length === 0);
await act(async () => {
wrapper.find('CredentialForm').prop('onSubmit')({
test('handleSubmit should post to the api', async () => {
await waitForElement(wrapper, 'isLoading', el => el.length === 0);
await act(async () => {
wrapper.find('CredentialForm').prop('onSubmit')({
user: 1,
organization: null,
name: 'foo',
description: 'bar',
credential_type: '1',
inputs: {
username: {
credential: {
id: 1,
name: 'Some cred',
},
inputs: {
foo: 'bar',
},
},
password: 'foo',
ssh_key_data: 'bar',
ssh_public_key_data: 'baz',
ssh_key_unlock: 'foobar',
become_method: '',
become_username: {
credential: {
id: 1,
name: 'Some cred',
},
inputs: {
secret_path: '/foo/bar',
secret_version: '9000',
},
touched: true,
},
become_password: '',
},
passwordPrompts: {
become_password: true,
},
});
});
expect(CredentialsAPI.update).toHaveBeenCalledWith(3, {
user: 1,
organization: null,
name: 'foo',
description: 'bar',
credential_type: '2',
credential_type: '1',
inputs: {
username: '',
password: '',
ssh_key_data: '',
ssh_key_unlock: '',
password: 'foo',
ssh_key_data: 'bar',
ssh_public_key_data: 'baz',
ssh_key_unlock: 'foobar',
become_method: '',
become_password: 'ASK',
},
passwordPrompts: {},
});
expect(CredentialInputSourcesAPI.create).toHaveBeenCalledWith({
input_field_name: 'username',
metadata: {
foo: 'bar',
},
source_credential: 1,
target_credential: 3,
});
expect(CredentialInputSourcesAPI.update).toHaveBeenCalledWith(35, {
metadata: {
secret_path: '/foo/bar',
secret_version: '9000',
},
source_credential: 1,
});
expect(CredentialInputSourcesAPI.destroy).toHaveBeenCalledWith(34);
expect(history.location.pathname).toBe('/credentials/3/details');
});
expect(CredentialsAPI.update).toHaveBeenCalledWith(3, {
user: 1,
organization: null,
name: 'foo',
description: 'bar',
credential_type: '2',
inputs: {
username: '',
password: '',
ssh_key_data: '',
ssh_key_unlock: '',
},
});
describe('Initial GET request fails', () => {
test('shows error when initial GET request fails', async () => {
CredentialTypesAPI.read.mockRejectedValue(new Error());
history = createMemoryHistory({ initialEntries: ['/credentials'] });
await act(async () => {
wrapper = mountWithContexts(
<CredentialEdit credential={mockCredential} />,
{
context: { router: { history } },
}
);
});
wrapper.update();
expect(wrapper.find('ContentError').length).toBe(1);
wrapper.unmount();
});
expect(history.location.pathname).toBe('/credentials/3/details');
});
});