@@ -21,7 +21,8 @@ import sinonChai from 'sinon-chai';
21
21
import {
22
22
transportHandler ,
23
23
setupTransportService ,
24
- resetTransportService
24
+ resetTransportService ,
25
+ flushQueuedEvents
25
26
} from './transport_service' ;
26
27
import { SettingsService } from './settings_service' ;
27
28
@@ -88,7 +89,7 @@ describe('Firebase Performance > transport_service', () => {
88
89
expect ( fetchStub ) . to . not . have . been . called ;
89
90
} ) ;
90
91
91
- it ( 'sends up to the maximum event limit in one request' , async ( ) => {
92
+ it ( 'sends up to the maximum event limit in one request if payload is under 64 KB ' , async ( ) => {
92
93
// Arrange
93
94
const setting = SettingsService . getInstance ( ) ;
94
95
const flTransportFullUrl =
@@ -134,6 +135,58 @@ describe('Firebase Performance > transport_service', () => {
134
135
expect ( fetchStub ) . to . not . have . been . called ;
135
136
} ) ;
136
137
138
+ it ( 'sends fetch if payload is above 64 KB' , async ( ) => {
139
+ // Arrange
140
+ const setting = SettingsService . getInstance ( ) ;
141
+ const flTransportFullUrl =
142
+ setting . flTransportEndpointUrl + '?key=' + setting . transportKey ;
143
+ fetchStub . resolves (
144
+ new Response ( '{}' , {
145
+ status : 200 ,
146
+ headers : { 'Content-type' : 'application/json' }
147
+ } )
148
+ ) ;
149
+
150
+ const payload = 'a' . repeat ( 300 ) ;
151
+ // Act
152
+ // Generate 1020 events
153
+ for ( let i = 0 ; i < 1020 ; i ++ ) {
154
+ testTransportHandler ( payload + i ) ;
155
+ }
156
+ // Wait for first and second event dispatch to happen.
157
+ clock . tick ( INITIAL_SEND_TIME_DELAY_MS ) ;
158
+ // This is to resolve the floating promise chain in transport service.
159
+ await Promise . resolve ( ) . then ( ) . then ( ) . then ( ) ;
160
+ clock . tick ( DEFAULT_SEND_INTERVAL_MS ) ;
161
+
162
+ // Assert
163
+ // Expects the first logRequest which contains first 1000 events.
164
+ const firstLogRequest = generateLogRequest ( '5501' ) ;
165
+ for ( let i = 0 ; i < MAX_EVENT_COUNT_PER_REQUEST ; i ++ ) {
166
+ firstLogRequest [ 'log_event' ] . push ( {
167
+ 'source_extension_json_proto3' : payload + i ,
168
+ 'event_time_ms' : '1'
169
+ } ) ;
170
+ }
171
+ expect ( fetchStub ) . calledWith ( flTransportFullUrl , {
172
+ method : 'POST' ,
173
+ body : JSON . stringify ( firstLogRequest )
174
+ } ) ;
175
+ // Expects the second logRequest which contains remaining 20 events;
176
+ const secondLogRequest = generateLogRequest ( '15501' ) ;
177
+ for ( let i = 0 ; i < 20 ; i ++ ) {
178
+ secondLogRequest [ 'log_event' ] . push ( {
179
+ 'source_extension_json_proto3' :
180
+ payload + ( MAX_EVENT_COUNT_PER_REQUEST + i ) ,
181
+ 'event_time_ms' : '1'
182
+ } ) ;
183
+ }
184
+ expect ( sendBeaconStub ) . calledWith (
185
+ flTransportFullUrl ,
186
+ JSON . stringify ( secondLogRequest )
187
+ ) ;
188
+ } ) ;
189
+
137
190
it ( 'falls back to fetch if sendBeacon fails.' , async ( ) => {
138
191
sendBeaconStub . returns ( false ) ;
139
192
fetchStub . resolves (
@@ -147,6 +200,98 @@ describe('Firebase Performance > transport_service', () => {
147
200
expect ( fetchStub ) . to . have . been . calledOnce ;
148
201
} ) ;
149
202
203
+ it ( 'flushes the queue with multiple sendBeacons in batches of 40' , async ( ) => {
204
+ // Arrange
205
+ const setting = SettingsService . getInstance ( ) ;
206
+ const flTransportFullUrl =
207
+ setting . flTransportEndpointUrl + '?key=' + setting . transportKey ;
208
+ fetchStub . resolves (
209
+ new Response ( '{}' , {
210
+ status : 200 ,
211
+ headers : { 'Content-type' : 'application/json' }
212
+ } )
213
+ ) ;
214
+
215
+ const payload = 'a' . repeat ( 300 ) ;
216
+ // Act
217
+ // Generate 80 events
218
+ for ( let i = 0 ; i < 80 ; i ++ ) {
219
+ testTransportHandler ( payload + i ) ;
220
+ }
221
+
222
+ flushQueuedEvents ( ) ;
223
+
224
+ // Assert
225
+ const firstLogRequest = generateLogRequest ( '1' ) ;
226
+ const secondLogRequest = generateLogRequest ( '1' ) ;
227
+ for ( let i = 0 ; i < 40 ; i ++ ) {
228
+ firstLogRequest [ 'log_event' ] . push ( {
229
+ 'source_extension_json_proto3' : payload + ( i + 40 ) ,
230
+ 'event_time_ms' : '1'
231
+ } ) ;
232
+ secondLogRequest [ 'log_event' ] . push ( {
233
+ 'source_extension_json_proto3' : payload + i ,
234
+ 'event_time_ms' : '1'
235
+ } ) ;
236
+ }
237
+ expect ( sendBeaconStub ) . calledWith (
238
+ flTransportFullUrl ,
239
+ JSON . stringify ( firstLogRequest )
240
+ ) ;
241
+ expect ( sendBeaconStub ) . calledWith (
242
+ flTransportFullUrl ,
243
+ JSON . stringify ( secondLogRequest )
244
+ ) ;
245
+ expect ( fetchStub ) . to . not . have . been . called ;
246
+ } ) ;
247
+
248
+ it ( 'flushes the queue with fetch for sendBeacons that failed' , async ( ) => {
249
+ // Arrange
250
+ const setting = SettingsService . getInstance ( ) ;
251
+ const flTransportFullUrl =
252
+ setting . flTransportEndpointUrl + '?key=' + setting . transportKey ;
253
+ fetchStub . resolves (
254
+ new Response ( '{}' , {
255
+ status : 200 ,
256
+ headers : { 'Content-type' : 'application/json' }
257
+ } )
258
+ ) ;
259
+
260
+ const payload = 'a' . repeat ( 300 ) ;
261
+ // Act
262
+ // Generate 80 events
263
+ for ( let i = 0 ; i < 80 ; i ++ ) {
264
+ testTransportHandler ( payload + i ) ;
265
+ }
266
+ sendBeaconStub . onCall ( 0 ) . returns ( true ) ;
267
+ sendBeaconStub . onCall ( 1 ) . returns ( false ) ;
268
+ flushQueuedEvents ( ) ;
269
+
270
+ // Assert
271
+ const firstLogRequest = generateLogRequest ( '1' ) ;
272
+ const secondLogRequest = generateLogRequest ( '1' ) ;
273
+ for ( let i = 40 ; i < 80 ; i ++ ) {
274
+ firstLogRequest [ 'log_event' ] . push ( {
275
+ 'source_extension_json_proto3' : payload + i ,
276
+ 'event_time_ms' : '1'
277
+ } ) ;
278
+ }
279
+ for ( let i = 0 ; i < 40 ; i ++ ) {
280
+ secondLogRequest [ 'log_event' ] . push ( {
281
+ 'source_extension_json_proto3' : payload + i ,
282
+ 'event_time_ms' : '1'
283
+ } ) ;
284
+ }
285
+ expect ( sendBeaconStub ) . calledWith (
286
+ flTransportFullUrl ,
287
+ JSON . stringify ( firstLogRequest )
288
+ ) ;
289
+ expect ( fetchStub ) . calledWith ( flTransportFullUrl , {
290
+ method : 'POST' ,
291
+ body : JSON . stringify ( secondLogRequest )
292
+ } ) ;
293
+ } ) ;
294
+
150
295
function generateLogRequest ( requestTimeMs : string ) : any {
151
296
return {
152
297
'request_time_ms' : requestTimeMs ,
0 commit comments