15
15
* limitations under the License.
16
16
*/
17
17
18
- import { FirebaseError } from '@firebase/util' ;
19
- import { expect } from 'chai' ;
18
+ import * as sinonChai from 'sinon-chai' ;
19
+ import * as sinon from 'sinon' ;
20
+ import { FirebaseError , querystring } from '@firebase/util' ;
21
+ import { expect , use } from 'chai' ;
20
22
import { testAuth , TestAuth } from '../../../test/helpers/mock_auth' ;
21
- import { AuthEventType } from '../../model/popup_redirect' ;
22
- import { _generateNewEvent } from './events' ;
23
+ import { AuthEvent , AuthEventType } from '../../model/popup_redirect' ;
24
+ import { _eventFromPartialAndUrl , _generateNewEvent , _getAndRemoveEvent , _getDeepLinkFromCallback , _savePartialEvent } from './events' ;
25
+ import { _createError } from '../../core/util/assert' ;
26
+ import { AuthErrorCode } from '../../core/errors' ;
27
+
28
+ use ( sinonChai ) ;
23
29
24
30
describe ( 'platform_cordova/popup_redirect/events' , ( ) => {
25
31
let auth : TestAuth ;
32
+ let storageStub : sinon . SinonStubbedInstance < typeof localStorage > ;
26
33
27
34
beforeEach ( async ( ) => {
28
35
auth = await testAuth ( ) ;
36
+ storageStub = sinon . stub ( localStorage ) ;
37
+ } ) ;
38
+
39
+ afterEach ( ( ) => {
40
+ sinon . restore ( ) ;
29
41
} ) ;
30
42
31
43
describe ( '_generateNewEvent' , ( ) => {
@@ -51,4 +63,98 @@ describe('platform_cordova/popup_redirect/events', () => {
51
63
. with . property ( 'code' , 'auth/no-auth-event' ) ;
52
64
} ) ;
53
65
} ) ;
66
+
67
+ describe ( '_savePartialEvent' , ( ) => {
68
+ it ( 'sets the event' , async ( ) => {
69
+ const event = _generateNewEvent ( auth , AuthEventType . REAUTH_VIA_REDIRECT ) ;
70
+ await _savePartialEvent ( auth , event ) ;
71
+ expect ( storageStub . setItem ) . to . have . been . calledWith ( 'firebase:authEvent:test-api-key:test-app' , JSON . stringify ( event ) ) ;
72
+ } ) ;
73
+ } ) ;
74
+
75
+ describe ( '_getAndRemoveEvent' , ( ) => {
76
+ it ( 'returns null if no event is present' , async ( ) => {
77
+ storageStub . getItem . returns ( null ) ;
78
+ expect ( await _getAndRemoveEvent ( auth ) ) . to . be . null ;
79
+ } ) ;
80
+
81
+ it ( 'returns the event and deletes the key if present' , async ( ) => {
82
+ const event = JSON . stringify ( _generateNewEvent ( auth , AuthEventType . REAUTH_VIA_REDIRECT ) ) ;
83
+ storageStub . getItem . returns ( event ) ;
84
+ expect ( await _getAndRemoveEvent ( auth ) ) . to . eql ( JSON . parse ( event ) ) ;
85
+ expect ( storageStub . removeItem ) . to . have . been . calledWith ( 'firebase:authEvent:test-api-key:test-app' ) ;
86
+ } ) ;
87
+ } ) ;
88
+
89
+ describe ( '_eventFromPartialAndUrl' , ( ) => {
90
+ let partialEvent : AuthEvent ;
91
+ beforeEach ( ( ) => {
92
+ partialEvent = _generateNewEvent ( auth , AuthEventType . REAUTH_VIA_REDIRECT , 'id' ) ;
93
+ } ) ;
94
+
95
+ function generateCallbackUrl ( params : Record < string , string > ) : string {
96
+ const deepLink = `http://foo/__/auth/callback?${ querystring ( params ) } ` ;
97
+ return `http://outer-app?link=${ encodeURIComponent ( deepLink ) } ` ;
98
+ }
99
+
100
+ it ( 'returns the proper event if everything is correct w/ no error' , ( ) => {
101
+ const url = generateCallbackUrl ( { } ) ;
102
+ expect ( _eventFromPartialAndUrl ( partialEvent , url ) ) . to . eql ( {
103
+ type : AuthEventType . REAUTH_VIA_REDIRECT ,
104
+ eventId : 'id' ,
105
+ tenantId : null ,
106
+ sessionId : partialEvent . sessionId ,
107
+ urlResponse : 'http://foo/__/auth/callback?' ,
108
+ postBody : null ,
109
+ } ) ;
110
+ } ) ;
111
+
112
+ it ( 'returns null if the callback url has no link' , ( ) => {
113
+ expect ( _eventFromPartialAndUrl ( partialEvent , 'http://foo' ) ) . to . be . null ;
114
+ } ) ;
115
+
116
+ it ( 'generates an error if the callback has an error' , ( ) => {
117
+ const handlerError = _createError ( AuthErrorCode . INTERNAL_ERROR ) ;
118
+ const url = generateCallbackUrl ( {
119
+ 'firebaseError' : JSON . stringify ( handlerError ) ,
120
+ } ) ;
121
+ const { error, ...rest } = _eventFromPartialAndUrl ( partialEvent , url ) ! ;
122
+
123
+ expect ( error ) . to . be . instanceOf ( FirebaseError ) . with . property ( 'code' , 'auth/internal-error' ) ;
124
+ expect ( rest ) . to . eql ( {
125
+ type : AuthEventType . REAUTH_VIA_REDIRECT ,
126
+ eventId : 'id' ,
127
+ tenantId : null ,
128
+ urlResponse : null ,
129
+ sessionId : null ,
130
+ postBody : null ,
131
+ } ) ;
132
+ } ) ;
133
+ } ) ;
134
+
135
+ describe ( '_getDeepLinkFromCallback' , ( ) => {
136
+ it ( 'returns the iOS double deep link preferentially' , ( ) => {
137
+ expect ( _getDeepLinkFromCallback ( 'https://foo?link=http%3A%2F%2Ffoo%3Flink%3DdoubleDeep' +
138
+ '&deep_link_id=http%3A%2F%2Ffoo%3Flink%3DdoubleDeepIos' ) ) . to . eq ( 'doubleDeepIos' ) ;
139
+ } ) ;
140
+
141
+ it ( 'returns the iOS deep link preferentially' , ( ) => {
142
+ expect ( _getDeepLinkFromCallback ( 'https://foo?link=http%3A%2F%2Ffoo%3Flink%3DdoubleDeep' +
143
+ '&deep_link_id=http%3A%2F%2FfooIOS' ) ) . to . eq ( 'http://fooIOS' ) ;
144
+ } ) ;
145
+
146
+ it ( 'returns double deep link preferentially' , ( ) => {
147
+ expect ( _getDeepLinkFromCallback ( 'https://foo?link=http%3A%2F%2Ffoo%3Flink%3DdoubleDeep' ) ) . to . eq ( 'doubleDeep' ) ;
148
+ } ) ;
149
+
150
+ it ( 'returns the deep link preferentially' , ( ) => {
151
+ expect ( _getDeepLinkFromCallback ( 'https://foo?link=http%3A%2F%2Ffoo%3Funrelated%3Dyeah' ) ) . to . eq (
152
+ 'http://foo?unrelated=yeah'
153
+ ) ;
154
+ } ) ;
155
+
156
+ it ( 'returns the passed-in url when all else fails' , ( ) => {
157
+ expect ( _getDeepLinkFromCallback ( 'https://foo?bar=baz' ) ) . to . eq ( 'https://foo?bar=baz' ) ;
158
+ } ) ;
159
+ } ) ;
54
160
} ) ;
0 commit comments