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