@@ -44,6 +44,15 @@ const customGtagName = 'customGtag';
44
44
const customDataLayerName = 'customDataLayer' ;
45
45
let clock : sinon . SinonFakeTimers ;
46
46
47
+ // Fake indexedDB.open() request
48
+ let fakeRequest = {
49
+ onsuccess : ( ) => { } ,
50
+ result : {
51
+ close : ( ) => { }
52
+ }
53
+ } ;
54
+ let idbOpenStub = stub ( ) ;
55
+
47
56
function stubFetch ( status : number , body : object ) : void {
48
57
fetchStub = stub ( window , 'fetch' ) ;
49
58
const mockResponse = new Response ( JSON . stringify ( body ) , {
@@ -52,6 +61,18 @@ function stubFetch(status: number, body: object): void {
52
61
fetchStub . returns ( Promise . resolve ( mockResponse ) ) ;
53
62
}
54
63
64
+ // Stub indexedDB.open() because sinon's clock does not know
65
+ // how to wait for the real indexedDB callbacks to resolve.
66
+ function stubIdbOpen ( ) : void {
67
+ ( fakeRequest = {
68
+ onsuccess : ( ) => { } ,
69
+ result : {
70
+ close : ( ) => { }
71
+ }
72
+ } ) ,
73
+ ( idbOpenStub = stub ( indexedDB , 'open' ) . returns ( fakeRequest as any ) ) ;
74
+ }
75
+
55
76
describe ( 'FirebaseAnalytics instance tests' , ( ) => {
56
77
describe ( 'Initialization' , ( ) => {
57
78
beforeEach ( ( ) => resetGlobalVars ( ) ) ;
@@ -83,64 +104,50 @@ describe('FirebaseAnalytics instance tests', () => {
83
104
) ;
84
105
warnStub . restore ( ) ;
85
106
} ) ;
86
- it ( 'Throws if cookies are not enabled' , ( ) => {
107
+ it ( 'Warns if cookies are not enabled' , ( ) => {
108
+ const warnStub = stub ( console , 'warn' ) ;
87
109
const cookieStub = stub ( navigator , 'cookieEnabled' ) . value ( false ) ;
88
110
const app = getFakeApp ( {
89
111
appId : fakeAppParams . appId ,
90
112
apiKey : fakeAppParams . apiKey
91
113
} ) ;
92
114
const installations = getFakeInstallations ( ) ;
93
- expect ( ( ) => analyticsFactory ( app , installations ) ) . to . throw (
115
+ analyticsFactory ( app , installations ) ;
116
+ expect ( warnStub . args [ 0 ] [ 1 ] ) . to . include (
94
117
AnalyticsError . COOKIES_NOT_ENABLED
95
118
) ;
119
+ warnStub . restore ( ) ;
96
120
cookieStub . restore ( ) ;
97
121
} ) ;
98
- it ( 'Throws if browser extension environment' , ( ) => {
122
+ it ( 'Warns if browser extension environment' , ( ) => {
123
+ const warnStub = stub ( console , 'warn' ) ;
99
124
window . chrome = { runtime : { id : 'blah' } } ;
100
125
const app = getFakeApp ( {
101
126
appId : fakeAppParams . appId ,
102
127
apiKey : fakeAppParams . apiKey
103
128
} ) ;
104
129
const installations = getFakeInstallations ( ) ;
105
- expect ( ( ) => analyticsFactory ( app , installations ) ) . to . throw (
130
+ analyticsFactory ( app , installations ) ;
131
+ expect ( warnStub . args [ 0 ] [ 1 ] ) . to . include (
106
132
AnalyticsError . INVALID_ANALYTICS_CONTEXT
107
133
) ;
134
+ warnStub . restore ( ) ;
108
135
window . chrome = undefined ;
109
136
} ) ;
110
- it ( 'Throws if indexedDB does not exist' , ( ) => {
111
- const idbStub = stub ( window , 'indexedDB' ) . value ( undefined ) ;
112
- const app = getFakeApp ( {
113
- appId : fakeAppParams . appId ,
114
- apiKey : fakeAppParams . apiKey
115
- } ) ;
116
- const installations = getFakeInstallations ( ) ;
117
- expect ( ( ) => analyticsFactory ( app , installations ) ) . to . throw (
118
- AnalyticsError . INDEXED_DB_UNSUPPORTED
119
- ) ;
120
- idbStub . restore ( ) ;
121
- } ) ;
122
- it ( 'Warns eventually if indexedDB.open() does not work' , async ( ) => {
123
- clock = useFakeTimers ( ) ;
124
- stubFetch ( 200 , { measurementId : fakeMeasurementId } ) ;
137
+ it ( 'Warns if indexedDB does not exist' , ( ) => {
125
138
const warnStub = stub ( console , 'warn' ) ;
126
- const idbOpenStub = stub ( indexedDB , 'open' ) . throws (
127
- 'idb open throw message'
128
- ) ;
139
+ const idbStub = stub ( window , 'indexedDB' ) . value ( undefined ) ;
129
140
const app = getFakeApp ( {
130
141
appId : fakeAppParams . appId ,
131
142
apiKey : fakeAppParams . apiKey
132
143
} ) ;
133
144
const installations = getFakeInstallations ( ) ;
134
145
analyticsFactory ( app , installations ) ;
135
- await clock . runAllAsync ( ) ;
136
146
expect ( warnStub . args [ 0 ] [ 1 ] ) . to . include (
137
- AnalyticsError . INVALID_INDEXED_DB_CONTEXT
147
+ AnalyticsError . INDEXED_DB_UNSUPPORTED
138
148
) ;
139
- expect ( warnStub . args [ 0 ] [ 1 ] ) . to . include ( 'idb open throw message' ) ;
140
149
warnStub . restore ( ) ;
141
- idbOpenStub . restore ( ) ;
142
- fetchStub . restore ( ) ;
143
- clock . restore ( ) ;
150
+ idbStub . restore ( ) ;
144
151
} ) ;
145
152
it ( 'Throws if creating an instance with already-used appId' , ( ) => {
146
153
const app = getFakeApp ( fakeAppParams ) ;
@@ -166,6 +173,7 @@ describe('FirebaseAnalytics instance tests', () => {
166
173
window [ 'gtag' ] = gtagStub ;
167
174
window [ 'dataLayer' ] = [ ] ;
168
175
stubFetch ( 200 , { measurementId : fakeMeasurementId } ) ;
176
+ stubIdbOpen ( ) ;
169
177
analyticsInstance = analyticsFactory ( app , installations ) ;
170
178
} ) ;
171
179
after ( ( ) => {
@@ -174,6 +182,7 @@ describe('FirebaseAnalytics instance tests', () => {
174
182
removeGtagScript ( ) ;
175
183
fetchStub . restore ( ) ;
176
184
clock . restore ( ) ;
185
+ idbOpenStub . restore ( ) ;
177
186
} ) ;
178
187
it ( 'Contains reference to parent app' , ( ) => {
179
188
expect ( analyticsInstance . app ) . to . equal ( app ) ;
@@ -182,6 +191,8 @@ describe('FirebaseAnalytics instance tests', () => {
182
191
analyticsInstance . logEvent ( EventName . ADD_PAYMENT_INFO , {
183
192
currency : 'USD'
184
193
} ) ;
194
+ // Successfully resolves fake IDB open request.
195
+ fakeRequest . onsuccess ( ) ;
185
196
// Clear promise chain started by logEvent.
186
197
await clock . runAllAsync ( ) ;
187
198
expect ( gtagStub ) . to . have . been . calledWith ( 'js' ) ;
@@ -219,6 +230,48 @@ describe('FirebaseAnalytics instance tests', () => {
219
230
} ) ;
220
231
} ) ;
221
232
233
+ describe ( 'Standard app, indexedDB.open not available' , ( ) => {
234
+ let app : FirebaseApp = { } as FirebaseApp ;
235
+ let fidDeferred : Deferred < void > ;
236
+ const gtagStub : SinonStub = stub ( ) ;
237
+ let warnStub : SinonStub ;
238
+ before ( ( ) => {
239
+ clock = useFakeTimers ( ) ;
240
+ resetGlobalVars ( ) ;
241
+ app = getFakeApp ( fakeAppParams ) ;
242
+ fidDeferred = new Deferred < void > ( ) ;
243
+ const installations = getFakeInstallations ( 'fid-1234' , ( ) =>
244
+ fidDeferred . resolve ( )
245
+ ) ;
246
+ window [ 'gtag' ] = gtagStub ;
247
+ window [ 'dataLayer' ] = [ ] ;
248
+ stubFetch ( 200 , { measurementId : fakeMeasurementId } ) ;
249
+ warnStub = stub ( console , 'warn' ) ;
250
+ idbOpenStub = stub ( indexedDB , 'open' ) . throws ( 'idb open error' ) ;
251
+ analyticsInstance = analyticsFactory ( app , installations ) ;
252
+ } ) ;
253
+ after ( ( ) => {
254
+ delete window [ 'gtag' ] ;
255
+ delete window [ 'dataLayer' ] ;
256
+ removeGtagScript ( ) ;
257
+ fetchStub . restore ( ) ;
258
+ clock . restore ( ) ;
259
+ idbOpenStub . restore ( ) ;
260
+ warnStub . restore ( ) ;
261
+ } ) ;
262
+ it ( 'Does not call gtag on logEvent but does not throw' , async ( ) => {
263
+ analyticsInstance . logEvent ( EventName . ADD_PAYMENT_INFO , {
264
+ currency : 'USD'
265
+ } ) ;
266
+ // Clear promise chain started by logEvent.
267
+ await clock . runAllAsync ( ) ;
268
+ expect ( gtagStub ) . to . not . have . been . called ;
269
+ expect ( warnStub . args [ 0 ] [ 1 ] ) . to . include (
270
+ AnalyticsError . INVALID_INDEXED_DB_CONTEXT
271
+ ) ;
272
+ } ) ;
273
+ } ) ;
274
+
222
275
describe ( 'Page has user gtag script with custom gtag and dataLayer names' , ( ) => {
223
276
let app : FirebaseApp = { } as FirebaseApp ;
224
277
let fidDeferred : Deferred < void > ;
@@ -237,6 +290,7 @@ describe('FirebaseAnalytics instance tests', () => {
237
290
dataLayerName : customDataLayerName ,
238
291
gtagName : customGtagName
239
292
} ) ;
293
+ stubIdbOpen ( ) ;
240
294
stubFetch ( 200 , { measurementId : fakeMeasurementId } ) ;
241
295
analyticsInstance = analyticsFactory ( app , installations ) ;
242
296
} ) ;
@@ -246,11 +300,14 @@ describe('FirebaseAnalytics instance tests', () => {
246
300
removeGtagScript ( ) ;
247
301
fetchStub . restore ( ) ;
248
302
clock . restore ( ) ;
303
+ idbOpenStub . restore ( ) ;
249
304
} ) ;
250
305
it ( 'Calls gtag correctly on logEvent (instance)' , async ( ) => {
251
306
analyticsInstance . logEvent ( EventName . ADD_PAYMENT_INFO , {
252
307
currency : 'USD'
253
308
} ) ;
309
+ // Successfully resolves fake IDB open request.
310
+ fakeRequest . onsuccess ( ) ;
254
311
// Clear promise chain started by logEvent.
255
312
await clock . runAllAsync ( ) ;
256
313
expect ( gtagStub ) . to . have . been . calledWith ( 'js' ) ;
@@ -280,9 +337,12 @@ describe('FirebaseAnalytics instance tests', () => {
280
337
const app = getFakeApp ( fakeAppParams ) ;
281
338
const installations = getFakeInstallations ( ) ;
282
339
stubFetch ( 200 , { } ) ;
340
+ stubIdbOpen ( ) ;
283
341
analyticsInstance = analyticsFactory ( app , installations ) ;
284
342
285
343
const { initializationPromisesMap } = getGlobalVars ( ) ;
344
+ // Successfully resolves fake IDB open request.
345
+ fakeRequest . onsuccess ( ) ;
286
346
await initializationPromisesMap [ fakeAppParams . appId ] ;
287
347
expect ( findGtagScriptOnPage ( ) ) . to . not . be . null ;
288
348
expect ( typeof window [ 'gtag' ] ) . to . equal ( 'function' ) ;
@@ -292,6 +352,7 @@ describe('FirebaseAnalytics instance tests', () => {
292
352
delete window [ 'dataLayer' ] ;
293
353
removeGtagScript ( ) ;
294
354
fetchStub . restore ( ) ;
355
+ idbOpenStub . restore ( ) ;
295
356
} ) ;
296
357
} ) ;
297
358
} ) ;
0 commit comments