aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-watcher/test
diff options
context:
space:
mode:
Diffstat (limited to 'packages/order-watcher/test')
-rw-r--r--packages/order-watcher/test/expiration_watcher_test.ts199
-rw-r--r--packages/order-watcher/test/global_hooks.ts6
-rw-r--r--packages/order-watcher/test/order_watcher_test.ts887
-rw-r--r--packages/order-watcher/test/order_watcher_web_socket_server_test.ts312
-rw-r--r--packages/order-watcher/test/utils/chai_setup.ts13
-rw-r--r--packages/order-watcher/test/utils/constants.ts5
-rw-r--r--packages/order-watcher/test/utils/migrate.ts18
-rw-r--r--packages/order-watcher/test/utils/web3_wrapper.ts8
8 files changed, 0 insertions, 1448 deletions
diff --git a/packages/order-watcher/test/expiration_watcher_test.ts b/packages/order-watcher/test/expiration_watcher_test.ts
deleted file mode 100644
index fb5ea2a27..000000000
--- a/packages/order-watcher/test/expiration_watcher_test.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-import { tokenUtils } from '@0x/contract-wrappers/lib/test/utils/token_utils';
-import { BlockchainLifecycle, callbackErrorReporter } from '@0x/dev-utils';
-import { FillScenarios } from '@0x/fill-scenarios';
-import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
-import { DoneCallback } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import * as _ from 'lodash';
-import 'mocha';
-import * as Sinon from 'sinon';
-
-import { ExpirationWatcher } from '../src/order_watcher/expiration_watcher';
-import { utils } from '../src/utils/utils';
-
-import { chaiSetup } from './utils/chai_setup';
-import { migrateOnceAsync } from './utils/migrate';
-import { provider, web3Wrapper } from './utils/web3_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-const MILISECONDS_IN_SECOND = 1000;
-
-describe('ExpirationWatcher', () => {
- let userAddresses: string[];
- let fillScenarios: FillScenarios;
- let makerAssetData: string;
- let takerAssetData: string;
- let coinbase: string;
- let makerAddress: string;
- let takerAddress: string;
- let feeRecipient: string;
- const fillableAmount = new BigNumber(5);
- let currentUnixTimestampSec: BigNumber;
- let timer: Sinon.SinonFakeTimers;
- let expirationWatcher: ExpirationWatcher;
- before(async () => {
- const contractAddresses = await migrateOnceAsync();
- await blockchainLifecycle.startAsync();
- userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- fillScenarios = new FillScenarios(
- provider,
- userAddresses,
- contractAddresses.zrxToken,
- contractAddresses.exchange,
- contractAddresses.erc20Proxy,
- contractAddresses.erc721Proxy,
- );
- [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
- const [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses();
- [makerAssetData, takerAssetData] = [
- assetDataUtils.encodeERC20AssetData(makerTokenAddress),
- assetDataUtils.encodeERC20AssetData(takerTokenAddress),
- ];
- });
- after(async () => {
- await blockchainLifecycle.revertAsync();
- });
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- const sinonTimerConfig = { shouldAdvanceTime: true } as any;
- // This constructor has incorrect types
- timer = Sinon.useFakeTimers(sinonTimerConfig);
- currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
- expirationWatcher = new ExpirationWatcher();
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- timer.restore();
- expirationWatcher.unsubscribe();
- });
- it('correctly emits events when order expires', (done: DoneCallback) => {
- (async () => {
- const orderLifetimeSec = 60;
- const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- expirationUnixTimestampSec,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- expirationWatcher.addOrder(orderHash, signedOrder.expirationTimeSeconds.times(MILISECONDS_IN_SECOND));
- const callbackAsync = callbackErrorReporter.reportNoErrorCallbackErrors(done)((hash: string) => {
- expect(hash).to.be.equal(orderHash);
- expect(utils.getCurrentUnixTimestampSec()).to.be.bignumber.gte(expirationUnixTimestampSec);
- });
- expirationWatcher.subscribe(callbackAsync);
- timer.tick(orderLifetimeSec * MILISECONDS_IN_SECOND);
- })().catch(done);
- });
- it("doesn't emit events before order expires", (done: DoneCallback) => {
- (async () => {
- const orderLifetimeSec = 60;
- const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- expirationUnixTimestampSec,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- expirationWatcher.addOrder(orderHash, signedOrder.expirationTimeSeconds.times(MILISECONDS_IN_SECOND));
- const callbackAsync = callbackErrorReporter.reportNoErrorCallbackErrors(done)(async (_hash: string) => {
- done(new Error('Emitted expiration went before the order actually expired'));
- });
- expirationWatcher.subscribe(callbackAsync);
- const notEnoughTime = orderLifetimeSec - 1;
- timer.tick(notEnoughTime * MILISECONDS_IN_SECOND);
- done();
- })().catch(done);
- });
- it('emits events in correct order', (done: DoneCallback) => {
- (async () => {
- const order1Lifetime = 60;
- const order2Lifetime = 120;
- const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
- const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
- const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- order1ExpirationUnixTimestampSec,
- );
- const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- order2ExpirationUnixTimestampSec,
- );
- const orderHash1 = orderHashUtils.getOrderHashHex(signedOrder1);
- const orderHash2 = orderHashUtils.getOrderHashHex(signedOrder2);
- expirationWatcher.addOrder(orderHash2, signedOrder2.expirationTimeSeconds.times(MILISECONDS_IN_SECOND));
- expirationWatcher.addOrder(orderHash1, signedOrder1.expirationTimeSeconds.times(MILISECONDS_IN_SECOND));
- const expirationOrder = [orderHash1, orderHash2];
- const expectToBeCalledOnce = false;
- const callbackAsync = callbackErrorReporter.reportNoErrorCallbackErrors(done, expectToBeCalledOnce)(
- (hash: string) => {
- const orderHash = expirationOrder.shift();
- expect(hash).to.be.equal(orderHash);
- if (_.isEmpty(expirationOrder)) {
- done();
- }
- },
- );
- expirationWatcher.subscribe(callbackAsync);
- timer.tick(order2Lifetime * MILISECONDS_IN_SECOND);
- })().catch(done);
- });
- it('emits events in correct order when expirations are equal', (done: DoneCallback) => {
- (async () => {
- const order1Lifetime = 60;
- const order2Lifetime = 60;
- const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
- const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
- const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- order1ExpirationUnixTimestampSec,
- );
- const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- order2ExpirationUnixTimestampSec,
- );
- const orderHash1 = orderHashUtils.getOrderHashHex(signedOrder1);
- const orderHash2 = orderHashUtils.getOrderHashHex(signedOrder2);
- expirationWatcher.addOrder(orderHash1, signedOrder1.expirationTimeSeconds.times(MILISECONDS_IN_SECOND));
- expirationWatcher.addOrder(orderHash2, signedOrder2.expirationTimeSeconds.times(MILISECONDS_IN_SECOND));
- const expirationOrder = orderHash1 < orderHash2 ? [orderHash1, orderHash2] : [orderHash2, orderHash1];
- const expectToBeCalledOnce = false;
- const callbackAsync = callbackErrorReporter.reportNoErrorCallbackErrors(done, expectToBeCalledOnce)(
- (hash: string) => {
- const orderHash = expirationOrder.shift();
- expect(hash).to.be.equal(orderHash);
- if (_.isEmpty(expirationOrder)) {
- done();
- }
- },
- );
- expirationWatcher.subscribe(callbackAsync);
- timer.tick(order2Lifetime * MILISECONDS_IN_SECOND);
- })().catch(done);
- });
-});
diff --git a/packages/order-watcher/test/global_hooks.ts b/packages/order-watcher/test/global_hooks.ts
deleted file mode 100644
index 26c37158f..000000000
--- a/packages/order-watcher/test/global_hooks.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-before('set up mocha', async function(): Promise<void> {
- // HACK: Since the migrations take longer then our global mocha timeout limit
- // we manually increase it for this before hook.
- const mochaTestTimeoutMs = 25000;
- this.timeout(mochaTestTimeoutMs); // tslint:disable-line:no-invalid-this
-});
diff --git a/packages/order-watcher/test/order_watcher_test.ts b/packages/order-watcher/test/order_watcher_test.ts
deleted file mode 100644
index 28b564b32..000000000
--- a/packages/order-watcher/test/order_watcher_test.ts
+++ /dev/null
@@ -1,887 +0,0 @@
-// tslint:disable:no-unnecessary-type-assertion
-import { ContractWrappers } from '@0x/contract-wrappers';
-import { tokenUtils } from '@0x/contract-wrappers/lib/test/utils/token_utils';
-import { BlockchainLifecycle, callbackErrorReporter } from '@0x/dev-utils';
-import { FillScenarios } from '@0x/fill-scenarios';
-import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
-import {
- DoneCallback,
- ExchangeContractErrs,
- OrderState,
- OrderStateInvalid,
- OrderStateValid,
- SignedOrder,
-} from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import * as chai from 'chai';
-import * as _ from 'lodash';
-import 'mocha';
-
-import {
- DependentOrderHashesTracker,
- OrderHashesByERC20ByMakerAddress,
-} from '../src/order_watcher/dependent_order_hashes_tracker';
-import { OrderWatcher } from '../src/order_watcher/order_watcher';
-import { OrderWatcherError } from '../src/types';
-
-import { chaiSetup } from './utils/chai_setup';
-import { constants } from './utils/constants';
-import { migrateOnceAsync } from './utils/migrate';
-import { provider, web3Wrapper } from './utils/web3_wrapper';
-
-const TIMEOUT_MS = 150;
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-
-describe('OrderWatcher', () => {
- let contractWrappers: ContractWrappers;
- let fillScenarios: FillScenarios;
- let userAddresses: string[];
- let zrxTokenAddress: string;
- let makerAssetData: string;
- let takerAssetData: string;
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let makerAddress: string;
- let takerAddress: string;
- let coinbase: string;
- let feeRecipient: string;
- let signedOrder: SignedOrder;
- let orderWatcher: OrderWatcher;
- const decimals = constants.ZRX_DECIMALS;
- const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals);
- before(async () => {
- const contractAddresses = await migrateOnceAsync();
- await blockchainLifecycle.startAsync();
- const networkId = constants.TESTRPC_NETWORK_ID;
- const config = {
- networkId,
- contractAddresses,
- };
- contractWrappers = new ContractWrappers(provider, config);
- userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- zrxTokenAddress = contractAddresses.zrxToken;
- fillScenarios = new FillScenarios(
- provider,
- userAddresses,
- zrxTokenAddress,
- contractAddresses.exchange,
- contractAddresses.erc20Proxy,
- contractAddresses.erc721Proxy,
- );
- [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
- [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses();
- [makerAssetData, takerAssetData] = [
- assetDataUtils.encodeERC20AssetData(makerTokenAddress),
- assetDataUtils.encodeERC20AssetData(takerTokenAddress),
- ];
- const orderWatcherConfig = {};
- orderWatcher = new OrderWatcher(provider, networkId, contractAddresses, orderWatcherConfig);
- });
- after(async () => {
- await blockchainLifecycle.revertAsync();
- });
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- });
- describe('#removeOrder', async () => {
- it('should successfully remove existing order', async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- expect((orderWatcher as any)._orderByOrderHash).to.include({
- [orderHash]: signedOrder,
- });
- const dependentOrderHashesTracker = (orderWatcher as any)
- ._dependentOrderHashesTracker as DependentOrderHashesTracker;
- let orderHashesByERC20ByMakerAddress: OrderHashesByERC20ByMakerAddress = (dependentOrderHashesTracker as any)
- ._orderHashesByERC20ByMakerAddress;
- expect(orderHashesByERC20ByMakerAddress[signedOrder.makerAddress][makerTokenAddress]).to.have.keys(
- orderHash,
- );
- orderWatcher.removeOrder(orderHash);
- expect((orderWatcher as any)._orderByOrderHash).to.not.include({
- [orderHash]: signedOrder,
- });
- orderHashesByERC20ByMakerAddress = (dependentOrderHashesTracker as any)._orderHashesByERC20ByMakerAddress;
- expect(orderHashesByERC20ByMakerAddress[signedOrder.makerAddress]).to.be.undefined();
- });
- it('should no-op when removing a non-existing order', async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- const nonExistentOrderHash = `0x${orderHash
- .substr(2)
- .split('')
- .reverse()
- .join('')}`;
- orderWatcher.removeOrder(nonExistentOrderHash);
- });
- });
- describe('#subscribe', async () => {
- afterEach(async () => {
- orderWatcher.unsubscribe();
- });
- it('should fail when trying to subscribe twice', async () => {
- orderWatcher.subscribe(_.noop.bind(_));
- expect(() => orderWatcher.subscribe(_.noop.bind(_))).to.throw(OrderWatcherError.SubscriptionAlreadyPresent);
- });
- });
- describe('#getStats', async () => {
- it('orderCount should increment and decrement with order additions and removals', async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- expect(orderWatcher.getStats().orderCount).to.be.eq(0);
- await orderWatcher.addOrderAsync(signedOrder);
- expect(orderWatcher.getStats().orderCount).to.be.eq(1);
- orderWatcher.removeOrder(orderHash);
- expect(orderWatcher.getStats().orderCount).to.be.eq(0);
- });
- });
- describe('tests with cleanup', async () => {
- afterEach(async () => {
- orderWatcher.unsubscribe();
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- orderWatcher.removeOrder(orderHash);
- });
- it('should emit orderStateInvalid when makerAddress allowance set to 0 for watched order', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.erc20Token.setProxyAllowanceAsync(
- makerTokenAddress,
- makerAddress,
- new BigNumber(0),
- );
- })().catch(done);
- });
- it('should not emit an orderState event when irrelevant Transfer event received', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((_orderState: OrderState) => {
- throw new Error('OrderState callback fired for irrelevant order');
- });
- orderWatcher.subscribe(callback);
- const notTheMaker = userAddresses[0];
- const anyRecipient = takerAddress;
- const transferAmount = new BigNumber(2);
- await contractWrappers.erc20Token.transferAsync(
- makerTokenAddress,
- notTheMaker,
- anyRecipient,
- transferAmount,
- );
- setTimeout(() => {
- done();
- }, TIMEOUT_MS);
- })().catch(done);
- });
- it('should emit orderStateInvalid when makerAddress moves balance backing watched order', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
- });
- orderWatcher.subscribe(callback);
- const anyRecipient = takerAddress;
- const makerBalance = await contractWrappers.erc20Token.getBalanceAsync(makerTokenAddress, makerAddress);
- await contractWrappers.erc20Token.transferAsync(
- makerTokenAddress,
- makerAddress,
- anyRecipient,
- makerBalance,
- );
- })().catch(done);
- });
- it('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
-
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
- });
- orderWatcher.subscribe(callback);
-
- await contractWrappers.exchange.fillOrderAsync(signedOrder, fillableAmount, takerAddress);
- })().catch(done);
- });
- it('should include transactionHash in emitted orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- await orderWatcher.addOrderAsync(signedOrder);
-
- let transactionHash: string;
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.transactionHash).to.be.equal(transactionHash);
- });
- orderWatcher.subscribe(callback);
-
- transactionHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- fillableAmount,
- takerAddress,
- );
- })().catch(done);
- });
- it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
-
- const makerBalance = await contractWrappers.erc20Token.getBalanceAsync(makerTokenAddress, makerAddress);
- const fillAmountInBaseUnits = new BigNumber(2);
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
-
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.true();
- const validOrderState = orderState as OrderStateValid;
- expect(validOrderState.orderHash).to.be.equal(orderHash);
- const orderRelevantState = validOrderState.orderRelevantState;
- const remainingMakerBalance = makerBalance.minus(fillAmountInBaseUnits);
- const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits);
- expect(orderRelevantState.remainingFillableMakerAssetAmount).to.be.bignumber.equal(
- remainingFillable,
- );
- expect(orderRelevantState.remainingFillableTakerAssetAmount).to.be.bignumber.equal(
- remainingFillable,
- );
- expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance);
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.exchange.fillOrderAsync(signedOrder, fillAmountInBaseUnits, takerAddress);
- })().catch(done);
- });
- it('should trigger the callback when orders backing ZRX allowance changes', (done: DoneCallback) => {
- (async () => {
- const makerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
- const takerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(0), decimals);
- signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerAssetData,
- takerAssetData,
- makerFee,
- takerFee,
- makerAddress,
- takerAddress,
- fillableAmount,
- takerAddress,
- );
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)();
- await orderWatcher.addOrderAsync(signedOrder);
- orderWatcher.subscribe(callback);
- await contractWrappers.erc20Token.setProxyAllowanceAsync(
- zrxTokenAddress,
- makerAddress,
- new BigNumber(0),
- );
- })().catch(done);
- });
- describe('remainingFillable(M|T)akerTokenAmount', () => {
- it('should calculate correct remaining fillable', (done: DoneCallback) => {
- (async () => {
- const takerFillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(10), decimals);
- const makerFillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(20), decimals);
- signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- makerFillableAmount,
- takerFillableAmount,
- );
- const fillAmountInBaseUnits = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.true();
- const validOrderState = orderState as OrderStateValid;
- expect(validOrderState.orderHash).to.be.equal(orderHash);
- const orderRelevantState = validOrderState.orderRelevantState;
- expect(orderRelevantState.remainingFillableMakerAssetAmount).to.be.bignumber.equal(
- Web3Wrapper.toBaseUnitAmount(new BigNumber(16), decimals),
- );
- expect(orderRelevantState.remainingFillableTakerAssetAmount).to.be.bignumber.equal(
- Web3Wrapper.toBaseUnitAmount(new BigNumber(8), decimals),
- );
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.exchange.fillOrderAsync(signedOrder, fillAmountInBaseUnits, takerAddress);
- })().catch(done);
- });
- it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
-
- const changedMakerApprovalAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(3), decimals);
- await orderWatcher.addOrderAsync(signedOrder);
-
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- const validOrderState = orderState as OrderStateValid;
- const orderRelevantState = validOrderState.orderRelevantState;
- expect(orderRelevantState.remainingFillableMakerAssetAmount).to.be.bignumber.equal(
- changedMakerApprovalAmount,
- );
- expect(orderRelevantState.remainingFillableTakerAssetAmount).to.be.bignumber.equal(
- changedMakerApprovalAmount,
- );
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.erc20Token.setProxyAllowanceAsync(
- makerTokenAddress,
- makerAddress,
- changedMakerApprovalAmount,
- );
- })().catch(done);
- });
- it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
-
- const makerBalance = await contractWrappers.erc20Token.getBalanceAsync(
- makerTokenAddress,
- makerAddress,
- );
-
- const remainingAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(1), decimals);
- const transferAmount = makerBalance.minus(remainingAmount);
- await orderWatcher.addOrderAsync(signedOrder);
-
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.true();
- const validOrderState = orderState as OrderStateValid;
- const orderRelevantState = validOrderState.orderRelevantState;
- expect(orderRelevantState.remainingFillableMakerAssetAmount).to.be.bignumber.equal(
- remainingAmount,
- );
- expect(orderRelevantState.remainingFillableTakerAssetAmount).to.be.bignumber.equal(
- remainingAmount,
- );
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.erc20Token.transferAsync(
- makerTokenAddress,
- makerAddress,
- constants.NULL_ADDRESS,
- transferAmount,
- );
- })().catch(done);
- });
- it('should equal ratio amount when fee balance is lowered', (done: DoneCallback) => {
- (async () => {
- const takerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(0), decimals);
- const makerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals);
- signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerAssetData,
- takerAssetData,
- makerFee,
- takerFee,
- makerAddress,
- takerAddress,
- fillableAmount,
- feeRecipient,
- );
-
- const remainingFeeAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(3), decimals);
-
- const remainingTokenAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(4), decimals);
- const transferTokenAmount = makerFee.minus(remainingTokenAmount);
- await orderWatcher.addOrderAsync(signedOrder);
-
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- const validOrderState = orderState as OrderStateValid;
- const orderRelevantState = validOrderState.orderRelevantState;
- expect(orderRelevantState.remainingFillableMakerAssetAmount).to.be.bignumber.equal(
- remainingFeeAmount,
- );
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.erc20Token.setProxyAllowanceAsync(
- zrxTokenAddress,
- makerAddress,
- remainingFeeAmount,
- );
- await contractWrappers.erc20Token.transferAsync(
- makerTokenAddress,
- makerAddress,
- constants.NULL_ADDRESS,
- transferTokenAmount,
- );
- })().catch(done);
- });
- it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => {
- (async () => {
- const takerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(0), decimals);
- const makerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
- signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerAssetData,
- takerAssetData,
- makerFee,
- takerFee,
- makerAddress,
- takerAddress,
- fillableAmount,
- feeRecipient,
- );
-
- await orderWatcher.addOrderAsync(signedOrder);
-
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- const validOrderState = orderState as OrderStateValid;
- const orderRelevantState = validOrderState.orderRelevantState;
- expect(orderRelevantState.remainingFillableMakerAssetAmount).to.be.bignumber.equal(
- fillableAmount,
- );
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.erc20Token.setProxyAllowanceAsync(
- makerTokenAddress,
- makerAddress,
- Web3Wrapper.toBaseUnitAmount(new BigNumber(100), decimals),
- );
- })().catch(done);
- });
- });
- it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
-
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderCancelled);
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.exchange.cancelOrderAsync(signedOrder);
- })().catch(done);
- });
- it('should emit orderStateInvalid when within rounding error range after a partial fill', (done: DoneCallback) => {
- (async () => {
- const fillAmountInBaseUnits = new BigNumber(2);
- const makerAssetAmount = new BigNumber(1001);
- const takerAssetAmount = new BigNumber(3);
- signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- makerAssetAmount,
- takerAssetAmount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderFillRoundingError);
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.exchange.fillOrderAsync(signedOrder, fillAmountInBaseUnits, takerAddress);
- })().catch(done);
- });
- describe('erc721', () => {
- let makerErc721AssetData: string;
- let makerErc721TokenAddress: string;
- const tokenId = new BigNumber(42);
- [makerErc721TokenAddress] = tokenUtils.getDummyERC721TokenAddresses();
- makerErc721AssetData = assetDataUtils.encodeERC721AssetData(makerErc721TokenAddress, tokenId);
- const fillableErc721Amount = new BigNumber(1);
- it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerErc721AssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableErc721Amount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.erc721Token.setApprovalAsync(
- makerErc721TokenAddress,
- constants.NULL_ADDRESS,
- tokenId,
- );
- })().catch(done);
- });
- it('should emit orderStateInvalid when maker allowance for all set to 0 for watched order', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerErc721AssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableErc721Amount,
- );
- await contractWrappers.erc721Token.setApprovalAsync(
- makerErc721TokenAddress,
- constants.NULL_ADDRESS,
- tokenId,
- );
- let isApproved = true;
- await contractWrappers.erc721Token.setProxyApprovalForAllAsync(
- makerErc721TokenAddress,
- makerAddress,
- isApproved,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
- });
- orderWatcher.subscribe(callback);
- isApproved = false;
- await contractWrappers.erc721Token.setProxyApprovalForAllAsync(
- makerErc721TokenAddress,
- makerAddress,
- isApproved,
- );
- })().catch(done);
- });
- it('should emit orderStateInvalid when maker moves NFT backing watched order', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerErc721AssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableErc721Amount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.erc721Token.transferFromAsync(
- makerErc721TokenAddress,
- coinbase,
- makerAddress,
- tokenId,
- );
- })().catch(done);
- });
- });
- describe('multiAsset', async () => {
- const tokenId = new BigNumber(42);
- const [makerErc721TokenAddress] = tokenUtils.getDummyERC721TokenAddresses();
- const makerErc721AssetData = assetDataUtils.encodeERC721AssetData(makerErc721TokenAddress, tokenId);
- const fillableErc721Amount = new BigNumber(1);
- const [makerErc20TokenAddress] = tokenUtils.getDummyERC20TokenAddresses();
- const makerErc20AssetData = assetDataUtils.encodeERC20AssetData(makerErc20TokenAddress);
- const fillableErc20Amount = new BigNumber(2);
- const multiAssetAmounts = [fillableErc721Amount, fillableErc20Amount];
- const nestedAssetData = [makerErc721AssetData, makerErc20AssetData];
- const makerMultiAssetData = assetDataUtils.encodeMultiAssetData(multiAssetAmounts, nestedAssetData);
- it('should emit orderStateInvalid when maker allowance of ERC721 token set to 0 for watched order', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerMultiAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableErc721Amount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.erc721Token.setApprovalAsync(
- makerErc721TokenAddress,
- constants.NULL_ADDRESS,
- tokenId,
- );
- })().catch(done);
- });
- it('should emit orderStateInvalid when maker allowance for all of ERC721 token set to 0 for watched order', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerMultiAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableErc721Amount,
- );
- await contractWrappers.erc721Token.setApprovalAsync(
- makerErc721TokenAddress,
- constants.NULL_ADDRESS,
- tokenId,
- );
- let isApproved = true;
- await contractWrappers.erc721Token.setProxyApprovalForAllAsync(
- makerErc721TokenAddress,
- makerAddress,
- isApproved,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
- });
- orderWatcher.subscribe(callback);
- isApproved = false;
- await contractWrappers.erc721Token.setProxyApprovalForAllAsync(
- makerErc721TokenAddress,
- makerAddress,
- isApproved,
- );
- })().catch(done);
- });
- it('should emit orderStateInvalid when maker moves ERC721 backing watched order', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerMultiAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableErc721Amount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.erc721Token.transferFromAsync(
- makerErc721TokenAddress,
- coinbase,
- makerAddress,
- tokenId,
- );
- })().catch(done);
- });
- it('should emit orderStateInvalid when maker allowance of ERC20 token set to 0 for watched order', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerMultiAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableErc721Amount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
- });
- orderWatcher.subscribe(callback);
- await contractWrappers.erc20Token.setProxyAllowanceAsync(
- makerErc20TokenAddress,
- makerAddress,
- new BigNumber(0),
- );
- })().catch(done);
- });
- it('should not emit an orderState event when irrelevant ERC20 Transfer event received', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerMultiAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((_orderState: OrderState) => {
- throw new Error('OrderState callback fired for irrelevant order');
- });
- orderWatcher.subscribe(callback);
- const notTheMaker = userAddresses[0];
- const anyRecipient = takerAddress;
- const transferAmount = new BigNumber(2);
- await contractWrappers.erc20Token.transferAsync(
- makerTokenAddress,
- notTheMaker,
- anyRecipient,
- transferAmount,
- );
- setTimeout(() => {
- done();
- }, TIMEOUT_MS);
- })().catch(done);
- });
- it('should emit orderStateInvalid when makerAddress moves ERC20 balance backing watched order', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerMultiAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
- });
- orderWatcher.subscribe(callback);
- const anyRecipient = takerAddress;
- const makerBalance = await contractWrappers.erc20Token.getBalanceAsync(
- makerTokenAddress,
- makerAddress,
- );
- await contractWrappers.erc20Token.transferAsync(
- makerTokenAddress,
- makerAddress,
- anyRecipient,
- makerBalance,
- );
- })().catch(done);
- });
- // TODO(abandeali1): The following test will fail until the MAP has been deployed and activated.
- it.skip('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
- (async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerMultiAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- await orderWatcher.addOrderAsync(signedOrder);
-
- const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => {
- expect(orderState.isValid).to.be.false();
- const invalidOrderState = orderState as OrderStateInvalid;
- expect(invalidOrderState.orderHash).to.be.equal(orderHash);
- expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
- });
- orderWatcher.subscribe(callback);
-
- await contractWrappers.exchange.fillOrderAsync(signedOrder, fillableAmount, takerAddress);
- })().catch(done);
- });
- });
- });
-}); // tslint:disable:max-file-line-count
diff --git a/packages/order-watcher/test/order_watcher_web_socket_server_test.ts b/packages/order-watcher/test/order_watcher_web_socket_server_test.ts
deleted file mode 100644
index 36135f65c..000000000
--- a/packages/order-watcher/test/order_watcher_web_socket_server_test.ts
+++ /dev/null
@@ -1,312 +0,0 @@
-import { ContractAddresses } from '@0x/contract-addresses';
-import { ContractWrappers } from '@0x/contract-wrappers';
-import { tokenUtils } from '@0x/contract-wrappers/lib/test/utils/token_utils';
-import { BlockchainLifecycle } from '@0x/dev-utils';
-import { FillScenarios } from '@0x/fill-scenarios';
-import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
-import { ExchangeContractErrs, OrderStateInvalid, SignedOrder } from '@0x/types';
-import { BigNumber, logUtils } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import * as chai from 'chai';
-import 'mocha';
-import * as WebSocket from 'websocket';
-
-import { OrderWatcherWebSocketServer } from '../src/order_watcher/order_watcher_web_socket_server';
-import { AddOrderRequest, OrderWatcherMethod, RemoveOrderRequest } from '../src/types';
-
-import { chaiSetup } from './utils/chai_setup';
-import { constants } from './utils/constants';
-import { migrateOnceAsync } from './utils/migrate';
-import { provider, web3Wrapper } from './utils/web3_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-
-interface WsMessage {
- data: string;
-}
-
-describe('OrderWatcherWebSocketServer', async () => {
- let contractWrappers: ContractWrappers;
- let wsServer: OrderWatcherWebSocketServer;
- let wsClient: WebSocket.w3cwebsocket;
- let wsClientTwo: WebSocket.w3cwebsocket;
- let fillScenarios: FillScenarios;
- let userAddresses: string[];
- let makerAssetData: string;
- let takerAssetData: string;
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let makerAddress: string;
- let takerAddress: string;
- let zrxTokenAddress: string;
- let signedOrder: SignedOrder;
- let orderHash: string;
- let addOrderPayload: AddOrderRequest;
- let removeOrderPayload: RemoveOrderRequest;
- let networkId: number;
- let contractAddresses: ContractAddresses;
- const decimals = constants.ZRX_DECIMALS;
- const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals);
-
- before(async () => {
- // Set up constants
- contractAddresses = await migrateOnceAsync();
- await blockchainLifecycle.startAsync();
- networkId = constants.TESTRPC_NETWORK_ID;
- const config = {
- networkId,
- contractAddresses,
- };
- contractWrappers = new ContractWrappers(provider, config);
- userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- zrxTokenAddress = contractAddresses.zrxToken;
- [makerAddress, takerAddress] = userAddresses;
- [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses();
- [makerAssetData, takerAssetData] = [
- assetDataUtils.encodeERC20AssetData(makerTokenAddress),
- assetDataUtils.encodeERC20AssetData(takerTokenAddress),
- ];
- fillScenarios = new FillScenarios(
- provider,
- userAddresses,
- zrxTokenAddress,
- contractAddresses.exchange,
- contractAddresses.erc20Proxy,
- contractAddresses.erc721Proxy,
- );
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerAssetData,
- takerAssetData,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- addOrderPayload = {
- id: 1,
- jsonrpc: '2.0',
- method: OrderWatcherMethod.AddOrder,
- params: { signedOrder },
- };
- removeOrderPayload = {
- id: 1,
- jsonrpc: '2.0',
- method: OrderWatcherMethod.RemoveOrder,
- params: { orderHash },
- };
- });
- after(async () => {
- await blockchainLifecycle.revertAsync();
- });
- beforeEach(async () => {
- // Prepare OrderWatcher WebSocket server
- const orderWatcherConfig = {
- isVerbose: true,
- };
- wsServer = new OrderWatcherWebSocketServer(provider, networkId, contractAddresses, orderWatcherConfig);
- wsServer.start();
- await blockchainLifecycle.startAsync();
- wsClient = new WebSocket.w3cwebsocket('ws://127.0.0.1:8080/');
- logUtils.log(`${new Date()} [Client] Connected.`);
- });
- afterEach(async () => {
- wsClient.close();
- await blockchainLifecycle.revertAsync();
- wsServer.stop();
- logUtils.log(`${new Date()} [Client] Closed.`);
- });
-
- it('responds to getStats requests correctly', (done: any) => {
- const payload = {
- id: 1,
- jsonrpc: '2.0',
- method: 'GET_STATS',
- };
- wsClient.onopen = () => wsClient.send(JSON.stringify(payload));
- wsClient.onmessage = (msg: any) => {
- const responseData = JSON.parse(msg.data);
- expect(responseData.id).to.be.eq(1);
- expect(responseData.jsonrpc).to.be.eq('2.0');
- expect(responseData.method).to.be.eq('GET_STATS');
- expect(responseData.result.orderCount).to.be.eq(0);
- done();
- };
- });
-
- it('throws an error when an invalid method is attempted', async () => {
- const invalidMethodPayload = {
- id: 1,
- jsonrpc: '2.0',
- method: 'BAD_METHOD',
- };
- wsClient.onopen = () => wsClient.send(JSON.stringify(invalidMethodPayload));
- const errorMsg = await onMessageAsync(wsClient, null);
- const errorData = JSON.parse(errorMsg.data);
- // tslint:disable-next-line:no-unused-expression
- expect(errorData.id).to.be.null;
- // tslint:disable-next-line:no-unused-expression
- expect(errorData.method).to.be.null;
- expect(errorData.jsonrpc).to.be.eq('2.0');
- expect(errorData.error).to.match(/^Error: Expected request to conform to schema/);
- });
-
- it('throws an error when jsonrpc field missing from request', async () => {
- const noJsonRpcPayload = {
- id: 1,
- method: 'GET_STATS',
- };
- wsClient.onopen = () => wsClient.send(JSON.stringify(noJsonRpcPayload));
- const errorMsg = await onMessageAsync(wsClient, null);
- const errorData = JSON.parse(errorMsg.data);
- // tslint:disable-next-line:no-unused-expression
- expect(errorData.method).to.be.null;
- expect(errorData.jsonrpc).to.be.eq('2.0');
- expect(errorData.error).to.match(/^Error: Expected request to conform to schema/);
- });
-
- it('throws an error when we try to add an order without a signedOrder', async () => {
- const noSignedOrderAddOrderPayload = {
- id: 1,
- jsonrpc: '2.0',
- method: 'ADD_ORDER',
- orderHash: '0x7337e2f2a9aa2ed6afe26edc2df7ad79c3ffa9cf9b81a964f707ea63f5272355',
- };
- wsClient.onopen = () => wsClient.send(JSON.stringify(noSignedOrderAddOrderPayload));
- const errorMsg = await onMessageAsync(wsClient, null);
- const errorData = JSON.parse(errorMsg.data);
- // tslint:disable-next-line:no-unused-expression
- expect(errorData.id).to.be.null;
- // tslint:disable-next-line:no-unused-expression
- expect(errorData.method).to.be.null;
- expect(errorData.jsonrpc).to.be.eq('2.0');
- expect(errorData.error).to.match(/^Error: Expected request to conform to schema/);
- });
-
- it('throws an error when we try to add a bad signedOrder', async () => {
- const invalidAddOrderPayload = {
- id: 1,
- jsonrpc: '2.0',
- method: 'ADD_ORDER',
- signedOrder: {
- makerAddress: '0x0',
- },
- };
- wsClient.onopen = () => wsClient.send(JSON.stringify(invalidAddOrderPayload));
- const errorMsg = await onMessageAsync(wsClient, null);
- const errorData = JSON.parse(errorMsg.data);
- // tslint:disable-next-line:no-unused-expression
- expect(errorData.id).to.be.null;
- // tslint:disable-next-line:no-unused-expression
- expect(errorData.method).to.be.null;
- expect(errorData.error).to.match(/^Error: Expected request to conform to schema/);
- });
-
- it('executes addOrder and removeOrder requests correctly', async () => {
- wsClient.onopen = () => wsClient.send(JSON.stringify(addOrderPayload));
- const addOrderMsg = await onMessageAsync(wsClient, OrderWatcherMethod.AddOrder);
- const addOrderData = JSON.parse(addOrderMsg.data);
- expect(addOrderData.method).to.be.eq('ADD_ORDER');
- expect((wsServer as any)._orderWatcher._orderByOrderHash).to.deep.include({
- [orderHash]: signedOrder,
- });
-
- const clientOnMessagePromise = onMessageAsync(wsClient, OrderWatcherMethod.RemoveOrder);
- wsClient.send(JSON.stringify(removeOrderPayload));
- const removeOrderMsg = await clientOnMessagePromise;
- const removeOrderData = JSON.parse(removeOrderMsg.data);
- expect(removeOrderData.method).to.be.eq('REMOVE_ORDER');
- expect((wsServer as any)._orderWatcher._orderByOrderHash).to.not.deep.include({
- [orderHash]: signedOrder,
- });
- });
-
- it('broadcasts orderStateInvalid message when makerAddress allowance set to 0 for watched order', async () => {
- // Add the regular order
- wsClient.onopen = () => wsClient.send(JSON.stringify(addOrderPayload));
-
- // We register the onMessage callback before calling `setProxyAllowanceAsync` which we
- // expect will cause a message to be emitted. We do now "await" here, since we want to
- // check for messages _after_ calling `setProxyAllowanceAsync`
- const clientOnMessagePromise = onMessageAsync(wsClient, OrderWatcherMethod.Update);
-
- // Set the allowance to 0
- await contractWrappers.erc20Token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, new BigNumber(0));
-
- // We now await the `onMessage` promise to check for the message
- const orderWatcherUpdateMsg = await clientOnMessagePromise;
- const orderWatcherUpdateData = JSON.parse(orderWatcherUpdateMsg.data);
- expect(orderWatcherUpdateData.method).to.be.eq('UPDATE');
- const invalidOrderState = orderWatcherUpdateData.result as OrderStateInvalid;
- expect(invalidOrderState.isValid).to.be.false();
- expect(invalidOrderState.orderHash).to.be.eq(orderHash);
- expect(invalidOrderState.error).to.be.eq(ExchangeContractErrs.InsufficientMakerAllowance);
- });
-
- it('broadcasts to multiple clients when an order backing ZRX allowance changes', async () => {
- // Prepare order
- const makerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
- const takerFee = Web3Wrapper.toBaseUnitAmount(new BigNumber(0), decimals);
- const nonZeroMakerFeeSignedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerAssetData,
- takerAssetData,
- makerFee,
- takerFee,
- makerAddress,
- takerAddress,
- fillableAmount,
- takerAddress,
- );
- const nonZeroMakerFeeOrderPayload = {
- id: 1,
- jsonrpc: '2.0',
- method: 'ADD_ORDER',
- params: {
- signedOrder: nonZeroMakerFeeSignedOrder,
- },
- };
-
- // Set up a second client and have it add the order
- wsClientTwo = new WebSocket.w3cwebsocket('ws://127.0.0.1:8080/');
- logUtils.log(`${new Date()} [Client] Connected.`);
- wsClientTwo.onopen = () => wsClientTwo.send(JSON.stringify(nonZeroMakerFeeOrderPayload));
-
- // Setup the onMessage callbacks, but don't await them yet
- const clientOneOnMessagePromise = onMessageAsync(wsClient, OrderWatcherMethod.Update);
- const clientTwoOnMessagePromise = onMessageAsync(wsClientTwo, OrderWatcherMethod.Update);
-
- // Change the allowance
- await contractWrappers.erc20Token.setProxyAllowanceAsync(zrxTokenAddress, makerAddress, new BigNumber(0));
-
- // Check that both clients receive the emitted event by awaiting the onMessageAsync promises
- let updateMsg = await clientOneOnMessagePromise;
- let updateData = JSON.parse(updateMsg.data);
- let orderState = updateData.result as OrderStateInvalid;
- expect(orderState.isValid).to.be.false();
- expect(orderState.error).to.be.eq('INSUFFICIENT_MAKER_FEE_ALLOWANCE');
-
- updateMsg = await clientTwoOnMessagePromise;
- updateData = JSON.parse(updateMsg.data);
- orderState = updateData.result as OrderStateInvalid;
- expect(orderState.isValid).to.be.false();
- expect(orderState.error).to.be.eq('INSUFFICIENT_MAKER_FEE_ALLOWANCE');
-
- wsClientTwo.close();
- logUtils.log(`${new Date()} [Client] Closed.`);
- });
-});
-
-// HACK: createFillableSignedOrderAsync is Promise-based, which forces us
-// to use Promises instead of the done() callbacks for tests.
-// onmessage callback must thus be wrapped as a Promise.
-async function onMessageAsync(client: WebSocket.w3cwebsocket, method: string | null): Promise<WsMessage> {
- return new Promise<WsMessage>(resolve => {
- client.onmessage = (msg: WsMessage) => {
- const data = JSON.parse(msg.data);
- if (data.method === method) {
- resolve(msg);
- }
- };
- });
-}
diff --git a/packages/order-watcher/test/utils/chai_setup.ts b/packages/order-watcher/test/utils/chai_setup.ts
deleted file mode 100644
index 1a8733093..000000000
--- a/packages/order-watcher/test/utils/chai_setup.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import * as chai from 'chai';
-import chaiAsPromised = require('chai-as-promised');
-import ChaiBigNumber = require('chai-bignumber');
-import * as dirtyChai from 'dirty-chai';
-
-export const chaiSetup = {
- configure(): void {
- chai.config.includeStack = true;
- chai.use(ChaiBigNumber());
- chai.use(dirtyChai);
- chai.use(chaiAsPromised);
- },
-};
diff --git a/packages/order-watcher/test/utils/constants.ts b/packages/order-watcher/test/utils/constants.ts
deleted file mode 100644
index 78037647c..000000000
--- a/packages/order-watcher/test/utils/constants.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export const constants = {
- NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
- TESTRPC_NETWORK_ID: 50,
- ZRX_DECIMALS: 18,
-};
diff --git a/packages/order-watcher/test/utils/migrate.ts b/packages/order-watcher/test/utils/migrate.ts
deleted file mode 100644
index 665ce0faa..000000000
--- a/packages/order-watcher/test/utils/migrate.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { ContractAddresses } from '@0x/contract-addresses';
-import { devConstants } from '@0x/dev-utils';
-import { runMigrationsOnceAsync } from '@0x/migrations';
-
-import { provider } from './web3_wrapper';
-
-/**
- * Configures and runs the migrations exactly once. Any subsequent times this is
- * called, it returns the cached addresses.
- * @returns The addresses of contracts that were deployed during the migrations.
- */
-export async function migrateOnceAsync(): Promise<ContractAddresses> {
- const txDefaults = {
- gas: devConstants.GAS_LIMIT,
- from: devConstants.TESTRPC_FIRST_ADDRESS,
- };
- return runMigrationsOnceAsync(provider, txDefaults);
-}
diff --git a/packages/order-watcher/test/utils/web3_wrapper.ts b/packages/order-watcher/test/utils/web3_wrapper.ts
deleted file mode 100644
index accfcb7fe..000000000
--- a/packages/order-watcher/test/utils/web3_wrapper.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { web3Factory } from '@0x/dev-utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import { Provider } from 'ethereum-types';
-
-const provider: Provider = web3Factory.getRpcProvider({ shouldUseInProcessGanache: true });
-const web3Wrapper = new Web3Wrapper(provider);
-
-export { provider, web3Wrapper };