diff options
Diffstat (limited to 'packages/order-watcher/test')
-rw-r--r-- | packages/order-watcher/test/expiration_watcher_test.ts | 199 | ||||
-rw-r--r-- | packages/order-watcher/test/global_hooks.ts | 6 | ||||
-rw-r--r-- | packages/order-watcher/test/order_watcher_test.ts | 887 | ||||
-rw-r--r-- | packages/order-watcher/test/order_watcher_web_socket_server_test.ts | 312 | ||||
-rw-r--r-- | packages/order-watcher/test/utils/chai_setup.ts | 13 | ||||
-rw-r--r-- | packages/order-watcher/test/utils/constants.ts | 5 | ||||
-rw-r--r-- | packages/order-watcher/test/utils/migrate.ts | 18 | ||||
-rw-r--r-- | packages/order-watcher/test/utils/web3_wrapper.ts | 8 |
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 }; |