fix: live validation in deal ticket (#2315)

* fix: live validation in deal ticket

* fix: live validation in deal ticket

* fix: live validation in deal ticket

* fix: live validation in deal ticket - fix test mock generate
This commit is contained in:
macqbat 2022-12-06 09:09:13 +01:00 committed by GitHub
parent 5cd6bf3d46
commit ca5c3bc21d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 98 additions and 75 deletions

View File

@ -198,7 +198,11 @@ describe('useOrderValidation', () => {
`( `(
'Returns an error message for market state when not accepting orders', 'Returns an error message for market state when not accepting orders',
({ state }) => { ({ state }) => {
const { result } = setup({ market: { ...defaultOrder.market, state } }); const market = {
...defaultOrder.market,
data: { ...defaultOrder.market.data, marketState: state },
};
const { result } = setup({ market });
expect(result.current).toStrictEqual({ expect(result.current).toStrictEqual({
isDisabled: true, isDisabled: true,
message: `This market is ${marketTranslations( message: `This market is ${marketTranslations(
@ -220,14 +224,19 @@ describe('useOrderValidation', () => {
balance: '0', balance: '0',
margin: '100', margin: '100',
balanceError: false, balanceError: false,
// asset,
}); });
const { result } = setup({
market: { const market = {
...defaultOrder.market, ...defaultOrder.market,
state, data: {
tradingMode: Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION, ...defaultOrder.market.data,
marketState: state,
marketTradingMode:
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
}, },
};
const { result } = setup({
market,
order: { order: {
...order, ...order,
type: Schema.OrderType.TYPE_LIMIT, type: Schema.OrderType.TYPE_LIMIT,
@ -252,8 +261,12 @@ describe('useOrderValidation', () => {
`( `(
`Returns an error message when trying to submit a non-limit order for a "$tradingMode" market`, `Returns an error message when trying to submit a non-limit order for a "$tradingMode" market`,
({ tradingMode, errorMessage }) => { ({ tradingMode, errorMessage }) => {
const market = {
...defaultOrder.market,
data: { ...defaultOrder.market.data, marketTradingMode: tradingMode },
};
const { result } = setup({ const { result } = setup({
market: { ...defaultOrder.market, tradingMode }, market,
order: { order: {
...order, ...order,
type: Schema.OrderType.TYPE_MARKET, type: Schema.OrderType.TYPE_MARKET,
@ -278,8 +291,12 @@ describe('useOrderValidation', () => {
`( `(
`Returns an error message when submitting a limit order with a "$orderTimeInForce" value to a "$tradingMode" market`, `Returns an error message when submitting a limit order with a "$orderTimeInForce" value to a "$tradingMode" market`,
({ tradingMode, orderTimeInForce, errorMessage }) => { ({ tradingMode, orderTimeInForce, errorMessage }) => {
const market = {
...defaultOrder.market,
data: { ...defaultOrder.market.data, marketTradingMode: tradingMode },
};
const { result } = setup({ const { result } = setup({
market: { ...defaultOrder.market, tradingMode }, market,
order: { order: {
...order, ...order,
type: Schema.OrderType.TYPE_LIMIT, type: Schema.OrderType.TYPE_LIMIT,
@ -382,14 +399,15 @@ describe('useOrderValidation', () => {
`( `(
'Returns error when market state is pending and size is wrong', 'Returns error when market state is pending and size is wrong',
({ state }) => { ({ state }) => {
const market = {
...defaultOrder.market,
data: { ...defaultOrder.market.data, marketState: state },
};
const { result } = setup({ const { result } = setup({
fieldErrors: { fieldErrors: {
size: { type: `validate`, message: DealTicket.ERROR_SIZE_DECIMAL }, size: { type: `validate`, message: DealTicket.ERROR_SIZE_DECIMAL },
}, },
market: { market,
...market,
state,
},
}); });
expect(result.current).toStrictEqual({ expect(result.current).toStrictEqual({
isDisabled: true, isDisabled: true,

View File

@ -169,13 +169,13 @@ export const useOrderValidation = ({
Schema.MarketState.STATE_TRADING_TERMINATED, Schema.MarketState.STATE_TRADING_TERMINATED,
Schema.MarketState.STATE_CANCELLED, Schema.MarketState.STATE_CANCELLED,
Schema.MarketState.STATE_CLOSED, Schema.MarketState.STATE_CLOSED,
].includes(market.state) ].includes(market.data.marketState)
) { ) {
return { return {
isDisabled: true, isDisabled: true,
message: t( message: t(
`This market is ${marketTranslations( `This market is ${marketTranslations(
market.state market.data.marketState
)} and not accepting orders` )} and not accepting orders`
), ),
section: DEAL_TICKET_SECTION.SUMMARY, section: DEAL_TICKET_SECTION.SUMMARY,
@ -186,7 +186,7 @@ export const useOrderValidation = ({
[ [
Schema.MarketState.STATE_PROPOSED, Schema.MarketState.STATE_PROPOSED,
Schema.MarketState.STATE_PENDING, Schema.MarketState.STATE_PENDING,
].includes(market.state) ].includes(market.data.marketState)
) { ) {
if (fieldErrorChecking) { if (fieldErrorChecking) {
return fieldErrorChecking; return fieldErrorChecking;
@ -195,7 +195,7 @@ export const useOrderValidation = ({
isDisabled: false, isDisabled: false,
message: t( message: t(
`This market is ${marketTranslations( `This market is ${marketTranslations(
market.state market.data.marketState
)} and only accepting liquidity commitment orders` )} and only accepting liquidity commitment orders`
), ),
section: DEAL_TICKET_SECTION.SUMMARY, section: DEAL_TICKET_SECTION.SUMMARY,
@ -205,9 +205,9 @@ export const useOrderValidation = ({
if (isMarketInAuction(market)) { if (isMarketInAuction(market)) {
if (order.type === Schema.OrderType.TYPE_MARKET) { if (order.type === Schema.OrderType.TYPE_MARKET) {
if ( if (
market.tradingMode === market.data.marketTradingMode ===
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION && Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === market.data.trigger ===
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
) { ) {
return { return {
@ -230,9 +230,9 @@ export const useOrderValidation = ({
}; };
} }
if ( if (
market.tradingMode === market.data.marketTradingMode ===
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION && Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE
) { ) {
return { return {
isDisabled: true, isDisabled: true,
@ -270,9 +270,9 @@ export const useOrderValidation = ({
].includes(order.timeInForce) ].includes(order.timeInForce)
) { ) {
if ( if (
market.tradingMode === market.data.marketTradingMode ===
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION && Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === market.data.trigger ===
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
) { ) {
return { return {
@ -297,9 +297,9 @@ export const useOrderValidation = ({
}; };
} }
if ( if (
market.tradingMode === market.data.marketTradingMode ===
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION && Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE
) { ) {
return { return {
isDisabled: true, isDisabled: true,
@ -355,7 +355,7 @@ export const useOrderValidation = ({
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION, Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION, Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION, Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
].includes(market.tradingMode) ].includes(market.data.marketTradingMode)
) { ) {
return { return {
isDisabled: false, isDisabled: false,

View File

@ -59,6 +59,7 @@ const mockTradingPage = (
generateMarketData({ generateMarketData({
trigger: trigger, trigger: trigger,
marketTradingMode: tradingMode, marketTradingMode: tradingMode,
marketState: state,
}) })
); );
aliasQuery(req, 'MarketsData', generateMarketsData()); aliasQuery(req, 'MarketsData', generateMarketsData());

View File

@ -75,7 +75,7 @@ export const DealTicket = ({
return; return;
} }
const marketStateError = validateMarketState(market.state); const marketStateError = validateMarketState(market.data.marketState);
if (marketStateError !== true) { if (marketStateError !== true) {
setError('summary', { message: marketStateError }); setError('summary', { message: marketStateError });
return; return;
@ -87,7 +87,7 @@ export const DealTicket = ({
} }
const marketTradingModeError = validateMarketTradingMode( const marketTradingModeError = validateMarketTradingMode(
market.tradingMode market.data.marketTradingMode
); );
if (marketTradingModeError !== true) { if (marketTradingModeError !== true) {
setError('summary', { message: marketTradingModeError }); setError('summary', { message: marketTradingModeError });
@ -110,8 +110,8 @@ export const DealTicket = ({
hasNoBalance, hasNoBalance,
market.positionDecimalPlaces, market.positionDecimalPlaces,
market.decimalPlaces, market.decimalPlaces,
market.state, market.data.marketState,
market.tradingMode, market.data.marketTradingMode,
setError, setError,
] ]
); );
@ -242,7 +242,7 @@ const SummaryMessage = memo(
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION, Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION, Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION, Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
].includes(market.tradingMode) ].includes(market.data.marketTradingMode)
) { ) {
return ( return (
<div <div

View File

@ -16,9 +16,9 @@ export const compileGridData = (
): { label: ReactNode; value?: ReactNode }[] => { ): { label: ReactNode; value?: ReactNode }[] => {
const grid: MarketDataGridProps['grid'] = []; const grid: MarketDataGridProps['grid'] = [];
const isLiquidityMonitoringAuction = const isLiquidityMonitoringAuction =
market.tradingMode === market.data.marketTradingMode ===
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION && Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY; market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY;
const formatStake = (value: string) => { const formatStake = (value: string) => {
const formattedValue = addDecimalsFormatNumber( const formattedValue = addDecimalsFormatNumber(
@ -32,14 +32,14 @@ export const compileGridData = (
if (!market.data) return grid; if (!market.data) return grid;
if (market.data?.auctionStart) { if (market.data.auctionStart) {
grid.push({ grid.push({
label: t('Auction start'), label: t('Auction start'),
value: getDateTimeFormat().format(new Date(market.data.auctionStart)), value: getDateTimeFormat().format(new Date(market.data.auctionStart)),
}); });
} }
if (market.data?.auctionEnd) { if (market.data.auctionEnd) {
const endDate = getDateTimeFormat().format( const endDate = getDateTimeFormat().format(
new Date(market.data.auctionEnd) new Date(market.data.auctionEnd)
); );
@ -51,14 +51,14 @@ export const compileGridData = (
}); });
} }
if (isLiquidityMonitoringAuction && market.data?.targetStake) { if (isLiquidityMonitoringAuction && market.data.targetStake) {
grid.push({ grid.push({
label: t('Target liquidity'), label: t('Target liquidity'),
value: formatStake(market.data.targetStake), value: formatStake(market.data.targetStake),
}); });
} }
if (isLiquidityMonitoringAuction && market.data?.suppliedStake) { if (isLiquidityMonitoringAuction && market.data.suppliedStake) {
grid.push({ grid.push({
label: ( label: (
<Link <Link
@ -71,7 +71,7 @@ export const compileGridData = (
value: formatStake(market.data.suppliedStake), value: formatStake(market.data.suppliedStake),
}); });
} }
if (market.data?.indicativePrice) { if (market.data.indicativePrice) {
grid.push({ grid.push({
label: t('Est. uncrossing price'), label: t('Est. uncrossing price'),
value: value:
@ -85,7 +85,7 @@ export const compileGridData = (
}); });
} }
if (market.data?.indicativeVolume) { if (market.data.indicativeVolume) {
grid.push({ grid.push({
label: t('Est. uncrossing vol'), label: t('Est. uncrossing vol'),
value: value:

View File

@ -11,9 +11,9 @@ export const getMarketPrice = (market: MarketDealTicket) => {
// 0 can never be a valid uncrossing price // 0 can never be a valid uncrossing price
// as it would require there being orders on the book at that price. // as it would require there being orders on the book at that price.
if ( if (
market.data?.indicativePrice && market.data.indicativePrice &&
market.data.indicativePrice !== '0' && market.data.indicativePrice !== '0' &&
BigInt(market.data?.indicativePrice) !== BigInt(0) BigInt(market.data.indicativePrice) !== BigInt(0)
) { ) {
return market.data.indicativePrice; return market.data.indicativePrice;
} }

View File

@ -1,11 +1,13 @@
import { Schema } from '@vegaprotocol/types'; import { Schema } from '@vegaprotocol/types';
export const isMarketInAuction = (market: { export const isMarketInAuction = (market: {
tradingMode: Schema.MarketTradingMode; data: {
marketTradingMode: Schema.MarketTradingMode;
};
}) => { }) => {
return [ return [
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION, Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION, Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION, Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
].includes(market.tradingMode); ].includes(market.data.marketTradingMode);
}; };

View File

@ -6,12 +6,12 @@ import type { MarketDealTicket } from '@vegaprotocol/market-list';
export const validateTimeInForce = (market: MarketDealTicket) => { export const validateTimeInForce = (market: MarketDealTicket) => {
return (value: Schema.OrderTimeInForce) => { return (value: Schema.OrderTimeInForce) => {
const isMonitoringAuction = const isMonitoringAuction =
market.tradingMode === market.data.marketTradingMode ===
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION; Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION;
const isPriceTrigger = const isPriceTrigger =
market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE; market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE;
const isLiquidityTrigger = const isLiquidityTrigger =
market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY; market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY;
if (isMarketInAuction(market)) { if (isMarketInAuction(market)) {
if ( if (

View File

@ -7,13 +7,12 @@ export const validateType = (market: MarketDealTicket) => {
return (value: Schema.OrderType) => { return (value: Schema.OrderType) => {
if (isMarketInAuction(market) && value === Schema.OrderType.TYPE_MARKET) { if (isMarketInAuction(market) && value === Schema.OrderType.TYPE_MARKET) {
const isMonitoringAuction = const isMonitoringAuction =
market.tradingMode === market.data.marketTradingMode ===
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION; Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION;
const isPriceTrigger = const isPriceTrigger =
market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE; market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE;
const isLiquidityTrigger = const isLiquidityTrigger =
market.data?.trigger === market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY;
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY;
if (isMonitoringAuction && isPriceTrigger) { if (isMonitoringAuction && isPriceTrigger) {
return MarketModeValidationType.PriceMonitoringAuction; return MarketModeValidationType.PriceMonitoringAuction;

View File

@ -4,6 +4,7 @@ import type {
FetchPolicy, FetchPolicy,
OperationVariables, OperationVariables,
TypedDocumentNode, TypedDocumentNode,
FetchResult,
} from '@apollo/client'; } from '@apollo/client';
import type { Subscription } from 'zen-observable-ts'; import type { Subscription } from 'zen-observable-ts';
import isEqual from 'lodash/isEqual'; import isEqual from 'lodash/isEqual';
@ -362,6 +363,25 @@ function makeDataProviderInternal<
} }
}; };
const onNext = ({
data: subscriptionData,
}: FetchResult<SubscriptionData>) => {
if (!subscriptionData || !getDelta || !update) {
return;
}
const delta = getDelta(subscriptionData, variables);
if (loading || !data) {
updateQueue.push(delta);
} else {
const updatedData = update(data, delta, reload, variables);
if (updatedData === data) {
return;
}
data = updatedData;
notifyAll({ delta, isUpdate: true });
}
};
const initialize = async () => { const initialize = async () => {
if (subscription) { if (subscription) {
if (resetTimer) { if (resetTimer) {
@ -375,6 +395,7 @@ function makeDataProviderInternal<
if (!client) { if (!client) {
return; return;
} }
if (subscriptionQuery && getDelta && update) { if (subscriptionQuery && getDelta && update) {
subscription = client subscription = client
.subscribe<SubscriptionData>({ .subscribe<SubscriptionData>({
@ -382,32 +403,14 @@ function makeDataProviderInternal<
variables, variables,
fetchPolicy, fetchPolicy,
}) })
.subscribe( .subscribe(onNext, (e) => {
({ data: subscriptionData }) => { error = e as Error;
if (!subscriptionData) { if (subscription) {
return; subscription.unsubscribe();
} subscription = undefined;
const delta = getDelta(subscriptionData, variables);
if (loading || !data) {
updateQueue.push(delta);
} else {
const updatedData = update(data, delta, reload, variables);
if (updatedData === data) {
return;
}
data = updatedData;
notifyAll({ delta, isUpdate: true });
}
},
(e) => {
error = e as Error;
if (subscription) {
subscription.unsubscribe();
subscription = undefined;
}
notifyAll();
} }
); notifyAll();
});
} }
await initialFetch(); await initialFetch();
}; };