@@ -35,6 +35,7 @@ import {
3535import { Component , ComponentType } from '@firebase/component' ;
3636import { FirebaseAppCheckInternal } from '@firebase/app-check-interop-types' ;
3737import { captureError , flush , getTelemetry } from './api' ;
38+ import { LOG_ENTRY_ATTRIBUTE_KEYS , TELEMETRY_SESSION_ID_KEY } from './constants' ;
3839import { TelemetryService } from './service' ;
3940import { registerTelemetry } from './register' ;
4041import { _FirebaseInstallationsInternal } from '@firebase/installations' ;
@@ -127,7 +128,7 @@ describe('Top level API', () => {
127128 expect ( log . attributes ) . to . deep . equal ( {
128129 'error.type' : 'TestError' ,
129130 'error.stack' : '...stack trace...' ,
130- 'app.version' : 'unset'
131+ [ LOG_ENTRY_ATTRIBUTE_KEYS . APP_VERSION ] : 'unset'
131132 } ) ;
132133 } ) ;
133134
@@ -144,7 +145,7 @@ describe('Top level API', () => {
144145 expect ( log . attributes ) . to . deep . equal ( {
145146 'error.type' : 'Error' ,
146147 'error.stack' : 'No stack trace available' ,
147- 'app.version' : 'unset'
148+ [ LOG_ENTRY_ATTRIBUTE_KEYS . APP_VERSION ] : 'unset'
148149 } ) ;
149150 } ) ;
150151
@@ -156,7 +157,7 @@ describe('Top level API', () => {
156157 expect ( log . severityNumber ) . to . equal ( SeverityNumber . ERROR ) ;
157158 expect ( log . body ) . to . equal ( 'a string error' ) ;
158159 expect ( log . attributes ) . to . deep . equal ( {
159- 'app.version' : 'unset'
160+ [ LOG_ENTRY_ATTRIBUTE_KEYS . APP_VERSION ] : 'unset'
160161 } ) ;
161162 } ) ;
162163
@@ -168,7 +169,7 @@ describe('Top level API', () => {
168169 expect ( log . severityNumber ) . to . equal ( SeverityNumber . ERROR ) ;
169170 expect ( log . body ) . to . equal ( 'Unknown error type: number' ) ;
170171 expect ( log . attributes ) . to . deep . equal ( {
171- 'app.version' : 'unset'
172+ [ LOG_ENTRY_ATTRIBUTE_KEYS . APP_VERSION ] : 'unset'
172173 } ) ;
173174 } ) ;
174175
@@ -195,7 +196,7 @@ describe('Top level API', () => {
195196 expect ( emittedLogs [ 0 ] . attributes ) . to . deep . equal ( {
196197 'error.type' : 'TestError' ,
197198 'error.stack' : '...stack trace...' ,
198- 'app.version' : 'unset' ,
199+ [ LOG_ENTRY_ATTRIBUTE_KEYS . APP_VERSION ] : 'unset' ,
199200 'logging.googleapis.com/trace' : `projects/${ PROJECT_ID } /traces/my-trace` ,
200201 'logging.googleapis.com/spanId' : `my-span`
201202 } ) ;
@@ -220,7 +221,7 @@ describe('Top level API', () => {
220221 expect ( log . attributes ) . to . deep . equal ( {
221222 'error.type' : 'TestError' ,
222223 'error.stack' : '...stack trace...' ,
223- 'app.version' : 'unset' ,
224+ [ LOG_ENTRY_ATTRIBUTE_KEYS . APP_VERSION ] : 'unset' ,
224225 strAttr : 'string attribute' ,
225226 mapAttr : {
226227 boolAttr : true ,
@@ -244,7 +245,111 @@ describe('Top level API', () => {
244245 expect ( emittedLogs . length ) . to . equal ( 1 ) ;
245246 const log = emittedLogs [ 0 ] ;
246247 expect ( log . attributes ) . to . deep . equal ( {
247- 'app.version' : '1.0.0'
248+ [ LOG_ENTRY_ATTRIBUTE_KEYS . APP_VERSION ] : '1.0.0'
249+ } ) ;
250+ } ) ;
251+
252+ describe ( 'Session Metadata' , ( ) => {
253+ let originalSessionStorage : Storage | undefined ;
254+ let originalCrypto : Crypto | undefined ;
255+
256+ beforeEach ( ( ) => {
257+ // @ts -ignore
258+ originalSessionStorage = global . sessionStorage ;
259+ // @ts -ignore
260+ originalCrypto = global . crypto ;
261+ } ) ;
262+
263+ afterEach ( ( ) => {
264+ Object . defineProperty ( global , 'sessionStorage' , {
265+ value : originalSessionStorage ,
266+ writable : true
267+ } ) ;
268+ Object . defineProperty ( global , 'crypto' , {
269+ value : originalCrypto ,
270+ writable : true
271+ } ) ;
272+ } ) ;
273+
274+ it ( 'should generate and store a new session ID if none exists' , ( ) => {
275+ const sessionStorageMock = {
276+ getItem : ( ) => null ,
277+ setItem : ( _ : string , __ : string ) => { }
278+ } ;
279+ sessionStorageMock . setItem = (
280+ key : string ,
281+ value : string
282+ ) => {
283+ // @ts -ignore
284+ sessionStorageMock [ key ] = value ;
285+ } ;
286+ const cryptoMock = {
287+ randomUUID : ( ) => 'new-session-id'
288+ } ;
289+
290+ Object . defineProperty ( global , 'sessionStorage' , {
291+ value : sessionStorageMock ,
292+ writable : true
293+ } ) ;
294+ Object . defineProperty ( global , 'crypto' , {
295+ value : cryptoMock ,
296+ writable : true
297+ } ) ;
298+
299+ captureError ( fakeTelemetry , 'error' ) ;
300+
301+ expect ( emittedLogs . length ) . to . equal ( 1 ) ;
302+ const log = emittedLogs [ 0 ] ;
303+ expect ( log . attributes ! [ LOG_ENTRY_ATTRIBUTE_KEYS . SESSION_ID ] ) . to . equal ( 'new-session-id' ) ;
304+ // @ts -ignore
305+ expect ( sessionStorageMock [ TELEMETRY_SESSION_ID_KEY ] ) . to . equal (
306+ 'new-session-id'
307+ ) ;
308+ } ) ;
309+
310+ it ( 'should retrieve existing session ID from sessionStorage' , ( ) => {
311+ const sessionStorageMock = {
312+ getItem : ( ) => 'existing-session-id' ,
313+ setItem : ( ) => { }
314+ } ;
315+ const cryptoMock = {
316+ randomUUID : ( ) => 'new-session-id'
317+ } ;
318+
319+ Object . defineProperty ( global , 'sessionStorage' , {
320+ value : sessionStorageMock ,
321+ writable : true
322+ } ) ;
323+ Object . defineProperty ( global , 'crypto' , {
324+ value : cryptoMock ,
325+ writable : true
326+ } ) ;
327+
328+ captureError ( fakeTelemetry , 'error' ) ;
329+
330+ expect ( emittedLogs . length ) . to . equal ( 1 ) ;
331+ const log = emittedLogs [ 0 ] ;
332+ expect ( log . attributes ! [ LOG_ENTRY_ATTRIBUTE_KEYS . SESSION_ID ] ) . to . equal ( 'existing-session-id' ) ;
333+ } ) ;
334+
335+ it ( 'should handle errors when accessing sessionStorage' , ( ) => {
336+ const sessionStorageMock = {
337+ getItem : ( ) => {
338+ throw new Error ( 'SecurityError' ) ;
339+ } ,
340+ setItem : ( ) => { }
341+ } ;
342+
343+ Object . defineProperty ( global , 'sessionStorage' , {
344+ value : sessionStorageMock ,
345+ writable : true
346+ } ) ;
347+
348+ captureError ( fakeTelemetry , 'error' ) ;
349+
350+ expect ( emittedLogs . length ) . to . equal ( 1 ) ;
351+ const log = emittedLogs [ 0 ] ;
352+ expect ( log . attributes ! [ LOG_ENTRY_ATTRIBUTE_KEYS . SESSION_ID ] ) . to . be . undefined ;
248353 } ) ;
249354 } ) ;
250355 } ) ;
0 commit comments