1
+ /**
2
+ * @license
3
+ * Copyright 2020 Google LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import { expect , use } from 'chai' ;
19
+ import * as sinon from 'sinon' ;
20
+ import * as sinonChai from 'sinon-chai' ;
21
+
22
+ import { FirebaseApp } from '@firebase/app-types' ;
23
+ import { FirebaseError } from '@firebase/util' ;
24
+
25
+ import { testUser } from '../../../test/mock_auth' ;
26
+ import { Auth } from '../../model/auth' ;
27
+ import { Persistence } from '../persistence' ;
28
+ import { browserLocalPersistence } from '../persistence/browser' ;
29
+ import { inMemoryPersistence } from '../persistence/in_memory' ;
30
+ import { PersistenceUserManager } from '../persistence/persistence_user_manager' ;
31
+ import { ClientPlatform , getClientVersion } from '../util/version' ;
32
+ import { DEFAULT_API_HOST , DEFAULT_API_SCHEME , initializeAuth } from './auth_impl' ;
33
+
34
+ use ( sinonChai ) ;
35
+
36
+ const FAKE_APP : FirebaseApp = {
37
+ name : 'test-app' ,
38
+ options : {
39
+ apiKey : 'api-key' ,
40
+ authDomain : 'auth-domain' ,
41
+ } ,
42
+ automaticDataCollectionEnabled : false ,
43
+ async delete ( ) { } ,
44
+ } ;
45
+
46
+ describe ( 'AuthImpl' , ( ) => {
47
+ let auth : Auth ;
48
+ let persistenceStub : sinon . SinonStubbedInstance < Persistence > ;
49
+
50
+ beforeEach ( ( ) => {
51
+ persistenceStub = sinon . stub ( inMemoryPersistence ) ;
52
+ auth = initializeAuth ( FAKE_APP , { persistence : inMemoryPersistence } ) ;
53
+ } ) ;
54
+
55
+ afterEach ( sinon . restore ) ;
56
+
57
+ describe ( '#updateCurrentUser' , ( ) => {
58
+ it ( 'sets the field on the auth object' , async ( ) => {
59
+ const user = testUser ( 'uid' ) ;
60
+ await auth . updateCurrentUser ( user ) ;
61
+ expect ( auth . currentUser ) . to . eql ( user ) ;
62
+ } ) ;
63
+
64
+ it ( 'orders async operations correctly' , async ( ) => {
65
+ const users = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] . map ( n => {
66
+ return testUser ( `${ n } ` ) ;
67
+ } ) ;
68
+
69
+ persistenceStub . set . callsFake ( ( ) => {
70
+ return new Promise ( resolve => {
71
+ // Force into the async flow to make this test actually meaningful
72
+ setTimeout ( ( ) => resolve ( ) , 1 ) ;
73
+ } ) ;
74
+ } ) ;
75
+
76
+ await Promise . all ( users . map ( u => auth . updateCurrentUser ( u ) ) ) ;
77
+ for ( let i = 0 ; i < 10 ; i ++ ) {
78
+ expect ( persistenceStub . set . getCall ( i ) ) . to . have . been . calledWith (
79
+ sinon . match . any ,
80
+ users [ i ] . toPlainObject ( ) ,
81
+ ) ;
82
+ }
83
+ } ) ;
84
+
85
+ it ( 'setting to null triggers a remove call' , async ( ) => {
86
+ await auth . updateCurrentUser ( null ) ;
87
+ expect ( persistenceStub . remove ) . to . have . been . called ;
88
+ } ) ;
89
+ } ) ;
90
+
91
+ describe ( '#signOut' , ( ) => {
92
+ it ( 'sets currentUser to null, calls remove' , async ( ) => {
93
+ await auth . updateCurrentUser ( testUser ( 'test' ) ) ;
94
+ await auth . signOut ( ) ;
95
+ expect ( persistenceStub . remove ) . to . have . been . called ;
96
+ expect ( auth . currentUser ) . to . be . null ;
97
+ } ) ;
98
+ } ) ;
99
+
100
+ describe ( '#setPersistence' , ( ) => {
101
+ it ( 'swaps underlying persistence' , async ( ) => {
102
+ const newPersistence = browserLocalPersistence ;
103
+ const newStub = sinon . stub ( newPersistence ) ;
104
+ persistenceStub . get . returns ( Promise . resolve ( testUser ( 'test' ) . toPlainObject ( ) ) ) ;
105
+
106
+ await auth . setPersistence ( newPersistence ) ;
107
+ expect ( persistenceStub . get ) . to . have . been . called ;
108
+ expect ( persistenceStub . remove ) . to . have . been . called ;
109
+ expect ( newStub . set ) . to . have . been . calledWith (
110
+ sinon . match . any ,
111
+ testUser ( 'test' ) . toPlainObject ( ) ,
112
+ ) ;
113
+ } ) ;
114
+ } ) ;
115
+ } ) ;
116
+
117
+ describe ( 'initializeAuth' , ( ) => {
118
+ afterEach ( sinon . restore ) ;
119
+
120
+ it ( 'throws an API error if key not provided' , ( ) => {
121
+ expect ( ( ) => initializeAuth ( {
122
+ ...FAKE_APP ,
123
+ options : { } , // apiKey is missing
124
+ } ) ) . to . throw ( FirebaseError , 'Firebase: Your API key is invalid]: please check you have copied it correctly. (auth/invalid-api-key).' ) ;
125
+ } ) ;
126
+
127
+ describe ( 'persistence manager creation' , ( ) => {
128
+ let createManagerStub : sinon . SinonSpy ;
129
+ beforeEach ( ( ) => {
130
+ createManagerStub = sinon . spy ( PersistenceUserManager , 'create' ) ;
131
+ } ) ;
132
+
133
+ async function initAndWait ( persistence : Persistence | Persistence [ ] ) : Promise < Auth > {
134
+ const auth = initializeAuth ( FAKE_APP , { persistence} ) ;
135
+ // Auth initializes async. We can make sure the initialization is
136
+ // flushed by awaiting a method on the queue.
137
+ await auth . setPersistence ( inMemoryPersistence ) ;
138
+ return auth ;
139
+ }
140
+
141
+ it ( 'converts single persistence to array' , async ( ) => {
142
+ const auth = await initAndWait ( inMemoryPersistence ) ;
143
+ expect ( createManagerStub ) . to . have . been . calledWith ( auth , [ inMemoryPersistence ] ) ;
144
+ } ) ;
145
+
146
+ it ( 'pulls the user from storage' , async ( ) => {
147
+ sinon . stub ( inMemoryPersistence , 'get' ) . returns (
148
+ Promise . resolve ( testUser ( 'uid' ) . toPlainObject ( ) )
149
+ ) ;
150
+ const auth = await initAndWait ( inMemoryPersistence ) ;
151
+ expect ( auth . currentUser ! . uid ) . to . eq ( 'uid' ) ;
152
+ } ) ;
153
+
154
+ it ( 'calls create with the persistence in order' , async ( ) => {
155
+ const auth = await initAndWait ( [ inMemoryPersistence , browserLocalPersistence ] ) ;
156
+ expect ( createManagerStub ) . to . have . been . calledWith ( auth , [ inMemoryPersistence , browserLocalPersistence ] ) ;
157
+ } ) ;
158
+
159
+ it ( 'sets auth name and config' , async ( ) => {
160
+ const auth = await initAndWait ( inMemoryPersistence ) ;
161
+ expect ( auth . name ) . to . eq ( FAKE_APP . name ) ;
162
+ expect ( auth . config ) . to . eql ( {
163
+ apiKey : FAKE_APP . options . apiKey ,
164
+ authDomain : FAKE_APP . options . authDomain ,
165
+ apiHost : DEFAULT_API_HOST ,
166
+ apiScheme : DEFAULT_API_SCHEME ,
167
+ sdkClientVersion : getClientVersion ( ClientPlatform . BROWSER ) ,
168
+ } ) ;
169
+ } ) ;
170
+ } ) ;
171
+ } ) ;
0 commit comments