Skip to content

Commit b399ad1

Browse files
committed
Update tests
1 parent 5d1b7af commit b399ad1

File tree

3 files changed

+105
-22
lines changed

3 files changed

+105
-22
lines changed

packages/performance/src/services/oob_resources_service.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ describe('Firebase Performance > oob_resources_service', () => {
106106
[EntryType, (entry: PerformanceEntry) => void],
107107
void
108108
>;
109-
let createOobTraceStub: SinonSpy<
109+
let createOobTraceSpy: SinonSpy<
110110
[
111111
PerformanceController,
112112
PerformanceNavigationTiming[],
@@ -170,7 +170,7 @@ describe('Firebase Performance > oob_resources_service', () => {
170170
}
171171
);
172172
setupObserverStub = stub(Api.prototype, 'setupObserver');
173-
createOobTraceStub = spy(Trace, 'createOobTrace');
173+
createOobTraceSpy = spy(Trace, 'createOobTrace');
174174
const api = Api.getInstance();
175175
lcpSpy = spy(api, 'onLCP');
176176
inpSpy = spy(api, 'onINP');
@@ -210,7 +210,7 @@ describe('Firebase Performance > oob_resources_service', () => {
210210
clock.tick(1);
211211

212212
expect(apiGetInstanceSpy).to.be.called;
213-
expect(createOobTraceStub).not.to.be.called;
213+
expect(createOobTraceSpy).not.to.be.called;
214214
});
215215

216216
it('creates page load trace after hidden', () => {
@@ -224,7 +224,7 @@ describe('Firebase Performance > oob_resources_service', () => {
224224

225225
expect(getEntriesByTypeStub).to.be.calledWith('navigation');
226226
expect(getEntriesByTypeStub).to.be.calledWith('paint');
227-
expect(createOobTraceStub).to.be.calledWithExactly(
227+
expect(createOobTraceSpy).to.be.calledWithExactly(
228228
performanceController,
229229
[NAVIGATION_PERFORMANCE_ENTRY],
230230
[PAINT_PERFORMANCE_ENTRY],
@@ -243,7 +243,7 @@ describe('Firebase Performance > oob_resources_service', () => {
243243

244244
expect(getEntriesByTypeStub).to.be.calledWith('navigation');
245245
expect(getEntriesByTypeStub).to.be.calledWith('paint');
246-
expect(createOobTraceStub).to.be.calledWithExactly(
246+
expect(createOobTraceSpy).to.be.calledWithExactly(
247247
performanceController,
248248
[NAVIGATION_PERFORMANCE_ENTRY],
249249
[PAINT_PERFORMANCE_ENTRY],
@@ -272,7 +272,7 @@ describe('Firebase Performance > oob_resources_service', () => {
272272
callEventListener('visibilitychange');
273273
clock.tick(1);
274274

275-
expect(createOobTraceStub).to.be.calledWithExactly(
275+
expect(createOobTraceSpy).to.be.calledWithExactly(
276276
performanceController,
277277
[NAVIGATION_PERFORMANCE_ENTRY],
278278
[PAINT_PERFORMANCE_ENTRY],
@@ -308,7 +308,7 @@ describe('Firebase Performance > oob_resources_service', () => {
308308
callEventListener('visibilitychange');
309309
clock.tick(1);
310310

311-
expect(createOobTraceStub).to.be.calledWithExactly(
311+
expect(createOobTraceSpy).to.be.calledWithExactly(
312312
performanceController,
313313
[NAVIGATION_PERFORMANCE_ENTRY],
314314
[PAINT_PERFORMANCE_ENTRY],
@@ -336,7 +336,7 @@ describe('Firebase Performance > oob_resources_service', () => {
336336
callEventListener('visibilitychange');
337337
clock.tick(1);
338338

339-
expect(createOobTraceStub).to.be.calledWithExactly(
339+
expect(createOobTraceSpy).to.be.calledWithExactly(
340340
performanceController,
341341
[NAVIGATION_PERFORMANCE_ENTRY],
342342
[PAINT_PERFORMANCE_ENTRY],
@@ -365,7 +365,7 @@ describe('Firebase Performance > oob_resources_service', () => {
365365
callEventListener('visibilitychange');
366366
clock.tick(1);
367367

368-
expect(createOobTraceStub).to.be.calledWithExactly(
368+
expect(createOobTraceSpy).to.be.calledWithExactly(
369369
performanceController,
370370
[NAVIGATION_PERFORMANCE_ENTRY],
371371
[PAINT_PERFORMANCE_ENTRY],
@@ -400,7 +400,7 @@ describe('Firebase Performance > oob_resources_service', () => {
400400
callEventListener('visibilitychange');
401401
clock.tick(1);
402402

403-
expect(createOobTraceStub).to.be.calledWithExactly(
403+
expect(createOobTraceSpy).to.be.calledWithExactly(
404404
performanceController,
405405
[NAVIGATION_PERFORMANCE_ENTRY],
406406
[PAINT_PERFORMANCE_ENTRY],

packages/performance/src/services/transport_service.test.ts

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { spy, useFakeTimers, SinonFakeTimers } from 'sinon';
18+
import { stub, useFakeTimers, SinonFakeTimers } from 'sinon';
1919
import { use, expect } from 'chai';
2020
import sinonChai from 'sinon-chai';
2121
import {
@@ -27,8 +27,10 @@ import { SettingsService } from './settings_service';
2727

2828
use(sinonChai);
2929

30-
describe('Firebase Performance > transport_service', () => {
31-
const sendBeaconSpy = spy(navigator, 'sendBeacon');
30+
/* eslint-disable no-restricted-properties */
31+
describe.only('Firebase Performance > transport_service', () => {
32+
const sendBeaconStub = stub(navigator, 'sendBeacon');
33+
const fetchStub = stub(window, 'fetch');
3234
const INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000;
3335
const DEFAULT_SEND_INTERVAL_MS = 10 * 1000;
3436
const MAX_EVENT_COUNT_PER_REQUEST = 1000;
@@ -41,12 +43,14 @@ describe('Firebase Performance > transport_service', () => {
4143
beforeEach(() => {
4244
clock = useFakeTimers(1);
4345
setupTransportService();
46+
sendBeaconStub.returns(true);
4447
});
4548

4649
afterEach(() => {
4750
clock.restore();
4851
resetTransportService();
49-
sendBeaconSpy.resetHistory();
52+
sendBeaconStub.restore();
53+
fetchStub.restore();
5054
});
5155

5256
it('throws an error when logging an empty message', () => {
@@ -57,20 +61,23 @@ describe('Firebase Performance > transport_service', () => {
5761

5862
it('does not attempt to log an event after INITIAL_SEND_TIME_DELAY_MS if queue is empty', () => {
5963
clock.tick(INITIAL_SEND_TIME_DELAY_MS);
60-
expect(sendBeaconSpy).to.not.have.been.called;
64+
expect(sendBeaconStub).to.not.have.been.called;
65+
expect(fetchStub).to.not.have.been.called;
6166
});
6267

6368
it('attempts to log an event after DEFAULT_SEND_INTERVAL_MS if queue not empty', async () => {
6469
clock.tick(INITIAL_SEND_TIME_DELAY_MS);
6570
testTransportHandler('someEvent');
6671
clock.tick(DEFAULT_SEND_INTERVAL_MS);
67-
expect(sendBeaconSpy).to.have.been.calledOnce;
72+
expect(sendBeaconStub).to.have.been.calledOnce;
73+
expect(fetchStub).to.not.have.been.called;
6874
});
6975

7076
it('successful send a message to transport', () => {
7177
testTransportHandler('event1');
7278
clock.tick(INITIAL_SEND_TIME_DELAY_MS);
73-
expect(sendBeaconSpy).to.have.been.calledOnce;
79+
expect(sendBeaconStub).to.have.been.calledOnce;
80+
expect(fetchStub).to.not.have.been.called;
7481
});
7582

7683
it('sends up to the maximum event limit in one request', async () => {
@@ -99,7 +106,7 @@ describe('Firebase Performance > transport_service', () => {
99106
'event_time_ms': '1'
100107
});
101108
}
102-
expect(sendBeaconSpy).which.to.have.been.calledWith(
109+
expect(sendBeaconStub).which.to.have.been.calledWith(
103110
flTransportFullUrl,
104111
JSON.stringify(firstLogRequest)
105112
);
@@ -112,7 +119,55 @@ describe('Firebase Performance > transport_service', () => {
112119
'event_time_ms': '1'
113120
});
114121
}
115-
expect(sendBeaconSpy).calledWith(
122+
expect(sendBeaconStub).calledWith(
123+
flTransportFullUrl,
124+
JSON.stringify(secondLogRequest)
125+
);
126+
expect(fetchStub).to.not.have.been.called;
127+
});
128+
129+
it('falls back to fetch if sendBeacon fails.', async () => {
130+
sendBeaconStub.returns(false);
131+
// Arrange
132+
const setting = SettingsService.getInstance();
133+
const flTransportFullUrl =
134+
setting.flTransportEndpointUrl + '?key=' + setting.transportKey;
135+
136+
// Act
137+
// Generate 1020 events, which should be dispatched in two batches (1000 events and 20 events).
138+
for (let i = 0; i < 1020; i++) {
139+
testTransportHandler('event' + i);
140+
}
141+
// Wait for first and second event dispatch to happen.
142+
clock.tick(INITIAL_SEND_TIME_DELAY_MS);
143+
// This is to resolve the floating promise chain in transport service.
144+
await Promise.resolve().then().then().then();
145+
clock.tick(DEFAULT_SEND_INTERVAL_MS);
146+
147+
// Assert
148+
// Expects the first logRequest which contains first 1000 events.
149+
const firstLogRequest = generateLogRequest('5501');
150+
for (let i = 0; i < MAX_EVENT_COUNT_PER_REQUEST; i++) {
151+
firstLogRequest['log_event'].push({
152+
'source_extension_json_proto3': 'event' + i,
153+
'event_time_ms': '1'
154+
});
155+
}
156+
expect(fetchStub).to.not.have.been.called;
157+
expect(sendBeaconStub).which.to.have.been.calledWith(
158+
flTransportFullUrl,
159+
JSON.stringify(firstLogRequest)
160+
);
161+
// Expects the second logRequest which contains remaining 20 events;
162+
const secondLogRequest = generateLogRequest('15501');
163+
for (let i = 0; i < 20; i++) {
164+
secondLogRequest['log_event'].push({
165+
'source_extension_json_proto3':
166+
'event' + (MAX_EVENT_COUNT_PER_REQUEST + i),
167+
'event_time_ms': '1'
168+
});
169+
}
170+
expect(sendBeaconStub).calledWith(
116171
flTransportFullUrl,
117172
JSON.stringify(secondLogRequest)
118173
);

packages/performance/src/services/transport_service.ts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717

1818
import { SettingsService } from './settings_service';
1919
import { ERROR_FACTORY, ErrorCode } from '../utils/errors';
20+
import { consoleLogger } from '../utils/console_logger';
2021

2122
const DEFAULT_SEND_INTERVAL_MS = 10 * 1000;
2223
const INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000;
2324
const MAX_EVENT_COUNT_PER_REQUEST = 1000;
25+
const DEFAULT_REMAINING_TRIES = 3;
26+
27+
let remainingTries = DEFAULT_REMAINING_TRIES;
2428

2529
interface BatchEvent {
2630
message: string;
@@ -68,6 +72,11 @@ export function resetTransportService(): void {
6872

6973
function processQueue(timeOffset: number): void {
7074
setTimeout(() => {
75+
// If there is no remainingTries left, stop retrying.
76+
if (remainingTries === 0) {
77+
return;
78+
}
79+
7180
if (queue.length > 0) {
7281
dispatchQueueEvents();
7382
}
@@ -99,13 +108,32 @@ function dispatchQueueEvents(): void {
99108
};
100109
/* eslint-enable camelcase */
101110

102-
postToFlEndpoint(data);
111+
postToFlEndpoint(data)
112+
.then(() => {
113+
remainingTries = DEFAULT_REMAINING_TRIES;
114+
})
115+
.catch(() => {
116+
// If the request fails for some reason, add the events that were attempted
117+
// back to the primary queue to retry later.
118+
queue = [...staged, ...queue];
119+
remainingTries--;
120+
consoleLogger.info(`Tries left: ${remainingTries}.`);
121+
processQueue(DEFAULT_SEND_INTERVAL_MS);
122+
});
103123
}
104124

105-
function postToFlEndpoint(data: TransportBatchLogFormat): boolean {
125+
function postToFlEndpoint(data: TransportBatchLogFormat): Promise<void> {
106126
const flTransportFullUrl =
107127
SettingsService.getInstance().getFlTransportFullUrl();
108-
return navigator.sendBeacon(flTransportFullUrl, JSON.stringify(data));
128+
const body = JSON.stringify(data);
129+
130+
return navigator.sendBeacon && navigator.sendBeacon(flTransportFullUrl, body)
131+
? Promise.resolve()
132+
: fetch(flTransportFullUrl, {
133+
method: 'POST',
134+
body,
135+
keepalive: true
136+
}).then();
109137
}
110138

111139
function addToQueue(evt: BatchEvent): void {

0 commit comments

Comments
 (0)