1
1
import { getRedirectUrl , initializeFedCM } from './GoogleOneTap.importable' ;
2
2
3
3
const mockWindow = ( {
4
- replace,
5
4
get,
6
5
enableFedCM = true ,
7
6
} : {
8
- replace : jest . Mock ;
9
7
get : jest . Mock ;
10
8
enableFedCM ?: boolean ;
11
- } ) =>
12
- Object . defineProperty ( globalThis , 'window' , {
13
- value : {
14
- location : {
15
- href : 'https://www.theguardian.com/uk' ,
16
- hostname : 'm.code.theguardian.com' ,
17
- replace,
18
- } ,
19
- navigator : { credentials : { get } } ,
20
- ...( enableFedCM ? { IdentityCredential : 'mock value' } : { } ) ,
9
+ } ) => {
10
+ const form = {
11
+ submit : jest . fn ( ) ,
12
+ appendChild : jest . fn ( ) ,
13
+ method : undefined ,
14
+ action : undefined ,
15
+ } ;
16
+ const input = {
17
+ submit : jest . fn ( ) ,
18
+ type : undefined ,
19
+ name : undefined ,
20
+ value : undefined ,
21
+ } ;
22
+
23
+ const window = {
24
+ location : {
25
+ href : 'https://www.theguardian.com/uk' ,
26
+ hostname : 'm.code.theguardian.com' ,
27
+ } ,
28
+ navigator : { credentials : { get } } ,
29
+ ...( enableFedCM ? { IdentityCredential : 'mock value' } : { } ) ,
30
+ } ;
31
+
32
+ const document = {
33
+ createElement : jest . fn ( ( element ) => {
34
+ if ( element === 'form' ) {
35
+ return form ;
36
+ } else if ( element === 'input' ) {
37
+ return input ;
38
+ } else {
39
+ throw new Error ( `Unsupported element: ${ element } ` ) ;
40
+ }
41
+ } ) ,
42
+ addEventListener : jest . fn ( ) ,
43
+ body : {
44
+ appendChild : jest . fn ( ) ,
21
45
} ,
46
+ } ;
47
+
48
+ Object . defineProperty ( globalThis , 'window' , {
49
+ value : window ,
50
+ writable : true ,
51
+ } ) ;
52
+ Object . defineProperty ( globalThis , 'document' , {
53
+ value : document ,
22
54
writable : true ,
23
55
} ) ;
24
56
57
+ return { form, input } ;
58
+ } ;
59
+
25
60
describe ( 'GoogleOneTap' , ( ) => {
26
61
it ( 'should return the correct signin URL after constructing it with the provided stage and token' , ( ) => {
27
62
expect (
28
63
getRedirectUrl ( {
29
64
stage : 'PROD' ,
30
- token : 'test-token' ,
31
65
currentLocation : 'https://www.theguardian.com/uk' ,
32
66
} ) ,
33
67
) . toEqual (
34
- 'https://profile.theguardian.com/signin/google?token=test-token& returnUrl=https%3A%2F%2Fwww.theguardian.com%2Fuk' ,
68
+ 'https://profile.theguardian.com/signin/google-one-tap? returnUrl=https%3A%2F%2Fwww.theguardian.com%2Fuk' ,
35
69
) ;
36
70
37
71
expect (
38
72
getRedirectUrl ( {
39
73
stage : 'CODE' ,
40
- token : 'test-token' ,
41
74
currentLocation : 'https://m.code.dev-theguardian.com/uk' ,
42
75
} ) ,
43
76
) . toEqual (
44
- 'https://profile.code.dev-theguardian.com/signin/google?token=test-token& returnUrl=https%3A%2F%2Fm.code.dev-theguardian.com%2Fuk' ,
77
+ 'https://profile.code.dev-theguardian.com/signin/google-one-tap? returnUrl=https%3A%2F%2Fm.code.dev-theguardian.com%2Fuk' ,
45
78
) ;
46
79
47
80
expect (
48
81
getRedirectUrl ( {
49
82
stage : 'DEV' ,
50
- token : 'test-token' ,
51
83
currentLocation :
52
84
'http://localhost/Front/https://m.code.dev-theguardian.com/uk' ,
53
85
} ) ,
54
86
) . toEqual (
55
- 'https://profile.thegulocal.com/signin/google?token=test-token& returnUrl=http%3A%2F%2Flocalhost%2FFront%2Fhttps%3A%2F%2Fm.code.dev-theguardian.com%2Fuk' ,
87
+ 'https://profile.thegulocal.com/signin/google-one-tap? returnUrl=http%3A%2F%2Flocalhost%2FFront%2Fhttps%3A%2F%2Fm.code.dev-theguardian.com%2Fuk' ,
56
88
) ;
57
89
} ) ;
58
90
59
91
it ( 'should initializeFedCM and redirect to Gateway with token on success' , async ( ) => {
60
92
const navigatorGet = jest . fn ( ( ) =>
61
93
Promise . resolve ( { token : 'test-token' } ) ,
62
94
) ;
63
- const locationReplace = jest . fn ( ) ;
64
95
65
- mockWindow ( {
96
+ const { form , input } = mockWindow ( {
66
97
get : navigatorGet ,
67
- replace : locationReplace ,
68
98
} ) ;
69
99
70
100
await initializeFedCM ( { isSignedIn : false } ) ;
71
101
72
- expect ( navigatorGet ) . toHaveBeenCalledWith ( {
73
- identity : {
74
- context : 'continue' ,
75
- providers : [
76
- {
77
- clientId : '774465807556.apps.googleusercontent.com' ,
78
- configURL : 'https://accounts.google.com/gsi/fedcm.json' ,
79
- } ,
80
- ] ,
81
- } ,
82
- mediation : 'required' ,
83
- } ) ;
84
-
85
- expect ( locationReplace ) . toHaveBeenCalledWith (
86
- 'https://profile.theguardian.com/signin/google?token=test-token&returnUrl=https%3A%2F%2Fwww.theguardian.com%2Fuk' ,
102
+ expect ( form . action ) . toBe (
103
+ 'https://profile.theguardian.com/signin/google-one-tap?returnUrl=https%3A%2F%2Fwww.theguardian.com%2Fuk' ,
87
104
) ;
105
+ expect ( form . method ) . toBe ( 'POST' ) ;
106
+
107
+ expect ( input . type ) . toBe ( 'hidden' ) ;
108
+ expect ( input . name ) . toBe ( 'token' ) ;
109
+ expect ( input . value ) . toBe ( 'test-token' ) ;
110
+
111
+ expect ( form . submit ) . toHaveBeenCalled ( ) ;
88
112
} ) ;
89
113
90
114
it ( 'should initializeFedCM and not redirect to Gateway with token on failure' , async ( ) => {
91
115
const error = new Error ( 'Network Error' ) ;
92
116
error . name = 'NetworkError' ;
93
117
94
118
const navigatorGet = jest . fn ( ( ) => Promise . reject ( error ) ) ;
95
- const locationReplace = jest . fn ( ) ;
96
119
97
- mockWindow ( {
120
+ const { form } = mockWindow ( {
98
121
get : navigatorGet ,
99
- replace : locationReplace ,
100
122
} ) ;
101
123
102
124
await initializeFedCM ( { isSignedIn : false } ) ;
@@ -115,19 +137,17 @@ describe('GoogleOneTap', () => {
115
137
} ) ;
116
138
117
139
// Don't redirect whenever there is a "NetworkError" (aka user declined prompt)
118
- expect ( locationReplace ) . not . toHaveBeenCalled ( ) ;
140
+ expect ( form . submit ) . not . toHaveBeenCalled ( ) ;
119
141
} ) ;
120
142
121
143
it ( 'should initializeFedCM and throw error when unexpected' , async ( ) => {
122
144
const error = new Error ( 'window.navigator.credentials.get failed' ) ;
123
145
error . name = 'DOMException' ;
124
146
125
147
const navigatorGet = jest . fn ( ( ) => Promise . reject ( error ) ) ;
126
- const locationReplace = jest . fn ( ) ;
127
148
128
- mockWindow ( {
149
+ const { form } = mockWindow ( {
129
150
get : navigatorGet ,
130
- replace : locationReplace ,
131
151
} ) ;
132
152
133
153
await expect ( initializeFedCM ( { isSignedIn : false } ) ) . rejects . toThrow (
@@ -148,52 +168,46 @@ describe('GoogleOneTap', () => {
148
168
} ) ;
149
169
150
170
// Don't redirect whenever there is an unexpected error
151
- expect ( locationReplace ) . not . toHaveBeenCalled ( ) ;
171
+ expect ( form . submit ) . not . toHaveBeenCalled ( ) ;
152
172
} ) ;
153
173
154
174
it ( 'should not initializeFedCM when FedCM is unsupported' , async ( ) => {
155
175
const navigatorGet = jest . fn ( ) ;
156
- const locationReplace = jest . fn ( ) ;
157
176
158
- mockWindow ( {
177
+ const { form } = mockWindow ( {
159
178
get : navigatorGet ,
160
- replace : locationReplace ,
161
179
enableFedCM : false ,
162
180
} ) ;
163
181
164
182
await initializeFedCM ( { isSignedIn : false } ) ;
165
183
166
184
expect ( navigatorGet ) . not . toHaveBeenCalled ( ) ;
167
- expect ( locationReplace ) . not . toHaveBeenCalled ( ) ;
185
+ expect ( form . submit ) . not . toHaveBeenCalled ( ) ;
168
186
} ) ;
169
187
170
188
it ( 'should not initializeFedCM when user is signed in' , async ( ) => {
171
189
const navigatorGet = jest . fn ( ) ;
172
- const locationReplace = jest . fn ( ) ;
173
190
174
- mockWindow ( {
191
+ const { form } = mockWindow ( {
175
192
get : navigatorGet ,
176
- replace : locationReplace ,
177
193
} ) ;
178
194
179
195
await initializeFedCM ( { isSignedIn : true } ) ;
180
196
181
197
expect ( navigatorGet ) . not . toHaveBeenCalled ( ) ;
182
- expect ( locationReplace ) . not . toHaveBeenCalled ( ) ;
198
+ expect ( form . submit ) . not . toHaveBeenCalled ( ) ;
183
199
} ) ;
184
200
185
201
it ( 'should not initializeFedCM when user is not in test' , async ( ) => {
186
202
const navigatorGet = jest . fn ( ) ;
187
- const locationReplace = jest . fn ( ) ;
188
203
189
- mockWindow ( {
204
+ const { form } = mockWindow ( {
190
205
get : navigatorGet ,
191
- replace : locationReplace ,
192
206
} ) ;
193
207
194
208
await initializeFedCM ( { isSignedIn : true } ) ;
195
209
196
210
expect ( navigatorGet ) . not . toHaveBeenCalled ( ) ;
197
- expect ( locationReplace ) . not . toHaveBeenCalled ( ) ;
211
+ expect ( form . submit ) . not . toHaveBeenCalled ( ) ;
198
212
} ) ;
199
213
} ) ;
0 commit comments