Skip to content

Commit ff1a6ec

Browse files
author
renkelvin
authored
Add unit tests for handleRecaptchaFlow (#7699)
1 parent f10acb3 commit ff1a6ec

File tree

1 file changed

+141
-12
lines changed

1 file changed

+141
-12
lines changed

packages/auth/src/platform_browser/recaptcha/recaptcha_enterprise_verifier.test.ts

Lines changed: 141 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,27 @@ import chaiAsPromised from 'chai-as-promised';
2020
import * as sinon from 'sinon';
2121
import 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';
2429
import { mockEndpointWithParams } from '../../../test/helpers/api/helper';
2530
import { testAuth, TestAuth } from '../../../test/helpers/mock_auth';
2631
import * as mockFetch from '../../../test/helpers/mock_fetch';
2732
import { ServerError } from '../../api/errors';
33+
import { AuthInternal } from '../../model/auth';
2834

2935
import { MockGreCAPTCHATopLevel } from './recaptcha_mock';
3036
import {
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

3545
use(chaiAsPromised);
3646
use(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

Comments
 (0)