diff --git a/libs/orders/src/lib/order-hooks/use-order-validation.spec.tsx b/libs/orders/src/lib/order-hooks/use-order-validation.spec.tsx index b91c408bf..db4c97454 100644 --- a/libs/orders/src/lib/order-hooks/use-order-validation.spec.tsx +++ b/libs/orders/src/lib/order-hooks/use-order-validation.spec.tsx @@ -90,107 +90,146 @@ function setup( return renderHook(() => useOrderValidation({ ...defaultOrder, ...props })); } -it('Returns empty string when given valid data', () => { - const { result } = setup(); - expect(result.current).toEqual(''); -}); - -it('Returns an error message when no keypair found', async () => { - const { result } = setup(defaultOrder, { keypair: null }); - expect(result.current).toEqual(''); -}); - -it('Returns an error message when the keypair is tainted', async () => { - const { result } = setup(defaultOrder, { - keypair: { ...defaultWalletContext.keypair, tainted: true }, +describe(`useOrderValidation`, () => { + it('Returns empty string when given valid data', () => { + const { result } = setup(); + expect(result.current).toStrictEqual({ isDisabled: false, message: `` }); }); - expect(result.current).toEqual(''); -}); -it.each` - state | errorMessage - ${MarketState.Cancelled} | ${ERROR.MARKET_INACTIVE} - ${MarketState.Closed} | ${ERROR.MARKET_INACTIVE} - ${MarketState.Rejected} | ${ERROR.MARKET_INACTIVE} - ${MarketState.Settled} | ${ERROR.MARKET_INACTIVE} - ${MarketState.TradingTerminated} | ${ERROR.MARKET_INACTIVE} - ${MarketState.Suspended} | ${ERROR.MARKET_SUSPENDED} - ${MarketState.Pending} | ${ERROR.MARKET_WAITING} - ${MarketState.Proposed} | ${ERROR.MARKET_WAITING} -`( - 'Returns an error message for "$marketState" market', - async ({ state, errorMessage }) => { - const { result } = setup({ market: { ...defaultOrder.market, state } }); - expect(result.current).toEqual(errorMessage); - } -); - -it.each` - tradingMode | errorMessage - ${MarketTradingMode.BatchAuction} | ${ERROR.MARKET_CONTINUOUS_LIMIT} - ${MarketTradingMode.MonitoringAuction} | ${ERROR.MARKET_CONTINUOUS_LIMIT} - ${MarketTradingMode.OpeningAuction} | ${ERROR.MARKET_CONTINUOUS_LIMIT} -`( - 'Returns an error message when trying to submit a non-limit order for a "$tradingMode" market', - async ({ tradingMode, errorMessage }) => { - const { result } = setup({ - market: { ...defaultOrder.market, tradingMode }, - orderType: VegaWalletOrderType.Market, - }); - expect(result.current).toEqual(errorMessage); - } -); - -it.each` - tradingMode | orderTimeInForce | errorMessage - ${MarketTradingMode.BatchAuction} | ${VegaWalletOrderTimeInForce.FOK} | ${ERROR.MARKET_CONTINUOUS_TIF} - ${MarketTradingMode.MonitoringAuction} | ${VegaWalletOrderTimeInForce.FOK} | ${ERROR.MARKET_CONTINUOUS_TIF} - ${MarketTradingMode.OpeningAuction} | ${VegaWalletOrderTimeInForce.FOK} | ${ERROR.MARKET_CONTINUOUS_TIF} - ${MarketTradingMode.BatchAuction} | ${VegaWalletOrderTimeInForce.IOC} | ${ERROR.MARKET_CONTINUOUS_TIF} - ${MarketTradingMode.MonitoringAuction} | ${VegaWalletOrderTimeInForce.IOC} | ${ERROR.MARKET_CONTINUOUS_TIF} - ${MarketTradingMode.OpeningAuction} | ${VegaWalletOrderTimeInForce.IOC} | ${ERROR.MARKET_CONTINUOUS_TIF} - ${MarketTradingMode.BatchAuction} | ${VegaWalletOrderTimeInForce.GFN} | ${ERROR.MARKET_CONTINUOUS_TIF} - ${MarketTradingMode.MonitoringAuction} | ${VegaWalletOrderTimeInForce.GFN} | ${ERROR.MARKET_CONTINUOUS_TIF} - ${MarketTradingMode.OpeningAuction} | ${VegaWalletOrderTimeInForce.GFN} | ${ERROR.MARKET_CONTINUOUS_TIF} -`( - 'Returns an error message when submitting a limit order with a "$orderTimeInForce" value to a "$tradingMode" market', - async ({ tradingMode, orderTimeInForce, errorMessage }) => { - const { result } = setup({ - market: { ...defaultOrder.market, tradingMode }, - orderType: VegaWalletOrderType.Limit, - orderTimeInForce, - }); - expect(result.current).toEqual(errorMessage); - } -); - -it.each` - fieldName | errorType | errorMessage - ${'size'} | ${'required'} | ${ERROR.FIELD_SIZE_REQ} - ${'size'} | ${'min'} | ${ERROR.FIELD_SIZE_MIN} - ${'price'} | ${'required'} | ${ERROR.FIELD_PRICE_REQ} - ${'price'} | ${'min'} | ${ERROR.FIELD_PRICE_MIN} -`( - 'Returns an error message when the order $fieldName "$errorType" validation fails', - async ({ fieldName, errorType, errorMessage }) => { - const { result } = setup({ - fieldErrors: { [fieldName]: { type: errorType } }, - }); - expect(result.current).toEqual(errorMessage); - } -); - -it('Returns an error message when the order size incorrectly has decimal values', async () => { - const { result } = setup({ - market: { ...market, positionDecimalPlaces: 0 }, - fieldErrors: { size: { type: 'validate', message: ERROR_SIZE_DECIMAL } }, + it('Returns an error message when no keypair found', async () => { + const { result } = setup(defaultOrder, { keypair: null }); + expect(result.current).toStrictEqual({ isDisabled: false, message: `` }); }); - expect(result.current).toEqual(ERROR.FIELD_PRICE_STEP_NULL); -}); -it('Returns an error message when the order size has more decimals then allowed', async () => { - const { result } = setup({ - fieldErrors: { size: { type: 'validate', message: ERROR_SIZE_DECIMAL } }, + it('Returns an error message when the keypair is tainted', async () => { + const { result } = setup(defaultOrder, { + keypair: { ...defaultWalletContext.keypair, tainted: true }, + }); + expect(result.current).toStrictEqual({ isDisabled: false, message: `` }); + }); + + it.each` + state + ${MarketState.Settled} + ${MarketState.Rejected} + ${MarketState.TradingTerminated} + `( + 'Returns an error message for market state when no longer accepting orders', + async ({ state }) => { + const { result } = setup({ market: { ...defaultOrder.market, state } }); + expect(result.current).toStrictEqual({ + isDisabled: true, + message: `This market is ${state.toLowerCase()} and no longer accepting orders`, + }); + } + ); + + it.each` + state + ${MarketState.Suspended} + ${MarketState.Pending} + ${MarketState.Cancelled} + ${MarketState.Proposed} + ${MarketState.Closed} + `( + 'Returns an error message for market state suspended or pending', + async ({ state }) => { + const { result } = setup({ + market: { + ...defaultOrder.market, + state, + tradingMode: MarketTradingMode.BatchAuction, + }, + }); + expect(result.current).toStrictEqual({ + isDisabled: false, + message: `This market is ${state.toLowerCase()} and only accepting liquidity orders`, + }); + } + ); + + it.each` + tradingMode | errorMessage + ${MarketTradingMode.BatchAuction} | ${ERROR.MARKET_CONTINUOUS_LIMIT} + ${MarketTradingMode.MonitoringAuction} | ${ERROR.MARKET_CONTINUOUS_LIMIT} + ${MarketTradingMode.OpeningAuction} | ${ERROR.MARKET_CONTINUOUS_LIMIT} + `( + `Returns an error message when trying to submit a non-limit order for a "$tradingMode" market`, + async ({ tradingMode, errorMessage }) => { + const { result } = setup({ + market: { ...defaultOrder.market, tradingMode }, + orderType: VegaWalletOrderType.Market, + }); + expect(result.current).toStrictEqual({ + isDisabled: true, + message: errorMessage, + }); + } + ); + + it.each` + tradingMode | orderTimeInForce | errorMessage + ${MarketTradingMode.BatchAuction} | ${VegaWalletOrderTimeInForce.FOK} | ${ERROR.MARKET_CONTINUOUS_TIF} + ${MarketTradingMode.MonitoringAuction} | ${VegaWalletOrderTimeInForce.FOK} | ${ERROR.MARKET_CONTINUOUS_TIF} + ${MarketTradingMode.OpeningAuction} | ${VegaWalletOrderTimeInForce.FOK} | ${ERROR.MARKET_CONTINUOUS_TIF} + ${MarketTradingMode.BatchAuction} | ${VegaWalletOrderTimeInForce.IOC} | ${ERROR.MARKET_CONTINUOUS_TIF} + ${MarketTradingMode.MonitoringAuction} | ${VegaWalletOrderTimeInForce.IOC} | ${ERROR.MARKET_CONTINUOUS_TIF} + ${MarketTradingMode.OpeningAuction} | ${VegaWalletOrderTimeInForce.IOC} | ${ERROR.MARKET_CONTINUOUS_TIF} + ${MarketTradingMode.BatchAuction} | ${VegaWalletOrderTimeInForce.GFN} | ${ERROR.MARKET_CONTINUOUS_TIF} + ${MarketTradingMode.MonitoringAuction} | ${VegaWalletOrderTimeInForce.GFN} | ${ERROR.MARKET_CONTINUOUS_TIF} + ${MarketTradingMode.OpeningAuction} | ${VegaWalletOrderTimeInForce.GFN} | ${ERROR.MARKET_CONTINUOUS_TIF} + `( + `Returns an error message when submitting a limit order with a "$orderTimeInForce" value to a "$tradingMode" market`, + async ({ tradingMode, orderTimeInForce, errorMessage }) => { + const { result } = setup({ + market: { ...defaultOrder.market, tradingMode }, + orderType: VegaWalletOrderType.Limit, + orderTimeInForce, + }); + expect(result.current).toStrictEqual({ + isDisabled: true, + message: errorMessage, + }); + } + ); + + it.each` + fieldName | errorType | errorMessage + ${`size`} | ${`required`} | ${ERROR.FIELD_SIZE_REQ} + ${`size`} | ${`min`} | ${ERROR.FIELD_SIZE_MIN} + ${`price`} | ${`required`} | ${ERROR.FIELD_PRICE_REQ} + ${`price`} | ${`min`} | ${ERROR.FIELD_PRICE_MIN} + `( + `Returns an error message when the order $fieldName "$errorType" validation fails`, + async ({ fieldName, errorType, errorMessage }) => { + const { result } = setup({ + fieldErrors: { [fieldName]: { type: errorType } }, + }); + expect(result.current).toStrictEqual({ + isDisabled: true, + message: errorMessage, + }); + } + ); + + it('Returns an error message when the order size incorrectly has decimal values', async () => { + const { result } = setup({ + market: { ...market, positionDecimalPlaces: 0 }, + fieldErrors: { size: { type: `validate`, message: ERROR_SIZE_DECIMAL } }, + }); + expect(result.current).toStrictEqual({ + isDisabled: true, + message: ERROR.FIELD_PRICE_STEP_NULL, + }); + }); + + it('Returns an error message when the order size has more decimals then allowed', async () => { + const { result } = setup({ + fieldErrors: { size: { type: `validate`, message: ERROR_SIZE_DECIMAL } }, + }); + expect(result.current).toStrictEqual({ + isDisabled: true, + message: ERROR.FIELD_PRICE_STEP_DECIMAL, + }); }); - expect(result.current).toEqual(ERROR.FIELD_PRICE_STEP_DECIMAL); }); diff --git a/libs/orders/src/lib/order-hooks/use-order-validation.tsx b/libs/orders/src/lib/order-hooks/use-order-validation.tsx index 09733ac14..a750414f6 100644 --- a/libs/orders/src/lib/order-hooks/use-order-validation.tsx +++ b/libs/orders/src/lib/order-hooks/use-order-validation.tsx @@ -40,25 +40,32 @@ export const useOrderValidation = ({ }; } - if ([MarketState.Cancelled, MarketState.Rejected].includes(market.state)) { + if ( + [ + MarketState.Settled, + MarketState.Rejected, + MarketState.TradingTerminated, + ].includes(market.state) + ) { return { isDisabled: true, message: t( - `This market is ${market.state.toLowerCase()} and not accepting orders` + `This market is ${market.state.toLowerCase()} and no longer accepting orders` ), }; } if ( [ + MarketState.Suspended, + MarketState.Pending, + MarketState.Proposed, MarketState.Cancelled, MarketState.Closed, - MarketState.Proposed, - MarketState.Settled, ].includes(market.state) ) { return { - isDisabled: true, + isDisabled: false, message: t( `This market is ${market.state.toLowerCase()} and only accepting liquidity orders` ), @@ -96,7 +103,7 @@ export const useOrderValidation = ({ return { isDisabled: false, message: t( - 'This market is currently suspended and only accepting liquidity orders' + `This market is ${market.state.toLowerCase()} and only accepting liquidity orders` ), }; } @@ -108,7 +115,7 @@ export const useOrderValidation = ({ return { isDisabled: false, message: t( - 'This market is not active yet and can accept only liquidity orders' + `This market is ${market.state.toLowerCase()} and only accepting liquidity orders` ), }; } diff --git a/libs/wallet/src/vega-transaction-dialog/vega-transaction-dialog.tsx b/libs/wallet/src/vega-transaction-dialog/vega-transaction-dialog.tsx index bb77005a9..20a395b70 100644 --- a/libs/wallet/src/vega-transaction-dialog/vega-transaction-dialog.tsx +++ b/libs/wallet/src/vega-transaction-dialog/vega-transaction-dialog.tsx @@ -8,6 +8,7 @@ import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers'; import { useEnvironment } from '@vegaprotocol/environment'; import { OrderType } from '@vegaprotocol/types'; import type { Order } from '../wallet-types'; +import get from 'lodash/get'; export interface VegaTransactionDialogProps { orderDialogOpen: boolean; @@ -117,7 +118,8 @@ export const VegaDialog = ({ > {transaction.error && (
-            {JSON.stringify(transaction.error, null, 2)}
+            {get(transaction.error, 'error') ??
+              JSON.stringify(transaction.error, null, 2)}
           
)}