Skip to content

Commit 7c2b9d7

Browse files
Merge pull request #3621 from RedisInsight/feature/RI-5932-rdi-support
rework schemas fetching
2 parents 27de4e4 + 3141817 commit 7c2b9d7

File tree

8 files changed

+1474
-58
lines changed

8 files changed

+1474
-58
lines changed

redisinsight/api/src/__mocks__/rdi.ts

Lines changed: 1439 additions & 0 deletions
Large diffs are not rendered by default.

redisinsight/api/src/modules/rdi/client/api.rdi.client.spec.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import axios, { AxiosError } from 'axios';
22
import {
3-
mockRdi, mockRdiClientMetadata, mockRdiDryRunJob, mockRdiPipeline, mockRdiStatisticsData,
3+
mockRdi,
4+
mockRdiClientMetadata,
5+
mockRdiConfigSchema,
6+
mockRdiDryRunJob, mockRdiJobsSchema,
7+
mockRdiPipeline,
8+
mockRdiSchema,
9+
mockRdiStatisticsData,
410
} from 'src/__mocks__';
511
import errorMessages from 'src/constants/error-messages';
612
import { sign } from 'jsonwebtoken';
@@ -17,18 +23,20 @@ describe('ApiRdiClient', () => {
1723
let client: ApiRdiClient;
1824

1925
beforeEach(() => {
26+
jest.clearAllMocks();
2027
client = new ApiRdiClient(mockRdiClientMetadata, mockRdi);
2128
});
2229

2330
describe('getSchema', () => {
2431
it('should return schema', async () => {
25-
const data = { schema: {} };
26-
mockedAxios.get.mockResolvedValueOnce({ data });
32+
mockedAxios.get.mockResolvedValueOnce({ data: mockRdiConfigSchema });
33+
mockedAxios.get.mockResolvedValueOnce({ data: mockRdiJobsSchema });
2734

2835
const result = await client.getSchema();
2936

30-
expect(result).toEqual(data);
31-
expect(mockedAxios.get).toHaveBeenCalledWith(RdiUrl.GetSchema);
37+
expect(result).toEqual(mockRdiSchema);
38+
expect(mockedAxios.get).toHaveBeenCalledWith(RdiUrl.GetConfigSchema);
39+
expect(mockedAxios.get).toHaveBeenCalledWith(RdiUrl.GetJobsSchema);
3240
});
3341

3442
it('should throw error if request fails', async () => {
@@ -38,6 +46,8 @@ describe('ApiRdiClient', () => {
3846
status: 401,
3947
},
4048
};
49+
50+
mockedAxios.get.mockResolvedValueOnce({ data: mockRdiConfigSchema });
4151
mockedAxios.get.mockRejectedValueOnce(error);
4252

4353
await expect(client.getSchema()).rejects.toThrow(errorMessages.UNAUTHORIZED);

redisinsight/api/src/modules/rdi/client/api.rdi.client.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,15 @@ export class ApiRdiClient extends RdiClient {
5252

5353
async getSchema(): Promise<object> {
5454
try {
55-
const response = await this.client.get(RdiUrl.GetSchema);
56-
return response.data;
55+
const [config, jobs] = await Promise.all([
56+
this.client.get(RdiUrl.GetConfigSchema).then(({ data }) => data),
57+
this.client.get(RdiUrl.GetJobsSchema).then(({ data }) => data),
58+
]);
59+
60+
return {
61+
config,
62+
jobs,
63+
};
5764
} catch (e) {
5865
throw wrapRdiPipelineError(e);
5966
}

redisinsight/api/src/modules/rdi/constants/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export enum RdiUrl {
2-
GetSchema = 'api/v1/schemas',
2+
GetConfigSchema = 'api/v1/pipelines/config/schemas',
3+
GetJobsSchema = 'api/v1/pipelines/jobs/schemas',
34
GetPipeline = 'api/v1/pipelines',
45
GetStrategies = 'api/v1/pipelines/strategies',
56
GetConfigTemplate = 'api/v1/pipelines/config/templates',

redisinsight/api/src/modules/rdi/exceptions/rdi-pipiline.error.handler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ export const wrapRdiPipelineError = (error: AxiosError<any>, message?: string):
1919
return new RdiPipelineUnauthorizedException(message, errorOptions);
2020
case 422:
2121
return new RdiPipelineValidationException(message, errorOptions);
22-
default:
22+
case 404:
2323
return new RdiPipelineNotFoundException(message, errorOptions);
24+
default:
25+
return new RdiPipelineInternalServerErrorException(message);
2426
}
2527
}
2628

redisinsight/api/test/api/rdi/pipeline/GET-rdi-id-pipeline-schema.test.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { nock } from '../../../helpers/test';
44
import {
55
describe, expect, deps, getMainCheckFn,
66
} from '../../deps';
7+
import { mockRdiConfigSchema, mockRdiJobsSchema, mockRdiSchema } from 'src/__mocks__';
78

89
const {
910
localDb, request, server, constants,
@@ -16,27 +17,23 @@ const mockedAccessToken = sign({ exp: Math.trunc(Date.now() / 1000) + 3600 }, 't
1617

1718
const endpoint = (id: string) => request(server).get(`/${constants.API.RDI}/${id || testRdiId}/pipeline/schema`);
1819

19-
const mockResponseSuccess = {
20-
schema: { },
21-
};
22-
2320
const mainCheckFn = getMainCheckFn(endpoint);
2421

2522
describe('GET /rdi/:id/pipeline/schema', () => {
2623
[
2724
{
2825
name: 'Should be success if rdi with :id is in db',
29-
// responseSchema,
3026
statusCode: 200,
3127
checkFn: ({ body }) => {
32-
expect(body).to.eql(mockResponseSuccess);
28+
expect(body).to.eql(mockRdiSchema);
3329
},
3430
before: async () => {
3531
await localDb.generateRdis({ id: testRdiId, url: testRdiUrl }, 1);
3632
nock(testRdiUrl).post(`/${RdiUrl.Login}`).query(true).reply(200, {
3733
access_token: mockedAccessToken,
3834
});
39-
nock(testRdiUrl).get(`/${RdiUrl.GetSchema}`).query(true).reply(200, mockResponseSuccess);
35+
nock(testRdiUrl).get(`/${RdiUrl.GetConfigSchema}`).query(true).reply(200, mockRdiConfigSchema);
36+
nock(testRdiUrl).get(`/${RdiUrl.GetJobsSchema}`).query(true).reply(200, mockRdiJobsSchema);
4037
},
4138
},
4239
{
@@ -56,7 +53,6 @@ describe('GET /rdi/:id/pipeline/schema', () => {
5653
},
5754
{
5855
name: 'Should throw error if client getSchema will not succeed',
59-
// responseSchema,
6056
statusCode: 401,
6157
checkFn: ({ body }) => {
6258
expect(body).to.eql({
@@ -71,7 +67,8 @@ describe('GET /rdi/:id/pipeline/schema', () => {
7167
nock(testRdiUrl).post(`/${RdiUrl.Login}`).query(true).reply(200, {
7268
access_token: mockedAccessToken,
7369
});
74-
nock(testRdiUrl).get(`/${RdiUrl.GetSchema}`).query(true).reply(401, {
70+
nock(testRdiUrl).get(`/${RdiUrl.GetConfigSchema}`).query(true).reply(200, mockRdiConfigSchema);
71+
nock(testRdiUrl).get(`/${RdiUrl.GetJobsSchema}`).query(true).reply(401, {
7572
message: 'Request failed with status code 401',
7673
});
7774
},

redisinsight/ui/src/pages/rdi/home/connection-form/ConnectionForm.spec.tsx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,6 @@ describe('ConnectionForm', () => {
7272
expect(screen.getByTestId('connection-form-url-input')).toBeDisabled()
7373
})
7474

75-
it('should show url tooltip when url input is not disabled', async () => {
76-
render(<ConnectionForm {...mockedProps} />)
77-
78-
fireEvent.mouseOver(screen.getByTestId('connection-form-url-icon'))
79-
80-
const tooltip = await screen.findByTestId('connection-form-url-tooltip')
81-
82-
expect(tooltip).toBeInTheDocument()
83-
})
84-
8575
it('should show validation tooltip when submit button is disabled', async () => {
8676
render(<ConnectionForm {...mockedProps} />)
8777

redisinsight/ui/src/pages/rdi/home/connection-form/ConnectionForm.tsx

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ import {
66
EuiFlexItem,
77
EuiForm,
88
EuiFormRow,
9-
EuiIcon,
109
EuiTitle,
11-
EuiToolTip
1210
} from '@elastic/eui'
1311
import { Field, FieldInputProps, FieldMetaProps, Form, Formik, FormikErrors, FormikHelpers } from 'formik'
1412
import React, { useEffect, useState } from 'react'
@@ -43,33 +41,6 @@ const getInitialValues = (values: RdiInstance | null): ConnectionFormValues => (
4341
password: values ? null : ''
4442
})
4543

46-
const UrlTooltip = () => (
47-
<EuiToolTip
48-
data-testid="connection-form-url-tooltip"
49-
title={(
50-
<div>
51-
<p>
52-
<b>Pasting a connection URL auto fills the instance details.</b>
53-
</p>
54-
<p style={{ margin: 0, paddingTop: '10px' }}>The following connection URLs are supported:</p>
55-
</div>
56-
)}
57-
className={styles.urlTooltip}
58-
anchorClassName="inputAppendIcon"
59-
position="right"
60-
content={(
61-
<ul>
62-
<li>
63-
<span />
64-
TBD
65-
</li>
66-
</ul>
67-
)}
68-
>
69-
<EuiIcon data-testid="connection-form-url-icon" type="iInCircle" style={{ cursor: 'pointer' }} />
70-
</EuiToolTip>
71-
)
72-
7344
const ConnectionForm = (props: Props) => {
7445
const { onSubmit, onCancel, editInstance, isLoading } = props
7546

@@ -140,7 +111,6 @@ const ConnectionForm = (props: Props) => {
140111
fullWidth
141112
placeholder="Enter URL"
142113
disabled={!!editInstance}
143-
append={!editInstance ? <UrlTooltip /> : undefined}
144114
{...field}
145115
/>
146116
)}

0 commit comments

Comments
 (0)