diff --git a/src/store/__tests__/swapOrderSlice.test.ts b/src/store/__tests__/swapOrderSlice.test.ts index 46f4615a38..bb3a6861f4 100644 --- a/src/store/__tests__/swapOrderSlice.test.ts +++ b/src/store/__tests__/swapOrderSlice.test.ts @@ -1,6 +1,6 @@ import { listenerMiddlewareInstance } from '@/store' import { txHistorySlice } from '@/store/txHistorySlice' -import { swapOrderListener, swapOrderStatusListener, setSwapOrder } from '@/store/swapOrderSlice' +import { swapOrderListener, swapOrderStatusListener, setSwapOrder, deleteSwapOrder } from '@/store/swapOrderSlice' import { TransactionListItemType, type TransactionListItem, @@ -121,6 +121,37 @@ describe('swapOrderSlice', () => { }), ) }) + + it('should not dispatch setSwapOrder if the old status is undefined and new status is fulfilled, expired, or cancelled', () => { + const swapTransaction = { + type: TransactionListItemType.TRANSACTION, + transaction: { + id: '0x123', + txInfo: { + type: TransactionInfoType.SWAP_ORDER, + uid: 'order1', + status: 'fulfilled', // Test with 'expired' and 'cancelled' as well + }, + }, + } as unknown as TransactionListItem + + const action = txHistorySlice.actions.set({ + loading: false, + data: { + results: [swapTransaction], + }, + }) + + const effect = startListeningMock.mock.calls[0][0].effect + effect(action, { + dispatch: mockDispatch, + getOriginalState: () => ({ + swapOrders: {}, // Old status is undefined + }), + }) + + expect(mockDispatch).not.toHaveBeenCalled() + }) }) describe('swapOrderStatusListener', () => { @@ -167,7 +198,7 @@ describe('swapOrderSlice', () => { }) }) - it('should dispatch a notification if the swapOrder status is created and threshold is more than 1', () => { + it('should dispatch a notification if the swapOrder status is created and there is nothing about this swap in the state and threshold is more than 1', () => { const swapOrder = { orderUid: 'order1', status: 'created' as const, @@ -199,6 +230,43 @@ describe('swapOrderSlice', () => { }) }) + it('should dispatch a notification if the swapOrder status is open and we have old status and threshold is 1', () => { + const swapOrder = { + orderUid: 'order1', + status: 'open' as const, + txId: '0x123', + } + + const action = setSwapOrder(swapOrder) + + const effect = startListeningMock.mock.calls[0][0].effect + effect(action, { + dispatch: mockDispatch, + getState: () => ({ + safeInfo: { + data: { + threshold: 1, + }, + }, + }), + getOriginalState: () => ({ + swapOrders: { + order1: { + orderUid: 'order1', + status: 'created', // Old status is not undefined + }, + }, + }), + }) + + expect(showNotificationSpy).toHaveBeenCalledWith({ + title: 'Order created', + message: 'Waiting for the transaction to be executed', + groupKey: 'swap-order-status', + variant: 'info', + }) + }) + it('should dispatch a notification if the swapOrder status is presignaturePending', () => { const swapOrder = { orderUid: 'order1', @@ -325,6 +393,8 @@ describe('swapOrderSlice', () => { groupKey: 'swap-order-status', variant: 'info', }) + + expect(mockDispatch).toHaveBeenCalledWith(deleteSwapOrder('order1')) }) it('should not dispatch a notification if the swapOrder status is expired and old status is undefined', () => { @@ -352,6 +422,7 @@ describe('swapOrderSlice', () => { }) expect(showNotificationSpy).not.toHaveBeenCalled() + expect(mockDispatch).not.toHaveBeenCalledWith(deleteSwapOrder('order1')) }) it('should dispatch a notification if the swapOrder status is expired and old status is not undefined', () => { @@ -389,6 +460,8 @@ describe('swapOrderSlice', () => { groupKey: 'swap-order-status', variant: 'warning', }) + + expect(mockDispatch).toHaveBeenCalledWith(deleteSwapOrder('order1')) }) it('should not dispatch a notification if the swapOrder status is cancelled and old status is undefined', () => { @@ -416,6 +489,7 @@ describe('swapOrderSlice', () => { }) expect(showNotificationSpy).not.toHaveBeenCalled() + expect(mockDispatch).not.toHaveBeenCalledWith(deleteSwapOrder('order1')) }) it('should dispatch a notification if the swapOrder status is cancelled and old status is not undefined', () => { @@ -453,6 +527,7 @@ describe('swapOrderSlice', () => { groupKey: 'swap-order-status', variant: 'warning', }) + expect(mockDispatch).toHaveBeenCalledWith(deleteSwapOrder('order1')) }) }) }) diff --git a/src/store/swapOrderSlice.ts b/src/store/swapOrderSlice.ts index 12edc54019..3f8c0bed79 100644 --- a/src/store/swapOrderSlice.ts +++ b/src/store/swapOrderSlice.ts @@ -33,10 +33,15 @@ const slice = createSlice({ }, } }, + deleteSwapOrder: (state, { payload }: { payload: string }): SwapOrderState => { + const newState = { ...state } + delete newState[payload] + return newState + }, }, }) -export const { setSwapOrder } = slice.actions +export const { setSwapOrder, deleteSwapOrder } = slice.actions const selector = (state: RootState) => state[slice.name] export const swapOrderSlice = slice export const selectAllSwapOrderStatuses = selector @@ -72,7 +77,7 @@ export const swapOrderStatusListener = (listenerMiddleware: typeof listenerMiddl const oldStatus = selectSwapOrderStatus(listenerApi.getOriginalState(), swapOrder.orderUid) const newStatus = swapOrder.status - if (oldStatus === newStatus) { + if (oldStatus === newStatus || newStatus === undefined) { return } @@ -125,6 +130,7 @@ export const swapOrderStatusListener = (listenerMiddleware: typeof listenerMiddl variant: 'info', }), ) + dispatch(slice.actions.deleteSwapOrder(swapOrder.orderUid)) break case 'expired': if (oldStatus === undefined) { @@ -138,6 +144,7 @@ export const swapOrderStatusListener = (listenerMiddleware: typeof listenerMiddl variant: 'warning', }), ) + dispatch(slice.actions.deleteSwapOrder(swapOrder.orderUid)) break case 'cancelled': if (oldStatus === undefined) { @@ -151,6 +158,7 @@ export const swapOrderStatusListener = (listenerMiddleware: typeof listenerMiddl variant: 'warning', }), ) + dispatch(slice.actions.deleteSwapOrder(swapOrder.orderUid)) break } }, @@ -178,7 +186,8 @@ export const swapOrderListener = (listenerMiddleware: typeof listenerMiddlewareI const swapOrder = result.transaction.txInfo const oldStatus = selectSwapOrderStatus(listenerApi.getOriginalState(), swapOrder.uid) - if (oldStatus === swapOrder.status) { + const finalStatuses: AllStatuses[] = ['fulfilled', 'expired', 'cancelled'] + if (oldStatus === swapOrder.status || (oldStatus === undefined && finalStatuses.includes(swapOrder.status))) { continue }