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