-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
257 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import {RESTClient} from '.'; | ||
import {APIClient} from '../APIClient'; | ||
import nock from 'nock'; | ||
import {LoginAPI} from '../login'; | ||
import {AxiosRequestConfig} from 'axios'; | ||
|
||
describe('RESTClient', () => { | ||
function createRESTClient(): RESTClient { | ||
return new RESTClient(APIClient.URL_DEMO, ''); | ||
} | ||
|
||
describe('defaults', () => { | ||
it('supports overriding the timeout limit', () => { | ||
const rest = createRESTClient(); | ||
expect(rest.defaults.timeout).toBe(5000); | ||
rest.defaults.timeout = 2500; | ||
expect(rest.defaults.timeout).toBe(2500); | ||
}); | ||
}); | ||
|
||
describe('interceptors', () => { | ||
beforeAll(() => { | ||
nock(APIClient.URL_DEMO) | ||
.persist() | ||
.defaultReplyHeaders({ | ||
CST: 'test', | ||
'X-SECURITY-TOKEN': 'test', | ||
}) | ||
.post(LoginAPI.URL.SESSION) | ||
.query(true) | ||
.reply(200, JSON.stringify({})); | ||
}); | ||
|
||
it('supports custom HTTP interceptors', async () => { | ||
const rest = createRESTClient(); | ||
|
||
const onRequest = jasmine.createSpy('onRequest').and.callFake((config: AxiosRequestConfig) => config); | ||
|
||
const myInterceptor = rest.interceptors.request.use(onRequest); | ||
await rest.login.createSession('test-user', 'test-password'); | ||
expect(onRequest).toHaveBeenCalledTimes(1); | ||
|
||
rest.interceptors.request.eject(myInterceptor); | ||
await rest.login.createSession('test-user', 'test-password'); | ||
expect(onRequest).toHaveBeenCalledTimes(1); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import nock from 'nock'; | ||
import {APIClient} from '../APIClient'; | ||
import {LoginAPI} from './LoginAPI'; | ||
|
||
describe('LoginAPI', () => { | ||
describe('createSession', () => { | ||
it('creates a trading session', async () => { | ||
nock(APIClient.URL_DEMO) | ||
.post(LoginAPI.URL.SESSION) | ||
.query(true) | ||
.reply( | ||
200, | ||
JSON.stringify({ | ||
accountInfo: { | ||
available: 0, | ||
balance: 0, | ||
deposit: 0, | ||
profitLoss: 0, | ||
}, | ||
accountType: 'CFD', | ||
accounts: [ | ||
{ | ||
accountId: 'ABC123', | ||
accountName: 'CFD', | ||
accountType: 'CFD', | ||
preferred: true, | ||
}, | ||
], | ||
clientId: '133721337', | ||
currencyIsoCode: 'EUR', | ||
currencySymbol: 'E', | ||
currentAccountId: 'ABC123', | ||
dealingEnabled: false, | ||
hasActiveDemoAccounts: true, | ||
hasActiveLiveAccounts: true, | ||
lightstreamerEndpoint: 'https://apd.marketdatasystems.com', | ||
reroutingEnvironment: null, | ||
timezoneOffset: 1, | ||
trailingStopsEnabled: false, | ||
}) | ||
); | ||
|
||
const session = await global.client.rest.login.createSession('test-user', 'test-password'); | ||
expect(session.accounts[0].accountId).toBe('ABC123'); | ||
expect(session.clientId).toBe('133721337'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import nock from 'nock'; | ||
import {APIClient} from '../APIClient'; | ||
import {MarketAPI} from './MarketAPI'; | ||
|
||
describe('MarketAPI', () => { | ||
describe('searchMarkets', () => { | ||
it('returns all markets matching the search term', async () => { | ||
nock(APIClient.URL_DEMO) | ||
.get(MarketAPI.URL.MARKETS) | ||
.query({searchTerm: 'PFE'}) | ||
.reply( | ||
200, | ||
JSON.stringify({ | ||
markets: [ | ||
{ | ||
bid: null, | ||
delayTime: 0, | ||
epic: 'SE.D.PFE.CASH.IP', | ||
expiry: '-', | ||
high: 40.49, | ||
instrumentName: 'Pfizer Inc (All Sessions)', | ||
instrumentType: 'SHARES', | ||
low: 38.24, | ||
marketStatus: 'EDITS_ONLY', | ||
netChange: 0.18, | ||
offer: null, | ||
percentageChange: 0.45, | ||
scalingFactor: 100, | ||
streamingPricesAvailable: false, | ||
updateTime: '22:59:58', | ||
updateTimeUTC: '21:59:58', | ||
}, | ||
{ | ||
bid: null, | ||
delayTime: 0, | ||
epic: 'SI.D.PFNXUS.CASH.IP', | ||
expiry: '-', | ||
high: null, | ||
instrumentName: 'Pfenex Inc', | ||
instrumentType: 'SHARES', | ||
low: null, | ||
marketStatus: 'CLOSED', | ||
netChange: 0, | ||
offer: null, | ||
percentageChange: 0, | ||
scalingFactor: 100, | ||
streamingPricesAvailable: false, | ||
updateTime: '15:30:00', | ||
updateTimeUTC: '14:30:00', | ||
}, | ||
{ | ||
bid: null, | ||
delayTime: 0, | ||
epic: 'ED.D.PFVGY.CASH.IP', | ||
expiry: '-', | ||
high: 157, | ||
instrumentName: 'Pfeiffer Vacuum Technology AG', | ||
instrumentType: 'SHARES', | ||
low: 152.4, | ||
marketStatus: 'EDITS_ONLY', | ||
netChange: 2.6, | ||
offer: null, | ||
percentageChange: 1.69, | ||
scalingFactor: 100, | ||
streamingPricesAvailable: false, | ||
updateTime: '17:30:00', | ||
updateTimeUTC: '16:30:00', | ||
}, | ||
], | ||
}) | ||
); | ||
|
||
const marketSearch = await global.client.rest.market.searchMarkets('PFE'); | ||
expect(marketSearch.markets.length).toBe(3); | ||
expect(marketSearch.markets[0].epic).toBe('SE.D.PFE.CASH.IP'); | ||
expect(marketSearch.markets[2].updateTimeUTC).toBe('16:30:00'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import {AxiosInstance} from 'axios'; | ||
|
||
export interface Market { | ||
bid?: number; | ||
delayTime: number; | ||
epic: string; | ||
expiry: string; | ||
high?: number; | ||
instrumentName: string; | ||
instrumentType: string; | ||
low?: number; | ||
marketStatus: string; | ||
netChange: number; | ||
offer?: number; | ||
percentageChange: number; | ||
scalingFactor: number; | ||
streamingPricesAvailable: boolean; | ||
updateTime: string; | ||
updateTimeUTC: string; | ||
} | ||
|
||
export interface MarketSearch { | ||
markets: Market[]; | ||
} | ||
|
||
export class MarketAPI { | ||
static readonly URL = { | ||
MARKETS: `/markets`, | ||
}; | ||
|
||
constructor(private readonly apiClient: AxiosInstance) {} | ||
|
||
/** | ||
* Returns all markets matching the search term. | ||
* | ||
* @param searchTerm - The term to be used in the search | ||
* @see https://labs.ig.com/rest-trading-api-reference/service-detail?id=547 | ||
*/ | ||
async searchMarkets(searchTerm: string): Promise<MarketSearch> { | ||
const resource = `${MarketAPI.URL.MARKETS}?searchTerm=${searchTerm}`; | ||
const response = await this.apiClient.get<MarketSearch>(resource); | ||
return response.data; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './MarketAPI'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import {APIClient} from '../../APIClient'; | ||
import nock from 'nock'; | ||
|
||
declare global { | ||
module NodeJS { | ||
interface Global { | ||
client: APIClient; | ||
} | ||
} | ||
} | ||
|
||
beforeEach(() => { | ||
global.client = new APIClient(APIClient.URL_DEMO, ''); | ||
}); | ||
|
||
afterEach(() => nock.cleanAll()); |