Skip to content

Commit 45b0b6b

Browse files
committed
Add TradeAPI#fetchTradeQuote tests
1 parent 9ccac88 commit 45b0b6b

File tree

5 files changed

+157
-4
lines changed

5 files changed

+157
-4
lines changed

src/api/TradeAPI.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,18 +153,21 @@ export default class TradeAPI {
153153
this.assert.schema.isValidAddress('fromToken', fromToken);
154154
this.assert.schema.isValidAddress('toToken', toToken);
155155
this.assert.schema.isValidAddress('fromAddress', fromAddress);
156-
this.assert.schema.isValidNumber('fromTokenDecimals', fromTokenDecimals);
157-
this.assert.schema.isValidNumber('toTokenDecimals', toTokenDecimals);
158-
this.assert.schema.isValidNumber('rawAmount', rawAmount);
156+
this.assert.schema.isValidJsNumber('fromTokenDecimals', fromTokenDecimals);
157+
this.assert.schema.isValidJsNumber('toTokenDecimals', toTokenDecimals);
158+
this.assert.schema.isValidString('rawAmount', rawAmount);
159159

160+
const chainId = (await this.provider.getNetwork()).chainId;
161+
162+
// @ts-ignore
160163
return this.tradeQuoter.generate({
161164
fromToken,
162165
toToken,
163166
fromTokenDecimals,
164167
toTokenDecimals,
165168
rawAmount,
166169
fromAddress,
167-
chainId: this.chainId,
170+
chainId,
168171
tradeModule: this.tradeModuleWrapper,
169172
provider: this.provider,
170173
setToken,

src/assertions/SchemaAssertions.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,26 @@ export class SchemaAssertions {
9191
this.assertConformsToSchema(variableName, value, schemas.wholeNumberSchema);
9292
}
9393

94+
/**
95+
* Throws if a given input is not a native JS number.
96+
*
97+
* @param variableName Variable name being validated. Used for displaying error messages.
98+
* @param value Value being validated.
99+
*/
100+
public isValidJsNumber(variableName: string, value: any) {
101+
this.assertConformsToSchema(variableName, value, schemas.jsNumberSchema);
102+
}
103+
104+
/**
105+
* Throws if a given input is not a string.
106+
*
107+
* @param variableName Variable name being validated. Used for displaying error messages.
108+
* @param value Value being validated.
109+
*/
110+
public isValidString(variableName: string, value: any) {
111+
this.assertConformsToSchema(variableName, value, schemas.stringSchema);
112+
}
113+
94114
private assertConformsToSchema(
95115
variableName: string,
96116
value: any,

src/schemas/commonSchemas.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,13 @@ export const wholeNumberSchema = {
4646
type: 'object',
4747
format: 'wholeBigNumber',
4848
};
49+
50+
export const jsNumberSchema = {
51+
id: '/JsNumber',
52+
type: 'number',
53+
};
54+
55+
export const stringSchema = {
56+
id: '/String',
57+
type: 'string',
58+
};

src/schemas/schemas.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import {
2222
bytesSchema,
2323
numberSchema,
2424
wholeNumberSchema,
25+
jsNumberSchema,
26+
stringSchema
2527
} from './commonSchemas';
2628

2729
export const schemas = {
@@ -30,4 +32,6 @@ export const schemas = {
3032
bytesSchema,
3133
bytes32Schema,
3234
wholeNumberSchema,
35+
jsNumberSchema,
36+
stringSchema,
3337
};

test/api/TradeAPI.spec.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,23 @@ import { ether } from '@setprotocol/set-protocol-v2/dist/utils/common';
2222

2323
import TradeAPI from '@src/api/TradeAPI';
2424
import TradeModuleWrapper from '@src/wrappers/set-protocol-v2/TradeModuleWrapper';
25+
import type SetTokenAPI from '@src/api/SetTokenAPI';
26+
import { TradeQuoter } from '@src/api/utils/tradequote';
2527
import { expect } from '@test/utils/chai';
28+
import { TradeQuote } from '@src/types';
2629

2730
const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545');
2831

2932
jest.mock('@src/wrappers/set-protocol-v2/TradeModuleWrapper');
33+
jest.mock('@src/api/utils/tradequote');
3034

3135
describe('TradeAPI', () => {
3236
let tradeModuleAddress: Address;
3337
let setTokenAddress: Address;
3438
let owner: Address;
3539

3640
let tradeModuleWrapper: TradeModuleWrapper;
41+
let tradeQuoter: TradeQuoter;
3742

3843
let tradeAPI: TradeAPI;
3944

@@ -46,10 +51,12 @@ describe('TradeAPI', () => {
4651

4752
tradeAPI = new TradeAPI(provider, tradeModuleAddress);
4853
tradeModuleWrapper = (TradeModuleWrapper as any).mock.instances[0];
54+
tradeQuoter = (TradeQuoter as any).mock.instances[0];
4955
});
5056

5157
afterEach(async () => {
5258
(TradeModuleWrapper as any).mockClear();
59+
(TradeQuoter as any).mockClear();
5360
});
5461

5562
describe('#initializeAsync', () => {
@@ -175,4 +182,113 @@ describe('TradeAPI', () => {
175182
});
176183
});
177184
});
185+
186+
describe('#fetchTradeQuote', () => {
187+
let subjectFromToken: Address;
188+
let subjectToToken: Address;
189+
let subjectFromTokenDecimals: number;
190+
let subjectToTokenDecimals: number;
191+
let subjectRawAmount: string;
192+
let subjectFromAddress: Address;
193+
let subjectSetToken: SetTokenAPI;
194+
let subjectGasPrice: number;
195+
196+
beforeEach(async () => {
197+
subjectFromToken = '0xAAAA15AA9B462ed4fC84B5dFc43Fd2a10a54B569';
198+
subjectToToken = '0xBBBB262A92581EC09C2d522b48bCcd9E3C8ACf9C';
199+
subjectFromTokenDecimals = 8;
200+
subjectToTokenDecimals = 6;
201+
subjectRawAmount = '5';
202+
subjectFromAddress = '0xCCCC262A92581EC09C2d522b48bCcd9E3C8ACf9C';
203+
subjectSetToken = <unknown>{ val: 'settoken' } as SetTokenAPI;
204+
subjectGasPrice = 20;
205+
});
206+
207+
async function subject(): Promise<TradeQuote> {
208+
return await tradeAPI.fetchTradeQuoteAsync(
209+
subjectFromToken,
210+
subjectToToken,
211+
subjectFromTokenDecimals,
212+
subjectToTokenDecimals,
213+
subjectRawAmount,
214+
subjectFromAddress,
215+
subjectSetToken,
216+
subjectGasPrice
217+
);
218+
}
219+
220+
it('should call the TradeQuoter with correct params', async () => {
221+
const expectedQuoteOptions = {
222+
fromToken: subjectFromToken,
223+
toToken: subjectToToken,
224+
fromTokenDecimals: subjectFromTokenDecimals,
225+
toTokenDecimals: subjectToTokenDecimals,
226+
rawAmount: subjectRawAmount,
227+
fromAddress: subjectFromAddress,
228+
chainId: (await provider.getNetwork()).chainId,
229+
tradeModule: tradeModuleWrapper,
230+
provider: provider,
231+
setToken: subjectSetToken,
232+
gasPrice: subjectGasPrice,
233+
slippagePercentage: undefined,
234+
isFirmQuote: undefined,
235+
feePercentage: undefined,
236+
feeRecipient: undefined,
237+
excludedSources: undefined,
238+
};
239+
await subject();
240+
241+
expect(tradeQuoter.generate).to.have.beenCalledWith(expectedQuoteOptions);
242+
});
243+
244+
describe('when the fromToken address is invalid', () => {
245+
beforeEach(async () => {
246+
subjectFromToken = '0xInvalidAddress';
247+
});
248+
249+
it('should throw with invalid params', async () => {
250+
await expect(subject()).to.be.rejectedWith('Validation error');
251+
});
252+
});
253+
254+
describe('when the toToken address is invalid', () => {
255+
beforeEach(async () => {
256+
subjectToToken = '0xInvalidAddress';
257+
});
258+
259+
it('should throw with invalid params', async () => {
260+
await expect(subject()).to.be.rejectedWith('Validation error');
261+
});
262+
});
263+
264+
describe('when the fromTokenDecimals is invalid', () => {
265+
beforeEach(async () => {
266+
subjectFromTokenDecimals = <unknown>'100' as number;
267+
});
268+
269+
it('should throw with invalid params', async () => {
270+
await expect(subject()).to.be.rejectedWith('Validation error');
271+
});
272+
});
273+
274+
describe('when the toTokenDecimals is invalid', () => {
275+
beforeEach(async () => {
276+
subjectToTokenDecimals = <unknown>'100' as number;
277+
});
278+
279+
it('should throw with invalid params', async () => {
280+
await expect(subject()).to.be.rejectedWith('Validation error');
281+
});
282+
});
283+
284+
describe('when the rawAmount quantity is invalid', () => {
285+
beforeEach(async () => {
286+
subjectRawAmount = <unknown>5 as string;
287+
});
288+
289+
it('should throw with invalid params', async () => {
290+
await expect(subject()).to.be.rejectedWith('Validation error');
291+
});
292+
});
293+
});
178294
});

0 commit comments

Comments
 (0)