Merge pull request #103 from tiagosiebler/#3/tests
feat(#3): add initial integration tests for public api calls
This commit is contained in:
31
.circleci/config.yml
Normal file
31
.circleci/config.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
test:
|
||||
docker:
|
||||
- image: cimg/node:15.1
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
# See the configuration reference documentation for more details on using restore_cache and save_cache steps
|
||||
# https://circleci.com/docs/2.0/configuration-reference/?section=reference#save_cache
|
||||
keys:
|
||||
- node-deps-v1-{{ .Branch }}-{{checksum "package-lock.json"}}
|
||||
- run:
|
||||
name: install packages
|
||||
command: npm ci
|
||||
- save_cache:
|
||||
key: node-deps-v1-{{ .Branch }}-{{checksum "package-lock.json"}}
|
||||
paths:
|
||||
- ~/.npm
|
||||
- run:
|
||||
name: Run Build
|
||||
command: npm run build
|
||||
- run:
|
||||
name: Run Tests
|
||||
command: npm run test
|
||||
|
||||
workflows:
|
||||
integrationtests:
|
||||
jobs:
|
||||
- test
|
||||
@@ -1,4 +1,5 @@
|
||||
# bybit-api
|
||||
[](https://circleci.com/gh/tiagosiebler/bybit-api)
|
||||
[][1] [][1] [][1]
|
||||
[][1]
|
||||
[](https://www.codefactor.io/repository/github/tiagosiebler/bybit-api)
|
||||
|
||||
28
jest.config.js
Normal file
28
jest.config.js
Normal file
@@ -0,0 +1,28 @@
|
||||
// jest.config.js
|
||||
module.exports = {
|
||||
rootDir: './',
|
||||
globals: {
|
||||
__DEV__: true,
|
||||
__PROD__: false
|
||||
},
|
||||
testEnvironment: 'node',
|
||||
preset: "ts-jest",
|
||||
verbose: true, // report individual test
|
||||
bail: false, // enable to stop test when an error occur,
|
||||
detectOpenHandles: false,
|
||||
moduleDirectories: ['node_modules', 'src', 'test'],
|
||||
testMatch: ['**/test/**/*.test.ts?(x)'],
|
||||
testPathIgnorePatterns: ['node_modules/', 'dist/', '.json'],
|
||||
collectCoverageFrom: [
|
||||
'src/**/*.ts'
|
||||
],
|
||||
coverageThreshold: {
|
||||
// coverage strategy
|
||||
global: {
|
||||
branches: 80,
|
||||
functions: 80,
|
||||
lines: 50,
|
||||
statements: -10
|
||||
}
|
||||
}
|
||||
};
|
||||
3795
package-lock.json
generated
3795
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,8 @@
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"clean": "rm -rf lib dist",
|
||||
"build": "tsc",
|
||||
"build:clean": "npm run clean && npm run build",
|
||||
@@ -28,9 +29,12 @@
|
||||
"ws": "^7.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^26.0.23",
|
||||
"@types/node": "^14.14.7",
|
||||
"eslint": "^7.10.0",
|
||||
"jest": "^27.0.4",
|
||||
"source-map-loader": "^2.0.0",
|
||||
"ts-jest": "^27.0.3",
|
||||
"ts-loader": "^8.0.11",
|
||||
"typescript": "^4.0.5",
|
||||
"webpack": "^5.4.0",
|
||||
|
||||
@@ -22,7 +22,8 @@ export class InverseClient extends SharedEndpoints {
|
||||
restClientOptions: RestClientOptions = {},
|
||||
requestOptions: AxiosRequestConfig = {}
|
||||
) {
|
||||
super()
|
||||
super();
|
||||
|
||||
this.requestWrapper = new RequestWrapper(
|
||||
key,
|
||||
secret,
|
||||
@@ -53,9 +54,9 @@ export class InverseClient extends SharedEndpoints {
|
||||
*/
|
||||
getLatestInformation(params?: {
|
||||
symbol?: string;
|
||||
}): GenericAPIResponse {
|
||||
}): GenericAPIResponse {
|
||||
return this.getTickers(params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use getTrades() instead
|
||||
|
||||
@@ -22,7 +22,8 @@ export class InverseFuturesClient extends SharedEndpoints {
|
||||
restClientOptions: RestClientOptions = {},
|
||||
requestOptions: AxiosRequestConfig = {}
|
||||
) {
|
||||
super()
|
||||
super();
|
||||
|
||||
this.requestWrapper = new RequestWrapper(
|
||||
key,
|
||||
secret,
|
||||
|
||||
@@ -7,7 +7,7 @@ export class LinearClient extends SharedEndpoints {
|
||||
protected requestWrapper: RequestWrapper;
|
||||
|
||||
/**
|
||||
* @public Creates an instance of the inverse REST API client.
|
||||
* @public Creates an instance of the linear REST API client.
|
||||
*
|
||||
* @param {string} key - your API key
|
||||
* @param {string} secret - your API secret
|
||||
@@ -22,7 +22,8 @@ export class LinearClient extends SharedEndpoints {
|
||||
restClientOptions: RestClientOptions = {},
|
||||
requestOptions: AxiosRequestConfig = {}
|
||||
) {
|
||||
super()
|
||||
super();
|
||||
|
||||
this.requestWrapper = new RequestWrapper(
|
||||
key,
|
||||
secret,
|
||||
|
||||
70
test/inverse-futures/public.test.ts
Normal file
70
test/inverse-futures/public.test.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { InverseFuturesClient } from "../../src/inverse-futures-client";
|
||||
import { notAuthenticatedError, successResponseList, successResponseObject } from "../response.util";
|
||||
|
||||
describe('Public Inverse Futures REST API Endpoints', () => {
|
||||
const useLivenet = true;
|
||||
const api = new InverseFuturesClient(undefined, undefined, useLivenet, { disable_time_sync: true });
|
||||
|
||||
const symbol = 'BTCUSD';
|
||||
const interval = '15';
|
||||
const timestampOneHourAgo = (new Date().getTime() / 1000) - (1000 * 60 * 60);
|
||||
const from = Number(timestampOneHourAgo.toFixed(0));
|
||||
|
||||
describe('Inverse-Futures only endpoints', () => {
|
||||
it('should throw for unauthenticated private calls', async () => {
|
||||
expect(() => api.getPosition()).rejects.toMatchObject(notAuthenticatedError());
|
||||
});
|
||||
|
||||
it('getKline()', async () => {
|
||||
expect(
|
||||
await api.getKline({ symbol, interval, from })
|
||||
).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getTrades()', async () => {
|
||||
expect(await api.getTrades({ symbol })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getIndexPriceKline()', async () => {
|
||||
expect(await api.getIndexPriceKline({ symbol, interval, from })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getPremiumIndexKline()', async () => {
|
||||
expect(await api.getPremiumIndexKline({ symbol, interval, from })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getLastFundingRate()', async () => {
|
||||
expect(await api.getLastFundingRate({ symbol })).toMatchObject(successResponseObject());
|
||||
});
|
||||
});
|
||||
|
||||
describe('Shared endpoints', () => {
|
||||
it('should throw for unauthenticated private calls', async () => {
|
||||
expect(() => api.getApiKeyInfo()).rejects.toMatchObject(notAuthenticatedError());
|
||||
});
|
||||
|
||||
it('getOrderBook()', async () => {
|
||||
expect(await api.getOrderBook({ symbol })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getTickers()', async () => {
|
||||
expect(await api.getTickers()).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getSymbols()', async () => {
|
||||
expect(await api.getSymbols()).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getLiquidations()', async () => {
|
||||
expect(await api.getLiquidations({ symbol })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getServerTime()', async () => {
|
||||
expect(await api.getServerTime()).toMatchObject(successResponseObject());
|
||||
});
|
||||
|
||||
it('getApiAnnouncements()', async () => {
|
||||
expect(await api.getApiAnnouncements()).toMatchObject(successResponseList());
|
||||
});
|
||||
});
|
||||
});
|
||||
70
test/inverse/public.test.ts
Normal file
70
test/inverse/public.test.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { InverseClient } from "../../src/inverse-client";
|
||||
import { notAuthenticatedError, successResponseList, successResponseObject } from "../response.util";
|
||||
|
||||
describe('Public Inverse REST API Endpoints', () => {
|
||||
const useLivenet = true;
|
||||
const api = new InverseClient(undefined, undefined, useLivenet, { disable_time_sync: true });
|
||||
|
||||
const symbol = 'BTCUSD';
|
||||
const interval = '15';
|
||||
const timestampOneHourAgo = (new Date().getTime() / 1000) - (1000 * 60 * 60);
|
||||
const from = Number(timestampOneHourAgo.toFixed(0));
|
||||
|
||||
describe('Inverse only endpoints', () => {
|
||||
it('should throw for unauthenticated private calls', async () => {
|
||||
expect(() => api.getPosition()).rejects.toMatchObject(notAuthenticatedError());
|
||||
});
|
||||
|
||||
it('getKline()', async () => {
|
||||
expect(
|
||||
await api.getKline({ symbol, interval, from })
|
||||
).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getTrades()', async () => {
|
||||
expect(await api.getTrades({ symbol })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getIndexPriceKline()', async () => {
|
||||
expect(await api.getIndexPriceKline({ symbol, interval, from })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getPremiumIndexKline()', async () => {
|
||||
expect(await api.getPremiumIndexKline({ symbol, interval, from })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getLastFundingRate()', async () => {
|
||||
expect(await api.getLastFundingRate({ symbol })).toMatchObject(successResponseObject());
|
||||
});
|
||||
});
|
||||
|
||||
describe('Shared endpoints', () => {
|
||||
it('should throw for unauthenticated private calls', async () => {
|
||||
expect(() => api.getApiKeyInfo()).rejects.toMatchObject(notAuthenticatedError());
|
||||
});
|
||||
|
||||
it('getOrderBook()', async () => {
|
||||
expect(await api.getOrderBook({ symbol })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getTickers()', async () => {
|
||||
expect(await api.getTickers()).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getSymbols()', async () => {
|
||||
expect(await api.getSymbols()).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getLiquidations()', async () => {
|
||||
expect(await api.getLiquidations({ symbol })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getServerTime()', async () => {
|
||||
expect(await api.getServerTime()).toMatchObject(successResponseObject());
|
||||
});
|
||||
|
||||
it('getApiAnnouncements()', async () => {
|
||||
expect(await api.getApiAnnouncements()).toMatchObject(successResponseList());
|
||||
});
|
||||
});
|
||||
});
|
||||
70
test/linear/public.test.ts
Normal file
70
test/linear/public.test.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { LinearClient } from "../../src/linear-client";
|
||||
import { notAuthenticatedError, successResponseList, successResponseObject } from "../response.util";
|
||||
|
||||
describe('Public Linear REST API Endpoints', () => {
|
||||
const useLivenet = true;
|
||||
const api = new LinearClient(undefined, undefined, useLivenet, { disable_time_sync: true });
|
||||
|
||||
const symbol = 'BTCUSDT';
|
||||
const interval = '15';
|
||||
const timestampOneHourAgo = (new Date().getTime() / 1000) - (1000 * 60 * 60);
|
||||
const from = Number(timestampOneHourAgo.toFixed(0));
|
||||
|
||||
describe('Linear only endpoints', () => {
|
||||
it('should throw for unauthenticated private calls', async () => {
|
||||
expect(() => api.getPosition()).rejects.toMatchObject(notAuthenticatedError());
|
||||
});
|
||||
|
||||
it('getKline()', async () => {
|
||||
expect(
|
||||
await api.getKline({ symbol, interval, from })
|
||||
).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getTrades()', async () => {
|
||||
expect(await api.getTrades({ symbol })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getIndexPriceKline()', async () => {
|
||||
expect(await api.getIndexPriceKline({ symbol, interval, from })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getPremiumIndexKline()', async () => {
|
||||
expect(await api.getPremiumIndexKline({ symbol, interval, from })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getLastFundingRate()', async () => {
|
||||
expect(await api.getLastFundingRate({ symbol })).toMatchObject(successResponseObject());
|
||||
});
|
||||
});
|
||||
|
||||
describe('Shared endpoints', () => {
|
||||
it('should throw for unauthenticated private calls', async () => {
|
||||
expect(() => api.getApiKeyInfo()).rejects.toMatchObject(notAuthenticatedError());
|
||||
});
|
||||
|
||||
it('getOrderBook()', async () => {
|
||||
expect(await api.getOrderBook({ symbol })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getTickers()', async () => {
|
||||
expect(await api.getTickers()).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getSymbols()', async () => {
|
||||
expect(await api.getSymbols()).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getLiquidations()', async () => {
|
||||
expect(await api.getLiquidations({ symbol })).toMatchObject(successResponseList());
|
||||
});
|
||||
|
||||
it('getServerTime()', async () => {
|
||||
expect(await api.getServerTime()).toMatchObject(successResponseObject());
|
||||
});
|
||||
|
||||
it('getApiAnnouncements()', async () => {
|
||||
expect(await api.getApiAnnouncements()).toMatchObject(successResponseList());
|
||||
});
|
||||
});
|
||||
});
|
||||
26
test/response.util.ts
Normal file
26
test/response.util.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
export function successResponseList() {
|
||||
return {
|
||||
"ext_code": "",
|
||||
"ext_info": "",
|
||||
"result": expect.any(Array),
|
||||
"ret_code": 0,
|
||||
"ret_msg": "OK",
|
||||
"time_now": expect.any(String),
|
||||
};
|
||||
};
|
||||
|
||||
export function successResponseObject() {
|
||||
return {
|
||||
"ext_code": "",
|
||||
"ext_info": "",
|
||||
"result": expect.any(Object),
|
||||
"ret_code": 0,
|
||||
"ret_msg": "OK",
|
||||
"time_now": expect.any(String),
|
||||
};
|
||||
};
|
||||
|
||||
export function notAuthenticatedError() {
|
||||
return new Error('Private endpoints require api and private keys set');
|
||||
};
|
||||
Reference in New Issue
Block a user