@@ -20,17 +20,27 @@ import chaiAsPromised from 'chai-as-promised';
2020import * as sinon from 'sinon' ;
2121import sinonChai from 'sinon-chai' ;
2222
23- import { Endpoint , RecaptchaClientType , RecaptchaVersion } from '../../api' ;
23+ import {
24+ Endpoint ,
25+ RecaptchaClientType ,
26+ RecaptchaVersion ,
27+ RecaptchaActionName
28+ } from '../../api' ;
2429import { mockEndpointWithParams } from '../../../test/helpers/api/helper' ;
2530import { testAuth , TestAuth } from '../../../test/helpers/mock_auth' ;
2631import * as mockFetch from '../../../test/helpers/mock_fetch' ;
2732import { ServerError } from '../../api/errors' ;
33+ import { AuthInternal } from '../../model/auth' ;
2834
2935import { MockGreCAPTCHATopLevel } from './recaptcha_mock' ;
3036import {
3137 RecaptchaEnterpriseVerifier ,
32- FAKE_TOKEN
38+ FAKE_TOKEN ,
39+ handleRecaptchaFlow
3340} from './recaptcha_enterprise_verifier' ;
41+ import { RecaptchaConfig } from './recaptcha' ;
42+ import { AuthErrorCode } from '../../core/errors' ;
43+ import { _createError } from '../../core/util/assert' ;
3444
3545use ( chaiAsPromised ) ;
3646use ( sinonChai ) ;
@@ -39,6 +49,29 @@ describe('platform_browser/recaptcha/recaptcha_enterprise_verifier', () => {
3949 let auth : TestAuth ;
4050 let verifier : RecaptchaEnterpriseVerifier ;
4151
52+ const recaptchaConfigResponseEnforce = {
53+ recaptchaKey : 'foo/bar/to/site-key' ,
54+ recaptchaEnforcementState : [
55+ {
56+ provider : 'EMAIL_PASSWORD_PROVIDER' ,
57+ enforcementState : 'ENFORCE'
58+ }
59+ ]
60+ } ;
61+ const recaptchaConfigEnforce = new RecaptchaConfig (
62+ recaptchaConfigResponseEnforce
63+ ) ;
64+ const recaptchaConfigResponseOff = {
65+ recaptchaKey : 'foo/bar/to/site-key' ,
66+ recaptchaEnforcementState : [
67+ {
68+ provider : 'EMAIL_PASSWORD_PROVIDER' ,
69+ enforcementState : 'OFF'
70+ }
71+ ]
72+ } ;
73+ const recaptchaConfigOff = new RecaptchaConfig ( recaptchaConfigResponseOff ) ;
74+
4275 beforeEach ( async ( ) => {
4376 auth = await testAuth ( ) ;
4477 mockFetch . setUp ( ) ;
@@ -51,16 +84,6 @@ describe('platform_browser/recaptcha/recaptcha_enterprise_verifier', () => {
5184 } ) ;
5285
5386 context ( '#verify' , ( ) => {
54- const recaptchaConfigResponseEnforce = {
55- recaptchaKey : 'foo/bar/to/site-key' ,
56- recaptchaEnforcementState : [
57- {
58- provider : 'EMAIL_PASSWORD_PROVIDER' ,
59- enforcementState : 'ENFORCE'
60- }
61- ]
62- } ;
63-
6487 const request = {
6588 clientType : RecaptchaClientType . WEB ,
6689 version : RecaptchaVersion . ENTERPRISE
@@ -117,4 +140,110 @@ describe('platform_browser/recaptcha/recaptcha_enterprise_verifier', () => {
117140 expect ( await verifier . verify ( ) ) . to . eq ( FAKE_TOKEN ) ;
118141 } ) ;
119142 } ) ;
143+
144+ context ( 'handleRecaptchaFlow' , ( ) => {
145+ let mockAuthInstance : AuthInternal ;
146+ let mockRequest : any ;
147+ let mockActionMethod : sinon . SinonStub ;
148+
149+ beforeEach ( async ( ) => {
150+ mockAuthInstance = await testAuth ( ) ;
151+ mockRequest = { } ;
152+ mockActionMethod = sinon . stub ( ) ;
153+ } ) ;
154+
155+ afterEach ( ( ) => {
156+ sinon . restore ( ) ;
157+ } ) ;
158+
159+ it ( 'should call actionMethod with request if emailPasswordEnabled is true' , async ( ) => {
160+ if ( typeof window === 'undefined' ) {
161+ return ;
162+ }
163+ sinon
164+ . stub ( mockAuthInstance , '_getRecaptchaConfig' )
165+ . returns ( recaptchaConfigEnforce ) ;
166+ sinon
167+ . stub ( RecaptchaEnterpriseVerifier . prototype , 'verify' )
168+ . resolves ( 'recaptcha-response' ) ;
169+ mockRequest = { foo : 'bar' } ;
170+ mockActionMethod = sinon . stub ( ) . resolves ( 'testResponse' ) ;
171+ const response = await handleRecaptchaFlow (
172+ mockAuthInstance ,
173+ mockRequest ,
174+ RecaptchaActionName . SIGN_IN_WITH_PASSWORD ,
175+ mockActionMethod
176+ ) ;
177+ expect ( mockActionMethod ) . to . have . been . calledOnce ;
178+ expect ( response ) . to . equal ( 'testResponse' ) ;
179+ } ) ;
180+
181+ // "Errors like "MISSING_RECAPTCHA_TOKEN" will be handled irrespective of the enablement status of "emailPasswordEnabled", but this test verifies the more likely scenario where emailPasswordEnabled is false"
182+ it ( 'should handle MISSING_RECAPTCHA_TOKEN error when emailPasswordEnabled is false' , async ( ) => {
183+ if ( typeof window === 'undefined' ) {
184+ return ;
185+ }
186+ sinon
187+ . stub ( mockAuthInstance , '_getRecaptchaConfig' )
188+ . returns ( recaptchaConfigOff ) ;
189+ sinon
190+ . stub ( RecaptchaEnterpriseVerifier . prototype , 'verify' )
191+ . resolves ( 'recaptcha-response' ) ;
192+ mockRequest = { foo : 'bar' } ;
193+ let callCount = 0 ;
194+ mockActionMethod = sinon . stub ( ) . callsFake ( ( ) => {
195+ callCount ++ ;
196+ if ( callCount === 1 ) {
197+ return Promise . reject (
198+ _createError ( AuthErrorCode . MISSING_RECAPTCHA_TOKEN )
199+ ) ;
200+ } else {
201+ return Promise . resolve ( 'testResponse' ) ;
202+ }
203+ } ) ;
204+ const response = await handleRecaptchaFlow (
205+ mockAuthInstance ,
206+ mockRequest ,
207+ RecaptchaActionName . SIGN_IN_WITH_PASSWORD ,
208+ mockActionMethod
209+ ) ;
210+ expect ( mockActionMethod ) . to . have . been . calledTwice ;
211+ expect ( response ) . to . equal ( 'testResponse' ) ;
212+ } ) ;
213+
214+ it ( 'should handle non MISSING_RECAPTCHA_TOKEN error when emailPasswordEnabled is false' , async ( ) => {
215+ if ( typeof window === 'undefined' ) {
216+ return ;
217+ }
218+ sinon
219+ . stub ( mockAuthInstance , '_getRecaptchaConfig' )
220+ . returns ( recaptchaConfigOff ) ;
221+ sinon
222+ . stub ( RecaptchaEnterpriseVerifier . prototype , 'verify' )
223+ . resolves ( 'recaptcha-response' ) ;
224+ mockRequest = { foo : 'bar' } ;
225+ let callCount = 0 ;
226+ mockActionMethod = sinon . stub ( ) . callsFake ( ( ) => {
227+ callCount ++ ;
228+ if ( callCount === 1 ) {
229+ return Promise . reject (
230+ _createError ( AuthErrorCode . RECAPTCHA_NOT_ENABLED )
231+ ) ;
232+ } else {
233+ return Promise . resolve ( 'testResponse' ) ;
234+ }
235+ } ) ;
236+
237+ const response = handleRecaptchaFlow (
238+ mockAuthInstance ,
239+ mockRequest ,
240+ RecaptchaActionName . SIGN_IN_WITH_PASSWORD ,
241+ mockActionMethod
242+ ) ;
243+ await expect ( response ) . to . be . rejectedWith (
244+ AuthErrorCode . RECAPTCHA_NOT_ENABLED
245+ ) ;
246+ expect ( mockActionMethod ) . to . have . been . calledOnce ;
247+ } ) ;
248+ } ) ;
120249} ) ;
0 commit comments