@@ -23,9 +23,14 @@ import * as sinon from 'sinon';
23
23
import sinonChai from 'sinon-chai' ;
24
24
import { Auth } from './auth' ;
25
25
import { CompatPopupRedirectResolver } from './popup_redirect' ;
26
+ import * as platform from './platform' ;
26
27
27
28
use ( sinonChai ) ;
28
29
30
+ function delay ( ms : number ) : Promise < void > {
31
+ return new Promise ( resolve => setTimeout ( resolve , ms ) ) ;
32
+ }
33
+
29
34
// For the most part, the auth methods just call straight through. Some parts
30
35
// of the auth compat layer are more complicated: these tests cover those
31
36
describe ( 'auth compat' , ( ) => {
@@ -45,7 +50,7 @@ describe('auth compat', () => {
45
50
} ) ;
46
51
47
52
afterEach ( ( ) => {
48
- sinon . restore ;
53
+ sinon . restore ( ) ;
49
54
} ) ;
50
55
51
56
it ( 'saves the persistence into session storage if available' , async ( ) => {
@@ -75,6 +80,40 @@ describe('auth compat', () => {
75
80
}
76
81
} ) ;
77
82
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
+
78
117
it ( 'pulls the persistence and sets as the main persitsence if set' , ( ) => {
79
118
if ( typeof self !== 'undefined' ) {
80
119
sessionStorage . setItem (
@@ -98,5 +137,35 @@ describe('auth compat', () => {
98
137
} ) ;
99
138
}
100
139
} ) ;
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
+ } ) ;
101
170
} ) ;
102
171
} ) ;
0 commit comments