vega-frontend-monorepo/apps/trading/hooks/use-order-submit.spec.tsx
Matthew Russell 313e6e1217
Feat/63 Deal ticket (#82)
* scaffold dealticket package, remove trading views from react-helpers

* add deal ticket component, add intent utils, expand dialog and form group styles

* add splash component, show market not found message if market doesnt exist

* tidy up error handling

* add handleError method for vega tx hook

* add better testname for provider test, flesh out tests a bit more for deal ticket

* Add unit tests for useVegaTransaction and useOrderSubmit hooks

* add wrapper component for order dialog styles

* add vega styled loader to ui toolkit and use in order dialog

* add title prop to order dialog

* split limit and market tickets into own files

* add button radio component

* revert dialog styles

* move splash component to ui-toolkit, add story

* convert intent to enum

* Make button always type=button unless type prop is passed

* inline filter logic for tif selector

* add date-fns, add datetime to helpers

* add order types to wallet package, make price undefined if order type is market

* use enums in deal ticket logic

* tidy up order state by moving submit and transaction hooks out of deal ticket

* add comment for dialog styles

* remove decimal from price input

* add types package, delete old generated types from trading project

* rename types package to graphql

* update generate command to point to correct locations

* fix use order submit test

* use intent shadow helper

* remove date-fns and format manually, update submit button error to use input-error

* remove stray console.log
2022-03-17 12:35:46 -07:00

154 lines
4.2 KiB
TypeScript

import { MockedProvider } from '@apollo/client/testing';
import { act, renderHook } from '@testing-library/react-hooks';
import { Order } from '@vegaprotocol/deal-ticket';
import {
VegaKeyExtended,
VegaWalletContext,
VegaWalletContextShape,
} from '@vegaprotocol/wallet';
import { OrderSide, OrderTimeInForce, OrderType } from '@vegaprotocol/wallet';
import { ReactNode } from 'react';
import { useOrderSubmit } from './use-order-submit';
import { VegaTxStatus } from './use-vega-transaction';
const defaultWalletContext = {
keypair: null,
keypairs: [],
sendTx: jest.fn().mockReturnValue(Promise.resolve(null)),
connect: jest.fn(),
disconnect: jest.fn(),
selectPublicKey: jest.fn(),
connector: null,
};
function setup(
context?: Partial<VegaWalletContextShape>,
market = { id: 'market-id', decimalPlaces: 2 }
) {
const wrapper = ({ children }: { children: ReactNode }) => (
<MockedProvider>
<VegaWalletContext.Provider
value={{ ...defaultWalletContext, ...context }}
>
{children}
</VegaWalletContext.Provider>
</MockedProvider>
);
return renderHook(() => useOrderSubmit(market), { wrapper });
}
test('Has the correct default state', () => {
const { result } = setup();
expect(typeof result.current.submit).toEqual('function');
expect(typeof result.current.reset).toEqual('function');
expect(result.current.transaction.status).toEqual(VegaTxStatus.Default);
expect(result.current.transaction.hash).toEqual(null);
expect(result.current.transaction.error).toEqual(null);
});
test('Should not sendTx if no keypair', async () => {
const mockSendTx = jest.fn();
const { result } = setup({ sendTx: mockSendTx, keypairs: [], keypair: null });
await act(async () => {
result.current.submit({} as Order);
});
expect(mockSendTx).not.toHaveBeenCalled();
});
test('Should not sendTx side is not specified', async () => {
const mockSendTx = jest.fn();
const keypair = {
pub: '0x123',
} as VegaKeyExtended;
const { result } = setup({
sendTx: mockSendTx,
keypairs: [keypair],
keypair,
});
await act(async () => {
result.current.submit({} as Order);
});
expect(mockSendTx).not.toHaveBeenCalled();
});
test('Create an Id if a signature is returned', async () => {
const signature =
'597a7706491e6523c091bab1e4d655b62c45a224e80f6cd92ac366aa5dd9a070cc7dd3c6919cb07b81334b876c662dd43bdbe5e827c8baa17a089feb654fab0b';
const expectedId =
'2FE09B0E2E6ED35F8883802629C7D609D3CC2FC9CE3CEC0B7824A0D581BD3747';
const successObj = {
tx: {
inputData: 'input-data',
signature: {
algo: 'algo',
version: 1,
value: signature,
},
},
txHash: '0x123',
};
const mockSendTx = jest.fn().mockReturnValue(Promise.resolve(successObj));
const keypair = {
pub: '0x123',
} as VegaKeyExtended;
const { result } = setup({
sendTx: mockSendTx,
keypairs: [keypair],
keypair,
});
await act(async () => {
result.current.submit({
type: OrderType.Market,
side: OrderSide.Buy,
size: '1',
timeInForce: OrderTimeInForce.FOK,
});
});
expect(result.current.id).toEqual(expectedId);
});
test('Should submit a correctly formatted order', async () => {
const mockSendTx = jest.fn().mockReturnValue(Promise.resolve({}));
const keypair = {
pub: '0x123',
} as VegaKeyExtended;
const market = {
id: 'market-id',
decimalPlaces: 2,
};
const { result } = setup(
{
sendTx: mockSendTx,
keypairs: [keypair],
keypair,
},
market
);
const order = {
type: OrderType.Limit,
size: '10',
timeInForce: OrderTimeInForce.GTT,
side: OrderSide.Buy,
price: '1234567.89',
expiration: new Date('2022-01-01'),
};
await act(async () => {
result.current.submit(order);
});
expect(mockSendTx).toHaveBeenCalledWith({
pubKey: keypair.pub,
propagate: true,
orderSubmission: {
type: OrderType.Limit,
marketId: market.id, // Market provided from hook arugment
size: '10',
side: OrderSide.Buy,
timeInForce: OrderTimeInForce.GTT,
price: '123456789', // Decimal removed
expiresAt: order.expiration.getTime() + '000000', // Nanoseconds appened
},
});
});