Update Fireperf logging to use sendBeacon only if the payload is unde… · firebase/firebase-js-sdk@3d44792 (original) (raw)
`@@ -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,14 +89,15 @@ 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 =
`
95
96
`setting.flTransportEndpointUrl + '?key=' + setting.transportKey;
`
96
97
``
97
98
`// 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).
`
99
101
`for (let i = 0; i < 1020; i++) {
`
100
102
`testTransportHandler('event' + i);
`
101
103
`}
`
`@@ -134,6 +136,58 @@ describe('Firebase Performance > transport_service', () => {
`
134
136
`expect(fetchStub).to.not.have.been.called;
`
135
137
`});
`
136
138
``
``
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
+
137
191
`it('falls back to fetch if sendBeacon fails.', async () => {
`
138
192
`sendBeaconStub.returns(false);
`
139
193
`fetchStub.resolves(
`
`@@ -147,6 +201,98 @@ describe('Firebase Performance > transport_service', () => {
`
147
201
`expect(fetchStub).to.have.been.calledOnce;
`
148
202
`});
`
149
203
``
``
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
+
150
296
`function generateLogRequest(requestTimeMs: string): any {
`
151
297
`return {
`
152
298
`'request_time_ms': requestTimeMs,
`