@@ -14,6 +14,7 @@ import {
14
14
RESIMULATE_PARAMS ,
15
15
shouldResimulate ,
16
16
VALUE_COMPARISON_PERCENT_THRESHOLD ,
17
+ RESIMULATE_INTERVAL_MS ,
17
18
} from './ResimulateHelper' ;
18
19
import { CHAIN_IDS } from '../constants' ;
19
20
import type {
@@ -87,10 +88,6 @@ const mockTransactionMeta = {
87
88
jest . mock ( '../utils/utils' ) ;
88
89
89
90
describe ( 'ResimulateHelper' , ( ) => {
90
- let blockTrackerMock : jest . Mocked < BlockTracker > ;
91
- let getBlockTrackerMock : jest . Mock <
92
- ( networkClientId : NetworkClientId ) => BlockTracker
93
- > ;
94
91
let getTransactionsMock : jest . Mock < ( ) => TransactionMeta [ ] > ;
95
92
let updateSimulationDataMock : jest . Mock <
96
93
( transactionMeta : TransactionMeta ) => void
@@ -99,166 +96,104 @@ describe('ResimulateHelper', () => {
99
96
100
97
let resimulateHelper : ResimulateHelper ;
101
98
102
- beforeEach ( ( ) => {
103
- blockTrackerMock = {
104
- on : jest . fn ( ) ,
105
- removeListener : jest . fn ( ) ,
106
- } as unknown as jest . Mocked < BlockTracker > ;
99
+ function triggerStateChange ( ) {
100
+ onStateChangeMock . mock . calls [ 0 ] [ 0 ] ( ) ;
101
+ }
107
102
108
- getBlockTrackerMock = jest . fn ( ) . mockReturnValue ( blockTrackerMock ) ;
103
+ function mockGetTransactionsOnce ( transactions : TransactionMeta [ ] ) {
104
+ getTransactionsMock . mockReturnValueOnce (
105
+ transactions as unknown as ResimulateHelperOptions [ 'getTransactions' ] ,
106
+ ) ;
107
+ }
108
+
109
+ beforeEach ( ( ) => {
110
+ jest . useFakeTimers ( ) ;
109
111
getTransactionsMock = jest . fn ( ) ;
110
112
onStateChangeMock = jest . fn ( ) ;
111
113
updateSimulationDataMock = jest . fn ( ) ;
112
114
113
115
resimulateHelper = new ResimulateHelper ( {
114
- getBlockTracker : getBlockTrackerMock ,
115
116
getTransactions : getTransactionsMock ,
116
117
onStateChange : onStateChangeMock ,
117
118
updateSimulationData : updateSimulationDataMock ,
118
119
} as unknown as ResimulateHelperOptions ) ;
119
120
} ) ;
120
121
121
- it ( 'assigns a block tracker listener to resimulate for a focused transaction' , ( ) => {
122
- resimulateHelper . start ( mockTransactionMeta ) ;
122
+ it ( `resimulates unapproved focused transaction every ${ RESIMULATE_INTERVAL_MS } milliseconds` , ( ) => {
123
+ mockGetTransactionsOnce ( [ mockTransactionMeta ] ) ;
124
+ triggerStateChange ( ) ;
123
125
124
- expect ( getBlockTrackerMock ) . toHaveBeenCalledWith (
125
- mockTransactionMeta . networkClientId ,
126
- ) ;
127
- expect ( blockTrackerMock . on ) . toHaveBeenCalledWith (
128
- 'latest' ,
129
- expect . any ( Function ) ,
130
- ) ;
126
+ jest . advanceTimersByTime ( RESIMULATE_INTERVAL_MS ) ;
127
+
128
+ jest . advanceTimersByTime ( RESIMULATE_INTERVAL_MS ) ;
129
+
130
+ expect ( updateSimulationDataMock ) . toHaveBeenCalledWith ( mockTransactionMeta ) ;
131
+ expect ( updateSimulationDataMock ) . toHaveBeenCalledTimes ( 2 ) ;
131
132
} ) ;
132
133
133
- it ( 'removes a block tracker listener for a transaction that is no longer focused' , ( ) => {
134
- resimulateHelper . start ( mockTransactionMeta ) ;
134
+ it ( `does not resimulate twice the same transaction even if state change is triggered twice` , ( ) => {
135
+ mockGetTransactionsOnce ( [ mockTransactionMeta ] ) ;
136
+ triggerStateChange ( ) ;
135
137
136
- const unfocusedTransactionMeta = {
137
- ...mockTransactionMeta ,
138
- isFocused : false ,
139
- } as TransactionMeta ;
138
+ // Halfway through the interval
139
+ jest . advanceTimersByTime ( RESIMULATE_INTERVAL_MS / 2 ) ;
140
140
141
- resimulateHelper . stop ( unfocusedTransactionMeta ) ;
141
+ // Assume state change is triggered again
142
+ mockGetTransactionsOnce ( [ mockTransactionMeta ] ) ;
143
+ triggerStateChange ( ) ;
142
144
143
- expect ( blockTrackerMock . removeListener ) . toHaveBeenCalledWith (
144
- 'latest' ,
145
- expect . any ( Function ) ,
146
- ) ;
145
+ // Halfway through the interval
146
+ jest . advanceTimersByTime ( RESIMULATE_INTERVAL_MS / 2 ) ;
147
+
148
+ expect ( updateSimulationDataMock ) . toHaveBeenCalledTimes ( 1 ) ;
147
149
} ) ;
148
150
149
- it ( 'does not add a block tracker listener for a transaction that is not focused' , ( ) => {
150
- resimulateHelper . start ( {
151
- ...mockTransactionMeta ,
152
- isFocused : false ,
153
- } ) ;
151
+ it ( 'does not resimulate a transaction that is no longer focused' , ( ) => {
152
+ mockGetTransactionsOnce ( [ mockTransactionMeta ] ) ;
153
+ triggerStateChange ( ) ;
154
154
155
- expect ( blockTrackerMock . on ) . not . toHaveBeenCalled ( ) ;
156
- } ) ;
155
+ // Halfway through the interval
156
+ jest . advanceTimersByTime ( RESIMULATE_INTERVAL_MS / 2 ) ;
157
157
158
- it ( 'does not add a block tracker listener for a transaction that is already resimulating' , ( ) => {
159
- resimulateHelper . start ( mockTransactionMeta ) ;
160
- resimulateHelper . start ( mockTransactionMeta ) ;
158
+ const unfocusedTransactionMeta = {
159
+ ...mockTransactionMeta ,
160
+ isFocused : false ,
161
+ } as TransactionMeta ;
161
162
162
- expect ( blockTrackerMock . on ) . toHaveBeenCalledTimes ( 1 ) ;
163
- } ) ;
163
+ mockGetTransactionsOnce ( [ unfocusedTransactionMeta ] ) ;
164
+ triggerStateChange ( ) ;
164
165
165
- it ( 'does not remove a block tracker listener for a transaction that is not resimulating' , ( ) => {
166
- resimulateHelper . stop ( mockTransactionMeta ) ;
166
+ jest . advanceTimersByTime ( RESIMULATE_INTERVAL_MS / 2 ) ;
167
167
168
- expect ( blockTrackerMock . on ) . toHaveBeenCalledTimes ( 0 ) ;
168
+ expect ( updateSimulationDataMock ) . toHaveBeenCalledTimes ( 0 ) ;
169
169
} ) ;
170
170
171
- describe ( 'on Transaction Controller state change' , ( ) => {
172
- it ( 'start and stop resimulations depending on the isFocused state' , async ( ) => {
173
- const firstTransactionMeta = {
174
- ...mockTransactionMeta ,
175
- networkClientId : 'network1' as NetworkClientId ,
176
- id : '1' ,
177
- } as TransactionMeta ;
178
-
179
- const secondTransactionMeta = {
180
- ...mockTransactionMeta ,
181
- networkClientId : 'network2' as NetworkClientId ,
182
- id : '2' ,
183
- } as TransactionMeta ;
184
-
185
- // Assume both transactions are started to put them in the activeResimulations state
186
- resimulateHelper . start ( firstTransactionMeta ) ;
187
- resimulateHelper . start ( secondTransactionMeta ) ;
188
-
189
- expect ( getBlockTrackerMock ) . toHaveBeenCalledWith (
190
- firstTransactionMeta . networkClientId ,
191
- ) ;
192
- expect ( getBlockTrackerMock ) . toHaveBeenCalledWith (
193
- secondTransactionMeta . networkClientId ,
194
- ) ;
171
+ it ( 'does not resimulate a transaction that is not focused' , ( ) => {
172
+ const unfocusedTransactionMeta = {
173
+ ...mockTransactionMeta ,
174
+ isFocused : false ,
175
+ } as TransactionMeta ;
195
176
196
- // Assume both transactions are still in the transaction list but second is not focused anymore
197
- getTransactionsMock . mockReturnValueOnce ( [
198
- firstTransactionMeta ,
199
- {
200
- ...secondTransactionMeta ,
201
- isFocused : false ,
202
- } ,
203
- ] as unknown as ResimulateHelperOptions [ 'getTransactions' ] ) ;
177
+ mockGetTransactionsOnce ( [ unfocusedTransactionMeta ] ) ;
178
+ triggerStateChange ( ) ;
204
179
205
- // Manually trigger the state change listener
206
- onStateChangeMock . mock . calls [ 0 ] [ 0 ] ( ) ;
180
+ jest . advanceTimersByTime ( 2 * RESIMULATE_INTERVAL_MS ) ;
207
181
208
- expect ( blockTrackerMock . removeListener ) . toHaveBeenCalledWith (
209
- 'latest' ,
210
- expect . any ( Function ) ,
211
- ) ;
182
+ expect ( updateSimulationDataMock ) . toHaveBeenCalledTimes ( 0 ) ;
183
+ } ) ;
212
184
213
- // Manually trigger the block tracker listener
214
- const firstTransactionListener = blockTrackerMock . on . mock . calls [ 0 ] [ 1 ] ;
215
- await firstTransactionListener ( ) ;
185
+ it ( 'stops resimulating a transaction that is no longer in the transaction list' , ( ) => {
186
+ mockGetTransactionsOnce ( [ mockTransactionMeta ] ) ;
187
+ triggerStateChange ( ) ;
216
188
217
- // Assert that first transaction is still in the activeResimulations state
218
- expect ( updateSimulationDataMock ) . toHaveBeenCalledWith (
219
- firstTransactionMeta ,
220
- ) ;
221
- } ) ;
189
+ jest . advanceTimersByTime ( RESIMULATE_INTERVAL_MS ) ;
222
190
223
- it ( 'forces to stop resimulation for a transaction that is no longer in transaction list' , async ( ) => {
224
- const firstTransactionMeta = {
225
- ...mockTransactionMeta ,
226
- networkClientId : 'network1' as NetworkClientId ,
227
- id : '1' ,
228
- } as TransactionMeta ;
229
-
230
- const secondTransactionMeta = {
231
- ...mockTransactionMeta ,
232
- networkClientId : 'network2' as NetworkClientId ,
233
- id : '2' ,
234
- } as TransactionMeta ;
235
-
236
- // Assume both transactions are started to put them in the activeResimulations state
237
- resimulateHelper . start ( firstTransactionMeta ) ;
238
- resimulateHelper . start ( secondTransactionMeta ) ;
239
-
240
- // On next state change, first transaction is still in the transaction list but second is not
241
- getTransactionsMock . mockReturnValueOnce ( [
242
- firstTransactionMeta ,
243
- ] as unknown as ResimulateHelperOptions [ 'getTransactions' ] ) ;
244
-
245
- // Manually trigger the state change listener
246
- onStateChangeMock . mock . calls [ 0 ] [ 0 ] ( ) ;
247
-
248
- expect ( blockTrackerMock . removeListener ) . toHaveBeenCalledWith (
249
- 'latest' ,
250
- expect . any ( Function ) ,
251
- ) ;
191
+ mockGetTransactionsOnce ( [ ] ) ;
192
+ triggerStateChange ( ) ;
252
193
253
- // Manually trigger the block tracker listener
254
- const firstTransactionListener = blockTrackerMock . on . mock . calls [ 0 ] [ 1 ] ;
255
- await firstTransactionListener ( ) ;
194
+ jest . advanceTimersByTime ( RESIMULATE_INTERVAL_MS ) ;
256
195
257
- // Assert that first transaction is still in the activeResimulations state
258
- expect ( updateSimulationDataMock ) . toHaveBeenCalledWith (
259
- firstTransactionMeta ,
260
- ) ;
261
- } ) ;
196
+ expect ( updateSimulationDataMock ) . toHaveBeenCalledTimes ( 1 ) ;
262
197
} ) ;
263
198
} ) ;
264
199
0 commit comments