add CredentialTypesAPI.loadAllTypes helper function

This commit is contained in:
Keith Grant 2020-04-02 13:55:30 -07:00
parent 7710ad2e57
commit 0a00a3104a
4 changed files with 102 additions and 40 deletions

View File

@ -5,6 +5,28 @@ class CredentialTypes extends Base {
super(http);
this.baseUrl = '/api/v2/credential_types/';
}
async loadAllTypes(
acceptableKinds = ['machine', 'cloud', 'net', 'ssh', 'vault']
) {
const pageSize = 200;
// The number of credential types a user can have is unlimited. In practice, it is unlikely for
// users to have more than a page at the maximum request size.
const {
data: { next, results },
} = await this.read({ page_size: pageSize });
let nextResults = [];
if (next) {
const { data } = await this.read({
page_size: pageSize,
page: 2,
});
nextResults = data.results;
}
return results
.concat(nextResults)
.filter(type => acceptableKinds.includes(type.kind));
}
}
export default CredentialTypes;

View File

@ -0,0 +1,65 @@
import CredentialTypes from './CredentialTypes';
const typesData = [{ id: 1, kind: 'machine' }, { id: 2, kind: 'cloud' }];
describe('CredentialTypesAPI', () => {
test('should load all types', async () => {
const getPromise = () =>
Promise.resolve({
data: {
results: typesData,
},
});
const mockHttp = { get: jest.fn(getPromise) };
const CredentialTypesAPI = new CredentialTypes(mockHttp);
const types = await CredentialTypesAPI.loadAllTypes();
expect(mockHttp.get).toHaveBeenCalledTimes(1);
expect(mockHttp.get.mock.calls[0]).toEqual([
`/api/v2/credential_types/`,
{ params: { page_size: 200 } },
]);
expect(types).toEqual(typesData);
});
test('should load all types (2 pages)', async () => {
const getPromise = () =>
Promise.resolve({
data: {
results: typesData,
next: 2,
},
});
const mockHttp = { get: jest.fn(getPromise) };
const CredentialTypesAPI = new CredentialTypes(mockHttp);
const types = await CredentialTypesAPI.loadAllTypes();
expect(mockHttp.get).toHaveBeenCalledTimes(2);
expect(mockHttp.get.mock.calls[0]).toEqual([
`/api/v2/credential_types/`,
{ params: { page_size: 200 } },
]);
expect(mockHttp.get.mock.calls[1]).toEqual([
`/api/v2/credential_types/`,
{ params: { page_size: 200, page: 2 } },
]);
expect(types).toHaveLength(4);
});
test('should filter by acceptable kinds', async () => {
const getPromise = () =>
Promise.resolve({
data: {
results: typesData,
},
});
const mockHttp = { get: jest.fn(getPromise) };
const CredentialTypesAPI = new CredentialTypes(mockHttp);
const types = await CredentialTypesAPI.loadAllTypes(['machine']);
expect(types).toEqual([typesData[0]]);
});
});

View File

@ -17,27 +17,6 @@ const QS_CONFIG = getQSConfig('credentials', {
order_by: 'name',
});
async function loadCredentialTypes() {
const pageSize = 200;
const acceptableKinds = ['machine', 'cloud', 'net', 'ssh', 'vault'];
// The number of credential types a user can have is unlimited. In practice, it is unlikely for
// users to have more than a page at the maximum request size.
const {
data: { next, results },
} = await CredentialTypesAPI.read({ page_size: pageSize });
let nextResults = [];
if (next) {
const { data } = await CredentialTypesAPI.read({
page_size: pageSize,
page: 2,
});
nextResults = data.results;
}
return results
.concat(nextResults)
.filter(type => acceptableKinds.includes(type.kind));
}
async function loadCredentials(params, selectedCredentialTypeId) {
params.credential_type = selectedCredentialTypeId || 1;
const { data } = await CredentialsAPI.read(params);
@ -54,7 +33,7 @@ function MultiCredentialsLookup(props) {
useEffect(() => {
(async () => {
try {
const types = await loadCredentialTypes();
const types = await CredentialTypesAPI.loadAllTypes();
setCredentialTypes(types);
const match = types.find(type => type.kind === 'ssh') || types[0];
setSelectedType(match);

View File

@ -18,21 +18,16 @@ describe('<MultiCredentialsLookup />', () => {
];
beforeEach(() => {
CredentialTypesAPI.read.mockResolvedValueOnce({
data: {
results: [
{
id: 400,
kind: 'ssh',
namespace: 'biz',
name: 'Amazon Web Services',
},
{ id: 500, kind: 'vault', namespace: 'buzz', name: 'Vault' },
{ id: 600, kind: 'machine', namespace: 'fuzz', name: 'Machine' },
],
count: 2,
CredentialTypesAPI.loadAllTypes.mockResolvedValueOnce([
{
id: 400,
kind: 'ssh',
namespace: 'biz',
name: 'Amazon Web Services',
},
});
{ id: 500, kind: 'vault', namespace: 'buzz', name: 'Vault' },
{ id: 600, kind: 'machine', namespace: 'fuzz', name: 'Machine' },
]);
CredentialsAPI.read.mockResolvedValueOnce({
data: {
results: [
@ -52,7 +47,7 @@ describe('<MultiCredentialsLookup />', () => {
wrapper.unmount();
});
test('MultiCredentialsLookup renders properly', async () => {
test('should load credential types', async () => {
const onChange = jest.fn();
await act(async () => {
wrapper = mountWithContexts(
@ -64,8 +59,9 @@ describe('<MultiCredentialsLookup />', () => {
/>
);
});
wrapper.update();
expect(wrapper.find('MultiCredentialsLookup')).toHaveLength(1);
expect(CredentialTypesAPI.read).toHaveBeenCalled();
expect(CredentialTypesAPI.loadAllTypes).toHaveBeenCalled();
});
test('onChange is called when you click to remove a credential from input', async () => {
@ -118,12 +114,12 @@ describe('<MultiCredentialsLookup />', () => {
count: 1,
},
});
expect(CredentialsAPI.read).toHaveBeenCalledTimes(2);
expect(CredentialsAPI.read).toHaveBeenCalledTimes(1);
await act(async () => {
select.invoke('onChange')({}, 500);
});
wrapper.update();
expect(CredentialsAPI.read).toHaveBeenCalledTimes(3);
expect(CredentialsAPI.read).toHaveBeenCalledTimes(2);
expect(wrapper.find('OptionsList').prop('options')).toEqual([
{ id: 1, kind: 'cloud', name: 'New Cred', url: 'www.google.com' },
]);