Skip to content

Commit

Permalink
Merge pull request #213 from reportportal/feature/update-work-with-axios
Browse files Browse the repository at this point in the history
Keep axios instance between requests. Update work with headers
  • Loading branch information
AmsterGet authored Sep 17, 2024
2 parents 72695fb + efc9462 commit 4070b07
Show file tree
Hide file tree
Showing 18 changed files with 195 additions and 191 deletions.
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
node_modules
build
spec/**/*.json
__tests__/**/*.json
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
### Changed
- **Breaking change** Drop support of Node.js 12. The version [5.1.4](https://github.com/reportportal/client-javascript/releases/tag/v5.1.4) is the latest that supports it.
- The client now creates an instance of the `axios` HTTP client in the constructor.
- The `HOST` HTTP header is added to all requests as it was skipped by the HTTP client.
### Fixed
- Proxy support on HTTPS requests. Resolves [#30](https://github.com/reportportal/client-javascript/issues/30), related to [axios#4531](https://github.com/axios/axios/issues/4531).
- Allow using `restClientConfig` in `checkConnect()` method. Thanks to [stevez](https://github.com/stevez).
### Security
- Updated versions of vulnerable packages (braces).
Expand Down
File renamed without changes.
File renamed without changes.
29 changes: 0 additions & 29 deletions spec/helpers.spec.js → __tests__/helpers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ const os = require('os');
const fs = require('fs');
const glob = require('glob');
const helpers = require('../lib/helpers');
const RestClient = require('../lib/rest');
const pjson = require('../package.json');

describe('Helpers', () => {
Expand All @@ -27,34 +26,6 @@ describe('Helpers', () => {
});
});

describe('getServerResults', () => {
it('calls RestClient#request', () => {
jest.spyOn(RestClient, 'request').mockImplementation();

helpers.getServerResult(
'http://localhost:80/api/v1',
{ userId: 1 },
{
headers: {
'X-Custom-Header': 'WOW',
},
},
'POST',
);

expect(RestClient.request).toHaveBeenCalledWith(
'POST',
'http://localhost:80/api/v1',
{ userId: 1 },
{
headers: {
'X-Custom-Header': 'WOW',
},
},
);
});
});

describe('readLaunchesFromFile', () => {
it('should return the right ids', () => {
jest.spyOn(glob, 'sync').mockReturnValue(['rplaunch-fileOne.tmp', 'rplaunch-fileTwo.tmp']);
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const process = require('process');
const RPClient = require('../lib/report-portal-client');
const RestClient = require('../lib/rest');
const helpers = require('../lib/helpers');
const { OUTPUT_TYPES } = require('../lib/constants/outputs');

Expand Down Expand Up @@ -134,41 +133,12 @@ describe('ReportPortal javascript client', () => {
project: 'test',
endpoint: 'https://abc.com',
});
jest.spyOn(RestClient, 'request').mockReturnValue(Promise.resolve('ok'));
jest.spyOn(client.restClient, 'request').mockReturnValue(Promise.resolve('ok'));

const request = client.checkConnect();

return expect(request).resolves.toBeDefined();
});

it('client should include restClientConfig', () => {
const client = new RPClient({
apiKey: 'test',
project: 'test',
endpoint: 'https://abc.com/v1',
restClientConfig: {
proxy: false,
timeout: 0,
},
});
jest.spyOn(RestClient, 'request').mockImplementation();

client.checkConnect();

expect(RestClient.request).toHaveBeenCalledWith(
'GET',
'https://abc.com/v1/user',
{},
{
headers: {
'User-Agent': 'NodeJS',
Authorization: `bearer test`,
},
proxy: false,
timeout: 0,
},
);
});
});

describe('triggerAnalyticsEvent', () => {
Expand Down Expand Up @@ -278,15 +248,11 @@ describe('ReportPortal javascript client', () => {
startTime: time,
});

expect(client.restClient.create).toHaveBeenCalledWith(
'launch',
{
name: 'Test launch name',
startTime: time,
attributes: fakeSystemAttr,
},
{ headers: client.headers },
);
expect(client.restClient.create).toHaveBeenCalledWith('launch', {
name: 'Test launch name',
startTime: time,
attributes: fakeSystemAttr,
});
});

it('should call restClient with suitable parameters, attributes is concatenated', () => {
Expand All @@ -312,22 +278,18 @@ describe('ReportPortal javascript client', () => {
attributes: [{ value: 'value' }],
});

expect(client.restClient.create).toHaveBeenCalledWith(
'launch',
{
name: 'Test launch name',
startTime: time,
attributes: [
{ value: 'value' },
{
key: 'client',
value: 'client-name|1.0',
system: true,
},
],
},
{ headers: client.headers },
);
expect(client.restClient.create).toHaveBeenCalledWith('launch', {
name: 'Test launch name',
startTime: time,
attributes: [
{ value: 'value' },
{
key: 'client',
value: 'client-name|1.0',
system: true,
},
],
});
});

it('dont start new launch if launchDataRQ.id is not empty', () => {
Expand Down Expand Up @@ -599,9 +561,7 @@ describe('ReportPortal javascript client', () => {

expect(promise.then).toBeDefined();
await promise;
expect(client.restClient.create).toHaveBeenCalledWith('launch/merge', fakeMergeDataRQ, {
headers: client.headers,
});
expect(client.restClient.create).toHaveBeenCalledWith('launch/merge', fakeMergeDataRQ);
});

it('should not call rest client if something went wrong', async () => {
Expand Down
18 changes: 17 additions & 1 deletion spec/rest.spec.js → __tests__/rest.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ const nock = require('nock');
const isEqual = require('lodash/isEqual');
const http = require('http');
const RestClient = require('../lib/rest');
const logger = require('../lib/logger');

describe('RestClient', () => {
const options = {
baseURL: 'http://report-portal-host:8080/api/v1',
headers: {
Authorization: 'bearer 00000000-0000-0000-0000-000000000000',
'User-Agent': 'NodeJS',
Authorization: 'Bearer 00000000-0000-0000-0000-000000000000',
},
restClientConfig: {
agent: {
Expand All @@ -34,6 +35,21 @@ describe('RestClient', () => {
expect(restClient.baseURL).toBe(options.baseURL);
expect(restClient.headers).toEqual(options.headers);
expect(restClient.restClientConfig).toEqual(options.restClientConfig);
expect(restClient.axiosInstance).toBeDefined();
});

it('adds Logger to axios instance if enabled', () => {
const spyLogger = jest.spyOn(logger, 'addLogger').mockReturnValue();
const optionsWithLoggerEnabled = {
...options,
restClientConfig: {
...options.restClientConfig,
debug: true,
},
};
const client = new RestClient(optionsWithLoggerEnabled);

expect(spyLogger).toHaveBeenCalledWith(client.axiosInstance);
});
});

Expand Down
File renamed without changes.
15 changes: 11 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
module.exports = {
moduleFileExtensions: ['js'],
"testMatch": [
"<rootDir>/spec/**/*[sS]pec.js"
],
coverageReporters: ["lcov", "text-summary"],
testRegex: '/__tests__/.*\\.(test|spec).js$',
testEnvironment: 'node',
collectCoverageFrom: ['lib/**/*.js', '!lib/logger.js'],
coverageThreshold: {
global: {
branches: 80,
functions: 75,
lines: 80,
statements: 80,
},
},
bail: false,
};
3 changes: 2 additions & 1 deletion lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ module.exports = {
return new Date().valueOf();
},

// TODO: deprecate and remove
getServerResult(url, request, options, method) {
return RestClient.request(method, url, request, options);
return new RestClient(options).request(method, url, request, options);
},

readLaunchesFromFile() {
Expand Down
41 changes: 41 additions & 0 deletions lib/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const addLogger = (axiosInstance) => {
axiosInstance.interceptors.request.use((config) => {
const startDate = new Date();
// eslint-disable-next-line no-param-reassign
config.startTime = startDate.valueOf();

console.log(`Request method=${config.method} url=${config.url} [${startDate.toISOString()}]`);

return config;
});

axiosInstance.interceptors.response.use(
(response) => {
const date = new Date();
const { status, config } = response;

console.log(
`Response status=${status} url=${config.url} time=${
date.valueOf() - config.startTime
}ms [${date.toISOString()}]`,
);

return response;
},
(error) => {
const date = new Date();
const { response, config } = error;
const status = response ? response.status : null;

console.log(
`Response ${status ? `status=${status}` : `message='${error.message}'`} url=${
config.url
} time=${date.valueOf() - config.startTime}ms [${date.toISOString()}]`,
);

return Promise.reject(error);
},
);
};

module.exports = { addLogger };
34 changes: 14 additions & 20 deletions lib/report-portal-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ class RPClient {
this.baseURL = [this.config.endpoint, this.config.project].join('/');
this.headers = {
'User-Agent': 'NodeJS',
Authorization: `bearer ${this.apiKey}`,
'Content-Type': 'application/json; charset=UTF-8',
Authorization: `Bearer ${this.apiKey}`,
...(this.config.headers || {}),
};
this.helpers = helpers;
Expand Down Expand Up @@ -130,12 +131,7 @@ class RPClient {

checkConnect() {
const url = [this.config.endpoint.replace('/v2', '/v1'), 'user'].join('/');
return RestClient.request(
'GET',
url,
{},
{ headers: this.headers, ...this.restClient.getRestConfig() },
);
return this.restClient.request('GET', url, {});
}

async triggerStatisticsEvent() {
Expand Down Expand Up @@ -206,7 +202,7 @@ class RPClient {
this.map[tempId] = this.getNewItemObj((resolve, reject) => {
const url = 'launch';
this.logDebug(`Start launch with tempId ${tempId}`, launchDataRQ);
this.restClient.create(url, launchData, { headers: this.headers }).then(
this.restClient.create(url, launchData).then(
(response) => {
this.map[tempId].realId = response.id;
this.launchUuid = response.id;
Expand Down Expand Up @@ -265,7 +261,7 @@ class RPClient {
() => {
this.logDebug(`Finish launch with tempId ${launchTempId}`, finishExecutionData);
const url = ['launch', launchObj.realId, 'finish'].join('/');
this.restClient.update(url, finishExecutionData, { headers: this.headers }).then(
this.restClient.update(url, finishExecutionData).then(
(response) => {
this.logDebug(`Success finish launch with tempId ${launchTempId}`, response);
console.log(`\nReportPortal Launch Link: ${response.link}`);
Expand Down Expand Up @@ -337,11 +333,13 @@ class RPClient {
'filter.in.uuid': launchUUIds,
'page.size': launchUUIds.length,
});
const launchSearchUrl = this.config.mode === 'DEBUG' ?
`launch/mode?${params.toString()}` : `launch?${params.toString()}`;
const launchSearchUrl =
this.config.mode === 'DEBUG'
? `launch/mode?${params.toString()}`
: `launch?${params.toString()}`;
this.logDebug(`Find launches with UUIDs to merge: ${launchUUIds}`);
return this.restClient
.retrieveSyncAPI(launchSearchUrl, { headers: this.headers })
.retrieveSyncAPI(launchSearchUrl)
.then(
(response) => {
const launchIds = response.content.map((launch) => launch.id);
Expand All @@ -357,7 +355,7 @@ class RPClient {
const request = this.getMergeLaunchesRequest(launchIds, mergeOptions);
this.logDebug(`Merge launches with ids: ${launchIds}`, request);
const mergeURL = 'launch/merge';
return this.restClient.create(mergeURL, request, { headers: this.headers });
return this.restClient.create(mergeURL, request);
})
.then((response) => {
this.logDebug(`Launches with UUIDs: ${launchUUIds} were successfully merged!`);
Expand Down Expand Up @@ -426,7 +424,7 @@ class RPClient {
() => {
const url = ['launch', launchObj.realId, 'update'].join('/');
this.logDebug(`Update launch with tempId ${launchTempId}`, launchData);
this.restClient.update(url, launchData, { headers: this.headers }).then(
this.restClient.update(url, launchData).then(
(response) => {
this.logDebug(`Launch with tempId ${launchTempId} were successfully updated`, response);
resolvePromise(response);
Expand Down Expand Up @@ -534,7 +532,7 @@ class RPClient {
}
testItemData.launchUuid = realLaunchId;
this.logDebug(`Start test item with tempId ${tempId}`, testItemData);
this.restClient.create(url, testItemData, { headers: this.headers }).then(
this.restClient.create(url, testItemData).then(
(response) => {
this.logDebug(`Success start item with tempId ${tempId}`, response);
this.map[tempId].realId = response.id;
Expand Down Expand Up @@ -721,7 +719,6 @@ class RPClient {
return this.restClient.create(
url,
Object.assign(saveLogRQ, { launchUuid }, isItemUuid && { itemUuid }),
{ headers: this.headers },
);
};
return this.saveLog(itemObj, requestPromise);
Expand Down Expand Up @@ -777,7 +774,6 @@ class RPClient {
return this.restClient
.create(url, this.buildMultiPartStream([saveLogRQ], fileObj, MULTIPART_BOUNDARY), {
headers: {
...this.headers,
'Content-Type': `multipart/form-data; boundary=${MULTIPART_BOUNDARY}`,
},
})
Expand Down Expand Up @@ -840,9 +836,7 @@ class RPClient {
const url = ['item', itemObj.realId].join('/');
this.logDebug(`Finish test item with tempId ${itemTempId}`, itemObj);
this.restClient
.update(url, Object.assign(finishTestItemData, { launchUuid: this.launchUuid }), {
headers: this.headers,
})
.update(url, Object.assign(finishTestItemData, { launchUuid: this.launchUuid }))
.then(
(response) => {
this.logDebug(`Success finish item with tempId ${itemTempId}`, response);
Expand Down
Loading

0 comments on commit 4070b07

Please sign in to comment.