Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export class ApiRdiClient extends RdiClient {

return await this.pollActionStatus(actionId);
} catch (error) {
throw wrapRdiPipelineError(error, error.response.data.message);
throw wrapRdiPipelineError(error, error?.response?.data?.message);
}
}

Expand Down
8 changes: 4 additions & 4 deletions redisinsight/api/src/modules/rdi/rdi-pipeline.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
ClassSerializerInterceptor, Controller, Get, Post, UseInterceptors, UsePipes, ValidationPipe,
Param,
} from '@nestjs/common';
import { Rdi, RdiPipeline, RdiClientMetadata } from 'src/modules/rdi/models';
import { RdiPipeline, RdiClientMetadata } from 'src/modules/rdi/models';
import { ApiTags } from '@nestjs/swagger';
import { ApiEndpoint } from 'src/decorators/api-endpoint.decorator';
import { RdiPipelineService } from 'src/modules/rdi/rdi-pipeline.service';
Expand All @@ -23,7 +23,7 @@ export class RdiPipelineController {
@Get('/schema')
@ApiEndpoint({
description: 'Get pipeline schema',
responses: [{ status: 200, type: Rdi }],
responses: [{ status: 200, type: Object }],
})
async getSchema(
@RequestRdiClientMetadata() rdiClientMetadata: RdiClientMetadata,
Expand Down Expand Up @@ -57,7 +57,7 @@ export class RdiPipelineController {
@Post('/deploy')
@ApiEndpoint({
description: 'Deploy the pipeline',
responses: [{ status: 200, type: RdiPipeline }],
responses: [{ status: 200 }],
})
async deploy(
@RequestRdiClientMetadata() rdiClientMetadata: RdiClientMetadata,
Expand All @@ -81,7 +81,7 @@ export class RdiPipelineController {
@Get('/strategies')
@ApiEndpoint({
description: 'Get pipeline strategies and db types for template',
responses: [{ status: 200, type: Rdi }],
responses: [{ status: 200, type: Object }],
})
async getStrategies(
@RequestRdiClientMetadata() rdiClientMetadata: RdiClientMetadata,
Expand Down
2 changes: 1 addition & 1 deletion redisinsight/api/src/modules/rdi/rdi.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('RdiService', () => {
it('should throw an error if Rdi instance is not found', async () => {
repository.get.mockResolvedValue(undefined);

await expect(service.get('123')).rejects.toThrowError('TBD not found');
await expect(service.get('123')).rejects.toThrowError('RDI with id 123 was not found');
});
});

Expand Down
4 changes: 2 additions & 2 deletions redisinsight/api/src/modules/rdi/rdi.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { classToClass } from 'src/utils';
import { RdiClientProvider } from 'src/modules/rdi/providers/rdi.client.provider';
import { RdiClientFactory } from 'src/modules/rdi/providers/rdi.client.factory';
import { SessionMetadata } from 'src/common/models';
import { wrapRdiPipelineError } from 'src/modules/rdi/exceptions';
import { RdiPipelineNotFoundException, wrapRdiPipelineError } from 'src/modules/rdi/exceptions';
import { isUndefined, omitBy } from 'lodash';
import { deepMerge } from 'src/common/utils';
import { RdiAnalytics } from './rdi.analytics';
Expand Down Expand Up @@ -45,7 +45,7 @@ export class RdiService {
const rdi = await this.repository.get(id);

if (!rdi) {
throw new Error('TBD not found');
throw new RdiPipelineNotFoundException(`RDI with id ${id} was not found`);
}

return rdi;
Expand Down
55 changes: 55 additions & 0 deletions redisinsight/api/test/api/rdi/DELETE-rdi.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
describe, expect, deps, getMainCheckFn,
} from '../deps';

const {
localDb, request, server, constants,
} = deps;

const testRdiId = 'someTestId';
const testRdiId2 = 'someTestId_2';

const endpoint = () => request(server).delete(`/${constants.API.RDI}/`);

const validInputData = {
ids: [testRdiId, testRdiId2],
};

const mainCheckFn = getMainCheckFn(endpoint);

describe('DELETE /rdi', () => {
describe('Common', () => {
[
{
name: 'Should throw error if ids are empty',
data: { ids: [] },
statusCode: 500,
},
{
name: 'Should delete multiple rdis by ids',
data: validInputData,
statusCode: 200,
before: async () => {
await localDb.generateRdis({ id: testRdiId }, 1);
await localDb.generateRdis({ id: testRdiId2 }, 1);
const rdi1 = await localDb.getRdiById(testRdiId);
const rdi2 = await localDb.getRdiById(testRdiId2);
expect(rdi1.id).to.eql(testRdiId);
expect(rdi2.id).to.eql(testRdiId2);
},
after: async () => {
expect(await localDb.getRdiById(testRdiId)).to.eql(null);
expect(await localDb.getRdiById(testRdiId2)).to.eql(null);
},
},
{
name: 'Should not throw error even if id does not exist',
data: { ids: ['Not_existed'] },
statusCode: 200,
before: async () => {
expect(await localDb.getRdiById('Not_existed')).to.eql(null);
},
},
].forEach(mainCheckFn);
});
});
43 changes: 43 additions & 0 deletions redisinsight/api/test/api/rdi/GET-rdi-id-connect.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { RdiUrl } from 'src/modules/rdi/constants';
import { sign } from 'jsonwebtoken';
import {
describe, expect, deps, getMainCheckFn,
} from '../deps';
import { nock } from '../../helpers/test';

const {
localDb, request, server, constants,
} = deps;

const testRdiId = 'someTEST';
const notExistedRdiId = 'notExisted';
const testRdiUrl = 'http://rdilocal.test';

const endpoint = (id) => request(server).get(`/${constants.API.RDI}/${id || testRdiId}/connect`);

const mockedAccessToken = sign({ exp: Math.trunc(Date.now() / 1000) + 3600 }, 'test');

const mainCheckFn = getMainCheckFn(endpoint);

describe('GET /rdi/:id/connect', () => {
[
{
name: 'Should be success if rdi with :id is in db',
statusCode: 200,
before: async () => {
await localDb.generateRdis({ id: testRdiId, url: testRdiUrl }, 1);
nock(testRdiUrl).post(`/${RdiUrl.Login}`).query(true).reply(200, {
access_token: mockedAccessToken,
});
},
},
{
name: 'Should throw notFoundError if rdi with id in params does not exist',
endpoint: () => endpoint(notExistedRdiId),
statusCode: 404,
before: async () => {
expect(await localDb.getRdiById(notExistedRdiId)).to.eql(null);
},
},
].forEach(mainCheckFn);
});
58 changes: 58 additions & 0 deletions redisinsight/api/test/api/rdi/GET-rdi-id.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { v4 as uuidv4 } from 'uuid';
import {
describe, expect, deps, getMainCheckFn,
} from '../deps';
import { Joi } from '../../helpers/test';

const {
localDb, request, server, constants,
} = deps;

const testRdiId = uuidv4();
const notExistedRdiId = 'not-existed-rdi-id';

const endpoint = (rdiId) => request(server).get(`/${constants.API.RDI}/${rdiId || testRdiId}`);

const responseSchema = Joi.object().keys({
id: Joi.string().required(),
url: Joi.string().required(),
name: Joi.string().max(500).required(),
username: Joi.string().required(),
password: Joi.string().required(),
lastConnection: Joi.string().isoDate().required(),
version: Joi.string().required(),
}).required().strict(true);

const mainCheckFn = getMainCheckFn(endpoint);

describe('GET /rdi/:id', () => {
[
{
name: 'Should return rdi data by id',
responseSchema,
statusCode: 200,
checkFn: ({ body }) => {
expect(body.id).to.eql(testRdiId);
},
before: async () => {
await localDb.generateRdis({ id: testRdiId }, 1);
},
},
{
name: 'Should throw error if no rdi found in a db',
statusCode: 404,
endpoint: () => endpoint(notExistedRdiId),
checkFn: ({ body }) => {
expect(body).to.eql({
message: `RDI with id ${notExistedRdiId} was not found`,
statusCode: 404,
error: 'RdiNotFound',
errorCode: 11405,
});
},
before: async () => {
await (await localDb.getRepository(localDb.repositories.RDI)).clear();
},
},
].forEach(mainCheckFn);
});
49 changes: 49 additions & 0 deletions redisinsight/api/test/api/rdi/GET-rdi.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {
describe, expect, deps, getMainCheckFn,
} from '../deps';
import { Joi } from '../../helpers/test';

const {
localDb, request, server, constants,
} = deps;

const endpoint = () => request(server).get(`/${constants.API.RDI}`);

const responseSchema = Joi.array().items(Joi.object().keys({
id: Joi.string().required(),
url: Joi.string().required(),
name: Joi.string().max(500).required(),
username: Joi.string().required(),
lastConnection: Joi.string().isoDate().required(),
version: Joi.string().required(),
})).required().strict(true);

const mainCheckFn = getMainCheckFn(endpoint);

describe('GET /rdi', () => {
[
{
name: 'Should return empty array if no rdis yet',
responseSchema,
checkFn: ({ body }) => {
expect(body).to.eql([]);
},
before: async () => {
await (await localDb.getRepository(localDb.repositories.RDI)).clear();
await request(server).get('/rdi');
},
},
{
name: 'Should get rdis list',
responseSchema,
before: async () => {
await localDb.generateRdis({}, 2);
await request(server).get('/rdi');
},
checkFn: ({ body }) => {
expect(body.length).to.eql(2);
expect(body[0].name).to.eql('Rdi');
},
},
].forEach(mainCheckFn);
});
104 changes: 104 additions & 0 deletions redisinsight/api/test/api/rdi/PATCH-rdi-id.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { RdiUrl } from 'src/modules/rdi/constants';
import { sign } from 'jsonwebtoken';
import {
describe, expect, deps, getMainCheckFn, generateInvalidDataTestCases,
validateInvalidDataTestCase,
} from '../deps';
import { Joi, nock } from '../../helpers/test';

const {
localDb, request, server, constants,
} = deps;

const testRdiId = 'someTestId';
const testRdiUrl = 'http://rdilocal.test';
const testRdiName = 'Test Rdi Name';
const testRdiBase = { id: testRdiId, name: testRdiName, url: testRdiUrl };

const endpoint = (id) => request(server).patch(`/${constants.API.RDI}/${id || testRdiId}`);

const dataSchema = Joi.object().keys({
name: Joi.string().max(500).allow(null),
username: Joi.string().allow(null),
password: Joi.string().allow(null),
}).messages({ 'any.required': '{#label} should not be empty' }).strict(true);

const validInputData = {
name: 'Updated Rdi',
username: 'rdiUsername Updated',
password: constants.TEST_KEYTAR_PASSWORD,
};

const responseSchema = Joi.object().keys({
id: Joi.string().required(),
url: Joi.string().required(),
name: Joi.string().max(500).required(),
username: Joi.string().required(),
password: Joi.string().required(),
lastConnection: Joi.string().isoDate().required(),
version: Joi.string().required(),
}).required().strict(true);

const mockedAccessToken = sign({ exp: Math.trunc(Date.now() / 1000) + 3600 }, 'test');

const mainCheckFn = getMainCheckFn(endpoint);

describe('PATCH /rdi/:id', () => {
describe('Validation', () => {
generateInvalidDataTestCases(dataSchema, validInputData).forEach(
validateInvalidDataTestCase(endpoint, dataSchema),
);
});
describe('Common', () => {
[
{
name: 'Should update rdi name',
responseSchema,
data: { name: validInputData.name },
statusCode: 200,
checkFn: ({ body }) => {
expect(body.name).to.eql(validInputData.name);
expect(body.id).to.eql(testRdiId);
},
before: async () => {
await localDb.generateRdis(testRdiBase, 1);
nock(testRdiUrl).post(`/${RdiUrl.Login}`).query(true).reply(200, {
access_token: mockedAccessToken,
});
},
},
{
name: 'Should update rdi username',
responseSchema,
data: { username: validInputData.username },
statusCode: 200,
checkFn: ({ body }) => {
expect(body.name).to.eql(testRdiName);
expect(body.username).to.eql(validInputData.username);
},
before: async () => {
await localDb.generateRdis(testRdiBase, 1);
nock(testRdiUrl).post(`/${RdiUrl.Login}`).query(true).reply(200, {
access_token: mockedAccessToken,
});
},
},
{
name: 'Should throw error if rdiClient was not connected',
statusCode: 401,
data: validInputData,
before: () => {
nock(testRdiUrl).post(`/${RdiUrl.Login}`).query(true).reply(401, {
message: 'Unauthorized',
});
},
responseBody: {
message: 'Authorization failed',
statusCode: 401,
error: 'RdiUnauthorized',
errorCode: 11402,
},
},
].forEach(mainCheckFn);
});
});
Loading