@@ -23,9 +23,14 @@ import * as sinon from 'sinon';
2323import sinonChai from 'sinon-chai' ;
2424import { Auth } from './auth' ;
2525import { CompatPopupRedirectResolver } from './popup_redirect' ;
26+ import * as platform from './platform' ;
2627
2728use ( sinonChai ) ;
2829
30+ function delay ( ms : number ) : Promise < void > {
31+ return new Promise ( resolve => setTimeout ( resolve , ms ) ) ;
32+ }
33+
2934// For the most part, the auth methods just call straight through. Some parts
3035// of the auth compat layer are more complicated: these tests cover those
3136describe ( 'auth compat' , ( ) => {
@@ -45,7 +50,7 @@ describe('auth compat', () => {
4550 } ) ;
4651
4752 afterEach ( ( ) => {
48- sinon . restore ;
53+ sinon . restore ( ) ;
4954 } ) ;
5055
5156 it ( 'saves the persistence into session storage if available' , async ( ) => {
@@ -75,6 +80,40 @@ describe('auth compat', () => {
7580 }
7681 } ) ;
7782
83+ it ( 'does not save persistence if property throws DOMException' , async ( ) => {
84+ if ( typeof self !== 'undefined' ) {
85+ sinon . stub ( platform , '_getSelfWindow' ) . returns ( {
86+ get sessionStorage ( ) : Storage {
87+ throw new DOMException ( 'Nope!' ) ;
88+ }
89+ } as unknown as Window ) ;
90+ const setItemSpy = sinon . spy ( sessionStorage , 'setItem' ) ;
91+ sinon . stub ( underlyingAuth , '_getPersistence' ) . returns ( 'TEST' ) ;
92+ sinon
93+ . stub ( underlyingAuth , '_initializationPromise' )
94+ . value ( Promise . resolve ( ) ) ;
95+ sinon . stub (
96+ exp . _getInstance < exp . PopupRedirectResolverInternal > (
97+ CompatPopupRedirectResolver
98+ ) ,
99+ '_openRedirect'
100+ ) ;
101+ providerStub . isInitialized . returns ( true ) ;
102+ providerStub . getImmediate . returns ( underlyingAuth ) ;
103+ const authCompat = new Auth (
104+ app ,
105+ providerStub as unknown as Provider < 'auth' >
106+ ) ;
107+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
108+ await authCompat . signInWithRedirect ( new exp . GoogleAuthProvider ( ) ) ;
109+ await delay ( 50 ) ;
110+ expect ( setItemSpy ) . not . to . have . been . calledWith (
111+ 'firebase:persistence:api-key:undefined' ,
112+ 'TEST'
113+ ) ;
114+ }
115+ } ) ;
116+
78117 it ( 'pulls the persistence and sets as the main persitsence if set' , ( ) => {
79118 if ( typeof self !== 'undefined' ) {
80119 sessionStorage . setItem (
@@ -98,5 +137,35 @@ describe('auth compat', () => {
98137 } ) ;
99138 }
100139 } ) ;
140+
141+ it ( 'does not die if sessionStorage errors' , async ( ) => {
142+ if ( typeof self !== 'undefined' ) {
143+ sinon . stub ( platform , '_getSelfWindow' ) . returns ( {
144+ get sessionStorage ( ) : Storage {
145+ throw new DOMException ( 'Nope!' ) ;
146+ }
147+ } as unknown as Window ) ;
148+ sessionStorage . setItem (
149+ 'firebase:persistence:api-key:undefined' ,
150+ 'none'
151+ ) ;
152+ providerStub . isInitialized . returns ( false ) ;
153+ providerStub . initialize . returns ( underlyingAuth ) ;
154+ new Auth ( app , providerStub as unknown as Provider < 'auth' > ) ;
155+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
156+ await delay ( 50 ) ;
157+ expect ( providerStub . initialize ) . to . have . been . calledWith ( {
158+ options : {
159+ popupRedirectResolver : CompatPopupRedirectResolver ,
160+ persistence : [
161+ exp . indexedDBLocalPersistence ,
162+ exp . browserLocalPersistence ,
163+ exp . browserSessionPersistence ,
164+ exp . inMemoryPersistence
165+ ]
166+ }
167+ } ) ;
168+ }
169+ } ) ;
101170 } ) ;
102171} ) ;
0 commit comments