chore(trading,governance): remove busEvent for proposals (#2946)

This commit is contained in:
Matthew Russell 2023-02-20 16:57:25 -08:00 committed by GitHub
parent a79e2f85bc
commit a12a5b3a15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 211 additions and 192 deletions

View File

@ -1,4 +1,4 @@
import { act } from '@testing-library/react-hooks';
import { act } from '@testing-library/react';
import { usePendingBalancesStore } from './use-pending-balances-manager';
import type { Event } from 'ethers';

View File

@ -27,12 +27,8 @@ fragment UpdateNetworkParameterProposal on Proposal {
}
subscription OnUpdateNetworkParameters {
busEvents(types: [Proposal], batchSize: 0) {
event {
... on Proposal {
...UpdateNetworkParameterProposal
}
}
proposals {
...UpdateNetworkParameterProposal
}
}

View File

@ -18,7 +18,7 @@ export type UpdateNetworkParameterProposalFragment = { __typename?: 'Proposal',
export type OnUpdateNetworkParametersSubscriptionVariables = Types.Exact<{ [key: string]: never; }>;
export type OnUpdateNetworkParametersSubscription = { __typename?: 'Subscription', busEvents?: Array<{ __typename?: 'BusEvent', event: { __typename?: 'AccountEvent' } | { __typename?: 'Asset' } | { __typename?: 'AuctionEvent' } | { __typename?: 'Deposit' } | { __typename?: 'LiquidityProvision' } | { __typename?: 'LossSocialization' } | { __typename?: 'MarginLevels' } | { __typename?: 'Market' } | { __typename?: 'MarketData' } | { __typename?: 'MarketEvent' } | { __typename?: 'MarketTick' } | { __typename?: 'NodeSignature' } | { __typename?: 'OracleSpec' } | { __typename?: 'Order' } | { __typename?: 'Party' } | { __typename?: 'PositionResolution' } | { __typename?: 'Proposal', id?: string | null, state: Types.ProposalState, datetime: any, terms: { __typename?: 'ProposalTerms', enactmentDatetime?: any | null, change: { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } } } | { __typename?: 'RiskFactor' } | { __typename?: 'SettleDistressed' } | { __typename?: 'SettlePosition' } | { __typename?: 'TimeUpdate' } | { __typename?: 'Trade' } | { __typename?: 'TransactionResult' } | { __typename?: 'TransferResponses' } | { __typename?: 'Vote' } | { __typename?: 'Withdrawal' } }> | null };
export type OnUpdateNetworkParametersSubscription = { __typename?: 'Subscription', proposals: { __typename?: 'Proposal', id?: string | null, state: Types.ProposalState, datetime: any, terms: { __typename?: 'ProposalTerms', enactmentDatetime?: any | null, change: { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } } } };
export type ProposalOfMarketQueryVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
@ -83,12 +83,8 @@ export type ProposalEventSubscriptionHookResult = ReturnType<typeof useProposalE
export type ProposalEventSubscriptionResult = Apollo.SubscriptionResult<ProposalEventSubscription>;
export const OnUpdateNetworkParametersDocument = gql`
subscription OnUpdateNetworkParameters {
busEvents(types: [Proposal], batchSize: 0) {
event {
... on Proposal {
...UpdateNetworkParameterProposal
}
}
proposals {
...UpdateNetworkParameterProposal
}
}
${UpdateNetworkParameterProposalFragmentDoc}`;

View File

@ -7,11 +7,16 @@ import type { Toast } from '@vegaprotocol/ui-toolkit';
import { ToastHeading } from '@vegaprotocol/ui-toolkit';
import { useToasts } from '@vegaprotocol/ui-toolkit';
import { ExternalLink, Intent } from '@vegaprotocol/ui-toolkit';
import compact from 'lodash/compact';
import { useCallback } from 'react';
import type { UpdateNetworkParameterProposalFragment } from './__generated__/Proposal';
import { useOnUpdateNetworkParametersSubscription } from './__generated__/Proposal';
export const PROPOSAL_STATES_TO_TOAST = [
ProposalState.STATE_DECLINED,
ProposalState.STATE_ENACTED,
ProposalState.STATE_OPEN,
ProposalState.STATE_PASSED,
];
const CLOSE_AFTER = 5000;
type Proposal = UpdateNetworkParameterProposalFragment;
@ -75,26 +80,16 @@ export const useUpdateNetworkParametersToasts = () => {
[remove]
);
useOnUpdateNetworkParametersSubscription({
onData: (options) => {
const events = compact(options.data.data?.busEvents);
if (!events || events.length === 0) return;
const validProposals = events
.filter(
(ev) =>
ev.event.__typename === 'Proposal' &&
ev.event.terms.__typename === 'ProposalTerms' &&
ev.event.terms.change.__typename === 'UpdateNetworkParameter' &&
[
ProposalState.STATE_DECLINED,
ProposalState.STATE_ENACTED,
ProposalState.STATE_OPEN,
ProposalState.STATE_PASSED,
].includes(ev.event.state)
)
.map((ev) => ev.event as Proposal);
if (validProposals.length < 5) {
validProposals.forEach((p) => setToast(fromProposal(p)));
return useOnUpdateNetworkParametersSubscription({
onData: ({ data }) => {
// note proposals is poorly named, it is actually a single proposal
const proposal = data.data?.proposals;
if (!proposal) return;
if (proposal.terms.change.__typename !== 'UpdateNetworkParameter') return;
// if one of the following states show a toast
if (PROPOSAL_STATES_TO_TOAST.includes(proposal.state)) {
setToast(fromProposal(proposal));
}
},
});

View File

@ -1,16 +1,19 @@
import merge from 'lodash/merge';
import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import { renderHook } from '@testing-library/react-hooks';
import { ProposalState } from '@vegaprotocol/types';
import type { ReactNode } from 'react';
import { useUpdateNetworkParametersToasts } from './use-update-network-paramaters-toasts';
import {
PROPOSAL_STATES_TO_TOAST,
useUpdateNetworkParametersToasts,
} from './use-update-network-paramaters-toasts';
import type {
UpdateNetworkParameterProposalFragment,
OnUpdateNetworkParametersSubscription,
} from './__generated__/Proposal';
import { OnUpdateNetworkParametersDocument } from './__generated__/Proposal';
import { useToasts } from '@vegaprotocol/ui-toolkit';
import { waitFor } from '@testing-library/react';
import { waitFor, renderHook } from '@testing-library/react';
const render = (mocks?: MockedResponse[]) => {
const wrapper = ({ children }: { children: ReactNode }) => (
@ -42,56 +45,6 @@ const generateUpdateNetworkParametersProposal = (
},
});
const mockedWrongEvent: MockedResponse<OnUpdateNetworkParametersSubscription> =
{
request: {
query: OnUpdateNetworkParametersDocument,
},
result: {
data: {
__typename: 'Subscription',
busEvents: [
{
__typename: 'BusEvent',
event: {
__typename: 'Asset',
},
},
],
},
},
};
const mockedEmptyEvent: MockedResponse<OnUpdateNetworkParametersSubscription> =
{
request: {
query: OnUpdateNetworkParametersDocument,
},
result: {
data: {
__typename: 'Subscription',
busEvents: [],
},
},
};
const mockedEvent: MockedResponse<OnUpdateNetworkParametersSubscription> = {
request: {
query: OnUpdateNetworkParametersDocument,
},
result: {
data: {
__typename: 'Subscription',
busEvents: [
{
__typename: 'BusEvent',
event: generateUpdateNetworkParametersProposal('abc.def', '123.456'),
},
],
},
},
};
const INITIAL = useToasts.getState();
const clear = () => {
@ -102,23 +55,113 @@ describe('useUpdateNetworkParametersToasts', () => {
beforeEach(clear);
afterAll(clear);
it('returns toast for update network parameters bus event', async () => {
render([mockedEvent]);
await waitFor(() => {
expect(useToasts.getState().count).toBe(1);
});
});
it.each(PROPOSAL_STATES_TO_TOAST)(
'toasts for %s network param proposals',
async (state) => {
const mockOpenProposal: MockedResponse<OnUpdateNetworkParametersSubscription> =
{
request: {
query: OnUpdateNetworkParametersDocument,
},
result: {
data: {
proposals: generateUpdateNetworkParametersProposal(
'abc.def',
'123.456',
state
),
},
},
};
const { result } = render([mockOpenProposal]);
expect(result.current.loading).toBe(true);
await waitFor(() => {
expect(result.current.loading).toBe(false);
expect(useToasts.getState().count).toBe(1);
});
}
);
it('does not return toast for empty event', async () => {
render([mockedEmptyEvent]);
const IGNORE_STATES = Object.keys(ProposalState).filter((state) => {
return !PROPOSAL_STATES_TO_TOAST.includes(state as ProposalState);
}) as ProposalState[];
it.each(IGNORE_STATES)('does not toast for %s proposals', async (state) => {
const mockFailedProposal: MockedResponse<OnUpdateNetworkParametersSubscription> =
{
request: {
query: OnUpdateNetworkParametersDocument,
},
result: {
data: {
proposals: generateUpdateNetworkParametersProposal(
'abc.def',
'123.456',
state
),
},
},
};
const { result } = render([mockFailedProposal]);
expect(result.current.loading).toBe(true);
await waitFor(() => {
expect(result.current.loading).toBe(false);
expect(useToasts.getState().count).toBe(0);
});
});
it('does not return toast for wrong event', async () => {
render([mockedWrongEvent]);
it('does not return toast for empty propsal', async () => {
const error = console.error;
console.error = () => {
/* no op */
};
const mockEmptyProposal: MockedResponse<OnUpdateNetworkParametersSubscription> =
{
request: {
query: OnUpdateNetworkParametersDocument,
},
result: {
data: {
proposals:
undefined as unknown as UpdateNetworkParameterProposalFragment,
},
},
};
const { result } = render([mockEmptyProposal]);
expect(result.current.loading).toBe(true);
await waitFor(() => {
expect(result.current.loading).toBe(false);
expect(useToasts.getState().count).toBe(0);
});
console.error = error;
});
it('does not return toast for wrong proposal type', async () => {
const wrongProposalType = merge(
generateUpdateNetworkParametersProposal('a', 'b'),
{
terms: {
change: {
__typename: 'NewMarket',
},
},
}
);
const mockWrongProposalType: MockedResponse<OnUpdateNetworkParametersSubscription> =
{
request: {
query: OnUpdateNetworkParametersDocument,
},
result: {
data: {
proposals: wrongProposalType,
},
},
};
const { result } = render([mockWrongProposalType]);
expect(result.current.loading).toBe(true);
await waitFor(() => {
expect(result.current.loading).toBe(false);
expect(useToasts.getState().count).toBe(0);
});
});

View File

@ -344,58 +344,12 @@ export type BusEvent = {
/** Event types */
export enum BusEventType {
/** An account has been updated */
Account = 'Account',
/** An asset has been created or update */
Asset = 'Asset',
/** A market has either entered or exited auction */
Auction = 'Auction',
/** Collateral has deposited in to this Vega network via the bridge */
Deposit = 'Deposit',
/** A liquidity commitment change occurred */
LiquidityProvision = 'LiquidityProvision',
/** A position has been closed without sufficient insurance pool balance to cover it */
LossSocialization = 'LossSocialization',
/** Margin levels have changed for a position */
MarginLevels = 'MarginLevels',
/** Constant for market events - mainly used for logging */
Market = 'Market',
/** A new market has been created */
MarketCreated = 'MarketCreated',
/** Market data has been updated */
MarketData = 'MarketData',
/** A market has progressed by one tick */
MarketTick = 'MarketTick',
/** A market has been updated */
MarketUpdated = 'MarketUpdated',
/** Validator node signatures for an event */
NodeSignature = 'NodeSignature',
/** An oracle spec has been registered */
OracleSpec = 'OracleSpec',
/** An order has been created or updated */
Order = 'Order',
/** A party has been updated */
Party = 'Party',
/** A position resolution event has occurred */
PositionResolution = 'PositionResolution',
/** A governance proposal has been created or updated */
Proposal = 'Proposal',
/** A risk factor adjustment was made */
RiskFactor = 'RiskFactor',
/** A distressed position has been settled */
SettleDistressed = 'SettleDistressed',
/** A position has been settled */
SettlePosition = 'SettlePosition',
/** Vega Time has changed */
TimeUpdate = 'TimeUpdate',
/** A trade has been created */
Trade = 'Trade',
/** The results from processing at transaction */
TransactionResult = 'TransactionResult',
/** A balance has been transferred between accounts */
TransferResponses = 'TransferResponses',
/** A vote has been placed on a governance proposal */
Vote = 'Vote',
/** Collateral has been withdrawn from this Vega network via the bridge */
Withdrawal = 'Withdrawal'
}
@ -1014,7 +968,7 @@ export type EthereumKeyRotationsConnection = {
};
/** Union type for wrapped events in stream PROPOSAL is mapped to governance data, something to keep in mind */
export type Event = AccountEvent | Asset | AuctionEvent | Deposit | LiquidityProvision | LossSocialization | MarginLevels | Market | MarketData | MarketEvent | MarketTick | NodeSignature | OracleSpec | Order | Party | PositionResolution | Proposal | RiskFactor | SettleDistressed | SettlePosition | TimeUpdate | Trade | TransactionResult | TransferResponses | Vote | Withdrawal;
export type Event = Deposit | TimeUpdate | TransactionResult | Withdrawal;
export type ExternalData = {
__typename?: 'ExternalData';
@ -1100,8 +1054,6 @@ export type FutureProduct = {
/** A segment of data node history */
export type HistorySegment = {
__typename?: 'HistorySegment';
/** Chain ID of the history segment */
chainID: Scalars['String'];
/** From block height of the history segment */
fromHeight: Scalars['Int'];
/** ID of the history segment */
@ -1225,6 +1177,8 @@ export type LedgerEntryFilter = {
/** Configuration of a market liquidity monitoring parameters */
export type LiquidityMonitoringParameters = {
__typename?: 'LiquidityMonitoringParameters';
/** Specifies by how many seconds an auction should be extended if leaving the auction were to trigger a liquidity auction */
auctionExtensionSecs: Scalars['Int'];
/** Specifies parameters related to target stake calculation */
targetStakeParameters: TargetStakeParameters;
/** Specifies the triggering ratio for entering liquidity auction */
@ -1489,6 +1443,8 @@ export type Market = {
fees: Fees;
/** Market ID */
id: Scalars['ID'];
/** Linear slippage factor is used to cap the slippage component of maintainence margin - it is applied to the slippage volume */
linearSlippageFactor: Scalars['String'];
/** Liquidity monitoring parameters for the market */
liquidityMonitoringParameters: LiquidityMonitoringParameters;
/** The list of the liquidity provision commitments for this market */
@ -1515,6 +1471,8 @@ export type Market = {
priceMonitoringSettings: PriceMonitoringSettings;
/** The proposal that initiated this market */
proposal?: Maybe<Proposal>;
/** Quadratic slippage factor is used to cap the slippage component of maintainence margin - it is applied to the square of the slippage volume */
quadraticSlippageFactor: Scalars['String'];
/** Risk factors for the market */
riskFactors?: Maybe<RiskFactor>;
/** Current state of the market */
@ -1870,10 +1828,20 @@ export type NewMarket = {
decimalPlaces: Scalars['Int'];
/** New market instrument configuration */
instrument: InstrumentConfiguration;
/** Linear slippage factor is used to cap the slippage component of maintainence margin - it is applied to the slippage volume */
linearSlippageFactor: Scalars['String'];
/** Liquidity monitoring parameters */
liquidityMonitoringParameters: LiquidityMonitoringParameters;
/** Liquidity Provision order price range */
lpPriceRange: Scalars['String'];
/** Metadata for this instrument, tags */
metadata?: Maybe<Array<Scalars['String']>>;
/** Decimal places for order sizes, sets what size the smallest order / position on the market can be */
positionDecimalPlaces: Scalars['Int'];
/** Price monitoring parameters */
priceMonitoringParameters: PriceMonitoringParameters;
/** Quadratic slippage factor is used to cap the slippage component of maintainence margin - it is applied to the square of the slippage volume */
quadraticSlippageFactor: Scalars['String'];
/** New market risk configuration */
riskParameters: RiskModel;
};
@ -2519,7 +2487,10 @@ export type Party = {
marginsConnection?: Maybe<MarginConnection>;
/** Orders relating to a party */
ordersConnection?: Maybe<OrderConnection>;
/** Trading positions relating to a party */
/**
* Trading positions relating to a party
* @deprecated Use root positions query instead of sub-query
*/
positionsConnection?: Maybe<PositionConnection>;
/** All governance proposals in the Vega network */
proposalsConnection?: Maybe<ProposalsConnection>;
@ -2610,7 +2581,9 @@ export type PartyrewardSummariesArgs = {
/** Represents a party on Vega, could be an ethereum wallet address in the future */
export type PartyrewardsConnectionArgs = {
assetId?: InputMaybe<Scalars['ID']>;
fromEpoch?: InputMaybe<Scalars['Int']>;
pagination?: InputMaybe<Pagination>;
toEpoch?: InputMaybe<Scalars['Int']>;
};
@ -2707,6 +2680,8 @@ export type Position = {
__typename?: 'Position';
/** Average entry price for this position */
averageEntryPrice: Scalars['String'];
/** The total amount of profit and loss that was not transferred due to loss socialisation */
lossSocializationAmount: Scalars['String'];
/** Margins of the party for the given position */
marginsConnection?: Maybe<MarginConnection>;
/** Market relating to this position */
@ -2715,6 +2690,8 @@ export type Position = {
openVolume: Scalars['String'];
/** The party holding this position */
party: Party;
/** Enum set if the position was closed out or orders were removed because party was distressed */
positionStatus: PositionStatus;
/** Realised Profit and Loss (int64) */
realisedPNL: Scalars['String'];
/** Unrealised Profit and Loss (int64) */
@ -2764,6 +2741,16 @@ export type PositionResolution = {
marketId: Scalars['ID'];
};
/** Position status can change if a position is distressed */
export enum PositionStatus {
/** The position was distressed, and had to be closed out entirely - orders were removed from the book, and the open volume was closed out by the network */
POSITION_STATUS_CLOSED_OUT = 'POSITION_STATUS_CLOSED_OUT',
/** The position was distressed, but removing open orders from the book brought the margin level back to a point where the open position could be maintained */
POSITION_STATUS_ORDERS_CLOSED = 'POSITION_STATUS_ORDERS_CLOSED',
/** The position is either healthy, or if closed out, was closed out normally */
POSITION_STATUS_UNSPECIFIED = 'POSITION_STATUS_UNSPECIFIED'
}
/**
* An individual party at any point in time is considered net long or net short. This refers to their Open Volume,
* calculated using FIFO. This volume is signed as either negative for LONG positions and positive for SHORT positions. A
@ -2788,6 +2775,12 @@ export type PositionUpdate = {
updatedAt?: Maybe<Scalars['Timestamp']>;
};
/** Filter to apply to the positions connection query */
export type PositionsFilter = {
marketIds?: InputMaybe<Array<Scalars['ID']>>;
partyIds?: InputMaybe<Array<Scalars['ID']>>;
};
/** Represents a price on either the buy or sell side and all the orders at that price */
export type PriceLevel = {
__typename?: 'PriceLevel';
@ -2826,7 +2819,7 @@ export type PriceMonitoringSettings = {
parameters?: Maybe<PriceMonitoringParameters>;
};
/** PriceMonitoringParameters holds together price projection horizon τ, probability level p, and auction extension duration */
/** PriceMonitoringTrigger holds together price projection horizon τ, probability level p, and auction extension duration */
export type PriceMonitoringTrigger = {
__typename?: 'PriceMonitoringTrigger';
/**
@ -3281,6 +3274,8 @@ export type Query = {
partiesConnection?: Maybe<PartyConnection>;
/** An entity that is trading on the Vega network */
party?: Maybe<Party>;
/** Fetch all positions */
positions?: Maybe<PositionConnection>;
/** A governance proposal located by either its ID or reference. If both are set, ID is used. */
proposal?: Maybe<Proposal>;
/** All governance proposals in the Vega network */
@ -3348,9 +3343,8 @@ export type QueryepochArgs = {
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QueryepochRewardSummariesArgs = {
fromEpoch?: InputMaybe<Scalars['Int']>;
filter?: InputMaybe<RewardSummaryFilter>;
pagination?: InputMaybe<Pagination>;
toEpoch?: InputMaybe<Scalars['Int']>;
};
@ -3453,6 +3447,7 @@ export type QuerymarketArgs = {
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QuerymarketsConnectionArgs = {
id?: InputMaybe<Scalars['ID']>;
includeSettled?: InputMaybe<Scalars['Boolean']>;
pagination?: InputMaybe<Pagination>;
};
@ -3546,6 +3541,13 @@ export type QuerypartyArgs = {
};
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QuerypositionsArgs = {
filter?: InputMaybe<PositionsFilter>;
pagination?: InputMaybe<Pagination>;
};
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QueryproposalArgs = {
id?: InputMaybe<Scalars['ID']>;
@ -3698,6 +3700,14 @@ export type RewardSummaryEdge = {
node: RewardSummary;
};
/** Filter for historical reward summary queries */
export type RewardSummaryFilter = {
assetIds?: InputMaybe<Array<Scalars['ID']>>;
fromEpoch?: InputMaybe<Scalars['Int']>;
marketIds?: InputMaybe<Array<Scalars['ID']>>;
toEpoch?: InputMaybe<Scalars['Int']>;
};
/** Connection type for retrieving cursor-based paginated rewards information */
export type RewardsConnection = {
__typename?: 'RewardsConnection';
@ -3894,6 +3904,10 @@ export type Statistics = {
chainVersion: Scalars['String'];
/** RFC3339Nano current time (real) */
currentTime: Scalars['Timestamp'];
/** Total number of events on the last block */
eventCount: Scalars['String'];
/** The number of events per second on the last block */
eventsPerSecond: Scalars['String'];
/** RFC3339Nano genesis time of the chain */
genesisTime: Scalars['Timestamp'];
/** Number of orders per seconds */

View File

@ -1,9 +1,8 @@
import { renderHook, act } from '@testing-library/react-hooks';
import { renderHook, waitFor } from '@testing-library/react';
import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import type { ReactNode } from 'react';
import { useVegaTransactionUpdater } from './use-vega-transaction-updater';
import waitForNextTick from 'flush-promises';
import {
OrderTxUpdateDocument,
TransactionEventDocument,
@ -112,14 +111,13 @@ const mockedTransactionResultBusEvent: MockedResponse<TransactionEventSubscripti
data: {
busEvents: [
{
type: BusEventType.Order,
type: BusEventType.TransactionResult,
event: transactionResultBusEvent,
},
],
},
},
};
const withdrawalBusEvent: WithdrawalBusEventFieldsFragment = {
id: '2fca514cebf9f465ae31ecb4c5721e3a6f5f260425ded887ca50ba15b81a5d50',
status: WithdrawalStatus.STATUS_OPEN,
@ -167,20 +165,16 @@ const mockedWithdrawalBusEvent: MockedResponse<WithdrawalBusEventSubscription> =
describe('useVegaTransactionManager', () => {
it('updates order on OrderTxUpdate', async () => {
mockTransactionStoreState.mockReturnValue(defaultState);
const { waitForNextUpdate } = render([mockedOrderUpdate]);
await act(async () => {
waitForNextUpdate();
await waitForNextTick();
render([mockedOrderUpdate]);
await waitFor(() => {
expect(updateOrder).toHaveBeenCalledWith(orderUpdate);
});
});
it('updates transaction on TransactionResultBusEvents', async () => {
mockTransactionStoreState.mockReturnValue(defaultState);
const { waitForNextUpdate } = render([mockedTransactionResultBusEvent]);
await act(async () => {
waitForNextUpdate();
await waitForNextTick();
render([mockedTransactionResultBusEvent]);
await waitFor(() => {
expect(updateTransactionResult).toHaveBeenCalledWith(
transactionResultBusEvent
);
@ -193,10 +187,8 @@ describe('useVegaTransactionManager', () => {
mockWaitForWithdrawalApproval.mockResolvedValueOnce(
erc20WithdrawalApproval
);
const { waitForNextUpdate } = render([mockedWithdrawalBusEvent]);
await act(async () => {
waitForNextUpdate();
await waitForNextTick();
render([mockedWithdrawalBusEvent]);
await waitFor(() => {
expect(updateWithdrawal).toHaveBeenCalledWith(
withdrawalBusEvent,
erc20WithdrawalApproval

View File

@ -38,9 +38,9 @@ export const useVegaTransactionUpdater = () => {
result.data?.busEvents?.forEach((event) => {
if (event.event.__typename === 'Withdrawal') {
const withdrawal = event.event;
waitForWithdrawalApproval(withdrawal.id, client).then((approval) =>
updateWithdrawal(withdrawal, approval)
);
waitForWithdrawalApproval(withdrawal.id, client).then((approval) => {
updateWithdrawal(withdrawal, approval);
});
}
}),
});

View File

@ -1,9 +1,8 @@
import { renderHook } from '@testing-library/react-hooks';
import { renderHook, waitFor } from '@testing-library/react';
import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import type { ReactNode } from 'react';
import { useEthTransactionUpdater } from './use-ethereum-transaction-updater';
import waitForNextTick from 'flush-promises';
import {
DepositBusEventDocument,
VegaWalletContext,
@ -77,9 +76,9 @@ const mockedDepositBusEvent: MockedResponse<DepositBusEventSubscription> = {
describe('useEthTransactionUpdater', () => {
it('updates deposit on DepositBusEvents', async () => {
mockTransactionStoreState.mockReturnValue(defaultState);
const { waitForNextUpdate } = render([mockedDepositBusEvent]);
waitForNextUpdate();
await waitForNextTick();
expect(updateDeposit).toHaveBeenCalledWith(depositBusEvent);
render([mockedDepositBusEvent]);
await waitFor(() => {
expect(updateDeposit).toHaveBeenCalledWith(depositBusEvent);
});
});
});

View File

@ -128,7 +128,6 @@
"@svgr/webpack": "^5.4.0",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "13.3.0",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.4.1",
"@types/classnames": "^2.3.1",
"@types/faker": "^5.5.8",

View File

@ -6364,14 +6364,6 @@
lodash "^4.17.15"
redent "^3.0.0"
"@testing-library/react-hooks@^8.0.1":
version "8.0.1"
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz#0924bbd5b55e0c0c0502d1754657ada66947ca12"
integrity sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==
dependencies:
"@babel/runtime" "^7.12.5"
react-error-boundary "^3.1.0"
"@testing-library/react@13.3.0":
version "13.3.0"
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.3.0.tgz#bf298bfbc5589326bbcc8052b211f3bb097a97c5"
@ -19130,13 +19122,6 @@ react-element-to-jsx-string@^14.3.4:
is-plain-object "5.0.0"
react-is "17.0.2"
react-error-boundary@^3.1.0:
version "3.1.4"
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0"
integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==
dependencies:
"@babel/runtime" "^7.12.5"
react-hook-form@^7.27.0:
version "7.37.0"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.37.0.tgz#4d1738f092d3d8a3ade34ee892d97350b1032b19"