Skip to content

Commit

Permalink
Merge pull request #159 from AElfProject/feature/node-fetch-test
Browse files Browse the repository at this point in the history
feat: 🎸 node, use node-fetch instead of xmlhttprequest
  • Loading branch information
hzz780 authored Jun 21, 2024
2 parents 68d67e3 + 70c07fa commit 645250e
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 33 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

| Statements | Branches | Functions | Lines |
| --------------------------- | ----------------------- | ------------------------- | ----------------- |
| ![Statements](https://img.shields.io/badge/statements-96.18%25-brightgreen.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-93.46%25-brightgreen.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-96.71%25-brightgreen.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-96.34%25-brightgreen.svg?style=flat) |
| ![Statements](https://img.shields.io/badge/statements-50%25-red.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-36.91%25-red.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-46%25-red.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-51.31%25-red.svg?style=flat) |


## 1. Introduction
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"isomorphic-fetch": "^3.0.0",
"js-sha256": "^0.9.0",
"keccak": "^3.0.3",
"node-fetch": "2",
"query-string": "^7.1.3",
"randombytes": "^2.1.0",
"readable-stream": "^4.3.0",
Expand Down
25 changes: 21 additions & 4 deletions src/util/httpProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const defaultHeaders = {
};

let RequestLibrary = {};
let RequestLibraryXMLOnly = null;
let isFetch = false;
if (process.env.RUNTIME_ENV === 'browser') {
// For browsers use DOM Api XMLHttpRequest
Expand All @@ -27,18 +28,24 @@ if (process.env.RUNTIME_ENV === 'browser') {
} else {
// For node use xmlhttprequest
// eslint-disable-next-line global-require
RequestLibrary = require('xmlhttprequest').XMLHttpRequest;
RequestLibraryXMLOnly = require('xmlhttprequest').XMLHttpRequest;
// eslint-disable-next-line global-require
RequestLibrary = require('node-fetch');
isFetch = true;
}

export default class HttpProvider {
constructor(
host = 'http://localhost:8545',
timeout = 8000,
headers = defaultHeaders
headers = defaultHeaders,
// support node-fetch options
options = {}
) {
this.host = host.replace(/\/$/, '');
this.timeout = timeout;
this.headers = {};
this.options = options;
if (Array.isArray(headers)) {
headers.forEach(({ name, value }) => {
this.headers[name] = value;
Expand Down Expand Up @@ -112,6 +119,7 @@ export default class HttpProvider {
myHeaders.append(header, this.headers[header]);
});
return request(uri, {
...this.options,
method: method.toUpperCase(),
headers: myHeaders,
body,
Expand Down Expand Up @@ -179,8 +187,17 @@ export default class HttpProvider {
}

send(requestConfig) {
if (isFetch) throw new Error("Can not get XMLHttpRequest, invalid parameter: 'sync'");
const request = new RequestLibrary();
let request;
if (isFetch) {
if (!RequestLibraryXMLOnly) {
// browser case, Chrome extension v3.
throw new Error("Can not get XMLHttpRequest, invalid parameter: 'sync'");
} else {
request = new RequestLibraryXMLOnly();
}
} else {
request = new RequestLibrary();
}
request.withCredentials = false;
this.requestSend(requestConfig, request);
let result = request.responseText;
Expand Down
4 changes: 2 additions & 2 deletions test/unit/util/httpProvider.browser-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ describe('test httpProvider', () => {
fetch
);
const result = await response.text();
expect(JSON.parse(result)).toEqual({
expect(JSON.parse(result)).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
Expand Down Expand Up @@ -401,7 +401,7 @@ describe('test httpProvider', () => {
request
);
const result = request.responseText;
expect(JSON.parse(result)).toEqual({
expect(JSON.parse(result)).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
Expand Down
27 changes: 27 additions & 0 deletions test/unit/util/httpProvider.data.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

139 changes: 139 additions & 0 deletions test/unit/util/httpProvider.fetch.node-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import HttpProvider from '../../../src/util/httpProvider';
import http from 'node:http';
import https from 'node:https';
import { blockByHeightRes } from './httpProvider.data';
const fetch = require('node-fetch');
const stageEndpoint = 'https://aelf-public-node.aelf.io/';
// for test timeout
jest.useFakeTimers();
jest.spyOn(global, 'setTimeout');

describe('test httpProvider', () => {
beforeEach(() => {
jest.resetModules();
});

test('test get request send by fetch', async () => {
const httpProvider = new HttpProvider(stageEndpoint);
const response = await httpProvider.requestSendByFetch(
{
url: 'blockChain/blockByHeight',
method: 'GET',
params: {
blockHeight: 136240697,
},
},
fetch
);
const result = await response.text();
expect(JSON.parse(result)).toEqual(blockByHeightRes);
});
test('test get request send by fetch, keepalive', async () => {
const httpAgent = new http.Agent({
keepAlive: true
});
const httpsAgent = new https.Agent({
keepAlive: true
});
const options = {
agent: function(_parsedURL) {
if (_parsedURL.protocol === 'http:') {
return httpAgent;
} else {
return httpsAgent;
}
}
};

const httpProvider = new HttpProvider(stageEndpoint, 8000, {}, options);
const response = await httpProvider.requestSendByFetch(
{
url: 'blockChain/blockByHeight',
method: 'GET',
params: {
blockHeight: 136240697,
},
},
fetch
);
const result = await response.text();
expect(JSON.parse(result)).toEqual(blockByHeightRes);
});
test('test post request send by fetch', async () => {
const httpProvider = new HttpProvider(stageEndpoint);
const response = await httpProvider.requestSendByFetch(
{
url: 'blockChain/calculateTransactionFee',
params: {
RawTransaction:
'0a220a2005c3b3959caeee55b5db4004f6f9d76860aae818ce7b33d210a446ecb275468212220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba18a8a19e022204fa60011c2a085472616e73666572322e0a220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba1203454c461880c2d72f82f10441ad1647aa462a8859c7a699f22d6124c82a5239c90746ac67ebfd8e1a7b4a25f343733351162d205fc881ea62072e9fe0fad5f6113734309b6666f6812d6b7a6400',
},
},
fetch
);
const result = await response.text();
expect(JSON.parse(result)).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
});
test('test send async by fetch', async () => {
const httpProvider = new HttpProvider(stageEndpoint);
const result = await httpProvider.sendAsyncByFetch({
url: 'blockChain/blockByHeight',
method: 'GET',
params: {
blockHeight: 136240697,
},
});
expect(result).toEqual(blockByHeightRes);
});

test('test send async by fetch when error', async () => {
const httpProvider = new HttpProvider(stageEndpoint);
await expect(
httpProvider.sendAsyncByFetch({
url: 'blockChain/executeTransaction',
method: 'POST',
params: {
RawTransaction: '111',
},
})
).rejects.toEqual({
Error: {
Code: '20012',
Message: 'Invalid params',
Details: null,
Data: {},
ValidationErrors: null,
},
});
});

test('test send by fetch', () => {
const httpProvider = new HttpProvider(stageEndpoint);
try {
httpProvider.send({
url: 'blockChain/blockHeight',
method: 'GET',
});
} catch (e) {
expect(e).toEqual(
new Error("Can not get XMLHttpRequest, invalid parameter: 'sync'")
);
}
});

test('test send async by fetch method', async () => {
const httpProvider = new HttpProvider(stageEndpoint);
const result = await httpProvider.sendAsync({
url: 'blockChain/blockByHeight',
method: 'GET',
params: {
blockHeight: 136240697,
},
});
expect(result).toEqual(blockByHeightRes);
});
});
63 changes: 37 additions & 26 deletions test/unit/util/requestManage.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,27 @@ describe('test requestManage', () => {
test('test send with provider', () => {
const httpProvider = new HttpProvider('https://aelf-public-node.aelf.io');
const requestManage = new RequestManager(httpProvider);
const result = requestManage.send({
requestMethod: 'post',
method: 'blockChain/calculateTransactionFee',
params: {
RawTransaction:
'0a220a2005c3b3959caeee55b5db4004f6f9d76860aae818ce7b33d210a446ecb275468212220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba18a8a19e022204fa60011c2a085472616e73666572322e0a220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba1203454c461880c2d72f82f10441ad1647aa462a8859c7a699f22d6124c82a5239c90746ac67ebfd8e1a7b4a25f343733351162d205fc881ea62072e9fe0fad5f6113734309b6666f6812d6b7a6400',
},
});
expect(result).toEqual({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
try {
const result = requestManage.send({
requestMethod: 'post',
method: 'blockChain/calculateTransactionFee',
params: {
RawTransaction:
'0a220a2005c3b3959caeee55b5db4004f6f9d76860aae818ce7b33d210a446ecb275468212220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba18a8a19e022204fa60011c2a085472616e73666572322e0a220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba1203454c461880c2d72f82f10441ad1647aa462a8859c7a699f22d6124c82a5239c90746ac67ebfd8e1a7b4a25f343733351162d205fc881ea62072e9fe0fad5f6113734309b6666f6812d6b7a6400',
},
});
expect(result).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
} catch(error) {
expect(error).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
}
});
test('test send without provider', () => {
const requestManage = new RequestManager();
Expand All @@ -61,19 +69,22 @@ describe('test requestManage', () => {
test('test send async with provider', async () => {
const httpProvider = new HttpProvider('https://aelf-public-node.aelf.io');
const requestManage = new RequestManager(httpProvider);
const result = await requestManage.sendAsync({
requestMethod: 'post',
method: 'blockChain/calculateTransactionFee',
params: {
RawTransaction:
'0a220a2005c3b3959caeee55b5db4004f6f9d76860aae818ce7b33d210a446ecb275468212220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba18a8a19e022204fa60011c2a085472616e73666572322e0a220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba1203454c461880c2d72f82f10441ad1647aa462a8859c7a699f22d6124c82a5239c90746ac67ebfd8e1a7b4a25f343733351162d205fc881ea62072e9fe0fad5f6113734309b6666f6812d6b7a6400',
},
});
expect(result).toEqual({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
try {
const result = await requestManage.sendAsync({
requestMethod: 'post',
method: 'blockChain/calculateTransactionFee',
params: {
RawTransaction:
'0a220a2005c3b3959caeee55b5db4004f6f9d76860aae818ce7b33d210a446ecb275468212220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba18a8a19e022204fa60011c2a085472616e73666572322e0a220a200e9a238616169860ba4fb502f8e87ce62db9ef321f29fd76d6e1ce30a0e0cdba1203454c461880c2d72f82f10441ad1647aa462a8859c7a699f22d6124c82a5239c90746ac67ebfd8e1a7b4a25f343733351162d205fc881ea62072e9fe0fad5f6113734309b6666f6812d6b7a6400',
},
});
} catch (error) {
expect(error).toMatchObject({
Success: false,
TransactionFee: null,
ResourceFee: null,
});
}
});
test('test send async without provider', async () => {
const requestManage = new RequestManager();
Expand Down
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8180,6 +8180,13 @@ node-addon-api@^2.0.0:
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32"
integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==

node-fetch@2:
version "2.7.0"
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
dependencies:
whatwg-url "^5.0.0"

node-fetch@^2.6.1, node-fetch@^2.6.7:
version "2.6.9"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6"
Expand Down

0 comments on commit 645250e

Please sign in to comment.