@@ -19,6 +19,14 @@ describe('useToastState', () => {
19
19
props : { timeout : 0 }
20
20
} ] ;
21
21
22
+ beforeEach ( ( ) => {
23
+ jest . useFakeTimers ( ) ;
24
+ } ) ;
25
+
26
+ afterEach ( ( ) => {
27
+ act ( ( ) => jest . runAllTimers ( ) ) ;
28
+ } ) ;
29
+
22
30
it ( 'should add a new toast via add' , ( ) => {
23
31
let { result} = renderHook ( ( ) => useToastState ( ) ) ;
24
32
expect ( result . current . visibleToasts ) . toStrictEqual ( [ ] ) ;
@@ -58,8 +66,209 @@ describe('useToastState', () => {
58
66
59
67
act ( ( ) => { result . current . add ( secondToast . content , secondToast . props ) ; } ) ;
60
68
expect ( result . current . visibleToasts . length ) . toBe ( 2 ) ;
61
- expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( secondToast . content ) ;
62
- expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( newValue [ 0 ] . content ) ;
69
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( newValue [ 0 ] . content ) ;
70
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( secondToast . content ) ;
71
+ } ) ;
72
+
73
+ it ( 'should be able to display three toasts and remove the middle toast via timeout then the visible toast' , ( ) => {
74
+ let { result} = renderHook ( ( ) => useToastState ( { maxVisibleToasts : 3 } ) ) ;
75
+
76
+ // Add the first toast
77
+ act ( ( ) => {
78
+ result . current . add ( 'First Toast' , { timeout : 0 } ) ;
79
+ } ) ;
80
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
81
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
82
+
83
+ // Add the second toast
84
+ act ( ( ) => {
85
+ result . current . add ( 'Second Toast' , { timeout : 1000 } ) ;
86
+ } ) ;
87
+ expect ( result . current . visibleToasts ) . toHaveLength ( 2 ) ;
88
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
89
+
90
+ result . current . resumeAll ( ) ;
91
+
92
+ // Add the third toast
93
+ act ( ( ) => {
94
+ result . current . add ( 'Third Toast' , { timeout : 0 } ) ;
95
+ } ) ;
96
+ expect ( result . current . visibleToasts ) . toHaveLength ( 3 ) ;
97
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
98
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( 'Second Toast' ) ;
99
+ expect ( result . current . visibleToasts [ 2 ] . content ) . toBe ( 'Third Toast' ) ;
100
+
101
+ act ( ( ) => jest . advanceTimersByTime ( 500 ) ) ;
102
+ expect ( result . current . visibleToasts ) . toHaveLength ( 3 ) ;
103
+
104
+ act ( ( ) => jest . advanceTimersByTime ( 1000 ) ) ;
105
+ expect ( result . current . visibleToasts ) . toHaveLength ( 2 ) ;
106
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
107
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( 'Third Toast' ) ;
108
+
109
+ act ( ( ) => { result . current . close ( result . current . visibleToasts [ 0 ] . key ) ; } ) ;
110
+ expect ( result . current . visibleToasts . length ) . toBe ( 1 ) ;
111
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'Third Toast' ) ;
112
+ } ) ;
113
+
114
+ it ( 'should be able to display one toast without exitAnimation, add multiple toasts, and remove the middle not visible one programmatically' , ( ) => {
115
+ let { result} = renderHook ( ( ) => useToastState ( ) ) ;
116
+
117
+ // Add the first toast
118
+ act ( ( ) => {
119
+ result . current . add ( 'First Toast' , { timeout : 0 } ) ;
120
+ } ) ;
121
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
122
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
123
+
124
+ let secondToastKey = null ;
125
+ // Add the second toast
126
+ act ( ( ) => {
127
+ secondToastKey = result . current . add ( 'Second Toast' , { timeout : 0 } ) ;
128
+ } ) ;
129
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
130
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
131
+
132
+ // Add the third toast
133
+ act ( ( ) => {
134
+ result . current . add ( 'Third Toast' , { timeout : 0 } ) ;
135
+ } ) ;
136
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
137
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
138
+
139
+ // Remove a toast that isn't visible
140
+ act ( ( ) => { result . current . close ( secondToastKey ) ; } ) ;
141
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
142
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
143
+
144
+ // Remove the visible toast to confirm the middle toast was removed
145
+ act ( ( ) => { result . current . close ( result . current . visibleToasts [ 0 ] . key ) ; } ) ;
146
+ expect ( result . current . visibleToasts . length ) . toBe ( 1 ) ;
147
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'Third Toast' ) ;
148
+ } ) ;
149
+
150
+ it ( 'should be able to display one toast with exitAnimation, add multiple toasts, and remove the middle not visible one programmatically' , ( ) => {
151
+ let { result} = renderHook ( ( ) => useToastState ( { hasExitAnimation : true } ) ) ;
152
+
153
+ // Add the first toast
154
+ act ( ( ) => {
155
+ result . current . add ( 'First Toast' , { timeout : 0 } ) ;
156
+ } ) ;
157
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
158
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
159
+
160
+ let secondToastKey = null ;
161
+ // Add the second toast
162
+ act ( ( ) => {
163
+ secondToastKey = result . current . add ( 'Second Toast' , { timeout : 0 } ) ;
164
+ } ) ;
165
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
166
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
167
+
168
+ // Add the third toast
169
+ act ( ( ) => {
170
+ result . current . add ( 'Third Toast' , { timeout : 0 } ) ;
171
+ } ) ;
172
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
173
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
174
+
175
+ // Remove a toast that isn't visible
176
+ act ( ( ) => { result . current . close ( secondToastKey ) ; } ) ;
177
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
178
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
179
+
180
+ // Remove the visible toast to confirm the middle toast was removed
181
+ act ( ( ) => { result . current . close ( result . current . visibleToasts [ 0 ] . key ) ; } ) ;
182
+ expect ( result . current . visibleToasts . length ) . toBe ( 1 ) ;
183
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
184
+ expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'exiting' ) ;
185
+ act ( ( ) => { result . current . remove ( result . current . visibleToasts [ 0 ] . key ) ; } ) ;
186
+
187
+ // there should only be one Toast left, the third one
188
+ expect ( result . current . visibleToasts . length ) . toBe ( 1 ) ;
189
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'Third Toast' ) ;
190
+ } ) ;
191
+
192
+ it ( 'should add a exit animation to a toast that is moved out of the visible list by a higher priority toast' , ( ) => {
193
+ let { result} = renderHook ( ( ) => useToastState ( { hasExitAnimation : true , maxVisibleToasts : 2 } ) ) ;
194
+
195
+ act ( ( ) => { result . current . add ( 'First Toast' , { priority : 5 } ) ; } ) ;
196
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
197
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
198
+ expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'entering' ) ;
199
+
200
+ act ( ( ) => { result . current . add ( 'Second Toast' , { priority : 1 } ) ; } ) ;
201
+ expect ( result . current . visibleToasts . length ) . toBe ( 2 ) ;
202
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
203
+ expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'entering' ) ;
204
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( 'Second Toast' ) ;
205
+ expect ( result . current . visibleToasts [ 1 ] . animation ) . toBe ( 'entering' ) ;
206
+
207
+ act ( ( ) => { result . current . add ( 'Third Toast' , { priority : 10 } ) ; } ) ;
208
+ expect ( result . current . visibleToasts . length ) . toBe ( 3 ) ;
209
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'Third Toast' ) ;
210
+ expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'entering' ) ;
211
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( 'First Toast' ) ;
212
+ expect ( result . current . visibleToasts [ 1 ] . animation ) . toBe ( 'entering' ) ;
213
+ expect ( result . current . visibleToasts [ 2 ] . content ) . toBe ( 'Second Toast' ) ;
214
+ expect ( result . current . visibleToasts [ 2 ] . animation ) . toBe ( 'exiting' ) ;
215
+
216
+ // Remove shouldn't get rid of the lower priority toast from the queue so that it may return when there is
217
+ // enough room. The below mimics a remove call that might be called in onAnimationEnd
218
+ act ( ( ) => { result . current . remove ( result . current . visibleToasts [ 2 ] . key ) ; } ) ;
219
+ expect ( result . current . visibleToasts . length ) . toBe ( 2 ) ;
220
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'Third Toast' ) ;
221
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( 'First Toast' ) ;
222
+
223
+ act ( ( ) => { result . current . close ( result . current . visibleToasts [ 0 ] . key ) ; } ) ;
224
+ act ( ( ) => { result . current . remove ( result . current . visibleToasts [ 0 ] . key ) ; } ) ;
225
+ expect ( result . current . visibleToasts . length ) . toBe ( 2 ) ;
226
+
227
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
228
+ expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'entering' ) ;
229
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( 'Second Toast' ) ;
230
+ expect ( result . current . visibleToasts [ 1 ] . animation ) . toBe ( 'queued' ) ;
231
+ } ) ;
232
+
233
+ it ( 'should maintain the toast queue order on close and apply exiting to the closing toast' , ( ) => {
234
+ let { result} = renderHook ( ( ) => useToastState ( { hasExitAnimation : true , maxVisibleToasts : 3 } ) ) ;
235
+
236
+ act ( ( ) => { result . current . add ( 'First Toast' ) ; } ) ;
237
+ expect ( result . current . visibleToasts ) . toHaveLength ( 1 ) ;
238
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
239
+ expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'entering' ) ;
240
+
241
+ act ( ( ) => { result . current . add ( 'Second Toast' ) ; } ) ;
242
+ expect ( result . current . visibleToasts ) . toHaveLength ( 2 ) ;
243
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
244
+ expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'entering' ) ;
245
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( 'Second Toast' ) ;
246
+ expect ( result . current . visibleToasts [ 1 ] . animation ) . toBe ( 'entering' ) ;
247
+
248
+ act ( ( ) => { result . current . add ( 'Third Toast' ) ; } ) ;
249
+ expect ( result . current . visibleToasts ) . toHaveLength ( 3 ) ;
250
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
251
+ expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'entering' ) ;
252
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( 'Second Toast' ) ;
253
+ expect ( result . current . visibleToasts [ 1 ] . animation ) . toBe ( 'entering' ) ;
254
+ expect ( result . current . visibleToasts [ 2 ] . content ) . toBe ( 'Third Toast' ) ;
255
+ expect ( result . current . visibleToasts [ 2 ] . animation ) . toBe ( 'entering' ) ;
256
+
257
+ act ( ( ) => { result . current . close ( result . current . visibleToasts [ 1 ] . key ) ; } ) ;
258
+ expect ( result . current . visibleToasts ) . toHaveLength ( 3 ) ;
259
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
260
+ expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'entering' ) ;
261
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( 'Second Toast' ) ;
262
+ expect ( result . current . visibleToasts [ 1 ] . animation ) . toBe ( 'exiting' ) ;
263
+ expect ( result . current . visibleToasts [ 2 ] . content ) . toBe ( 'Third Toast' ) ;
264
+ expect ( result . current . visibleToasts [ 2 ] . animation ) . toBe ( 'entering' ) ;
265
+
266
+ act ( ( ) => { result . current . remove ( result . current . visibleToasts [ 1 ] . key ) ; } ) ;
267
+ expect ( result . current . visibleToasts ) . toHaveLength ( 2 ) ;
268
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'First Toast' ) ;
269
+ expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'entering' ) ;
270
+ expect ( result . current . visibleToasts [ 1 ] . content ) . toBe ( 'Third Toast' ) ;
271
+ expect ( result . current . visibleToasts [ 1 ] . animation ) . toBe ( 'entering' ) ;
63
272
} ) ;
64
273
65
274
it ( 'should close a toast' , ( ) => {
@@ -91,11 +300,11 @@ describe('useToastState', () => {
91
300
92
301
act ( ( ) => { result . current . add ( 'Second Toast' ) ; } ) ;
93
302
expect ( result . current . visibleToasts . length ) . toBe ( 1 ) ;
94
- expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'Second Toast' ) ;
303
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( newValue [ 0 ] . content ) ;
95
304
96
305
act ( ( ) => { result . current . close ( result . current . visibleToasts [ 0 ] . key ) ; } ) ;
97
306
expect ( result . current . visibleToasts . length ) . toBe ( 1 ) ;
98
- expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( newValue [ 0 ] . content ) ;
307
+ expect ( result . current . visibleToasts [ 0 ] . content ) . toBe ( 'Second Toast' ) ;
99
308
expect ( result . current . visibleToasts [ 0 ] . animation ) . toBe ( 'queued' ) ;
100
309
} ) ;
101
310
0 commit comments