UNPKG

voluptasmollitia

Version:
155 lines (133 loc) 5.03 kB
/** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import * as sinon from 'sinon'; import * as sinonChai from 'sinon-chai'; import { FirebaseError } from '@firebase/util'; import { testAuth, TestAuth } from '../../../test/helpers/mock_auth'; import { stubSingleTimeout } from '../../../test/helpers/timeout_stub'; import { _window } from '../auth_window'; import * as jsHelpers from '../load_js'; import { _JSLOAD_CALLBACK, MockReCaptchaLoaderImpl, ReCaptchaLoader, ReCaptchaLoaderImpl } from './recaptcha_loader'; import { MockReCaptcha } from './recaptcha_mock'; use(chaiAsPromised); use(sinonChai); describe('platform_browser/recaptcha/recaptcha_loader', () => { let auth: TestAuth; beforeEach(async () => { auth = await testAuth(); }); afterEach(() => { sinon.restore(); delete _window().grecaptcha; }); describe('MockLoader', () => { it('returns a MockRecaptcha instance', async () => { expect(await new MockReCaptchaLoaderImpl().load(auth)).to.be.instanceOf( MockReCaptcha ); }); }); describe('RealLoader', () => { let triggerNetworkTimeout: () => void; let jsLoader: { resolve: () => void; reject: () => void }; let loader: ReCaptchaLoader; const networkTimeoutId = 123; beforeEach(() => { triggerNetworkTimeout = stubSingleTimeout(networkTimeoutId); sinon.stub(jsHelpers, '_loadJS').callsFake(() => { return (new Promise<void>((resolve, reject) => { jsLoader = { resolve, reject }; }) as unknown) as Promise<Event>; }); loader = new ReCaptchaLoaderImpl(); }); context('network timeout / errors', () => { it('rejects if the network times out', async () => { const promise = loader.load(auth); triggerNetworkTimeout(); await expect(promise).to.be.rejectedWith( FirebaseError, 'Firebase: A network AuthError (such as timeout, interrupted connection or unreachable host) has occurred. (auth/network-request-failed).' ); }); it('rejects with an internal error if the loadJS call fails', async () => { const promise = loader.load(auth); jsLoader.reject(); await expect(promise).to.be.rejectedWith( FirebaseError, 'Firebase: An internal AuthError has occurred. (auth/internal-error).' ); }); }); context('on js load callback', () => { function spoofJsLoad(): void { _window()[_JSLOAD_CALLBACK](); } it('clears the network timeout', () => { sinon.spy(_window(), 'clearTimeout'); // eslint-disable-next-line @typescript-eslint/no-floating-promises loader.load(auth); spoofJsLoad(); expect(_window().clearTimeout).to.have.been.calledWith( networkTimeoutId ); }); it('rejects if the grecaptcha object is not on the window', async () => { const promise = loader.load(auth); spoofJsLoad(); await expect(promise).to.be.rejectedWith( FirebaseError, 'Firebase: An internal AuthError has occurred. (auth/internal-error).' ); }); it('overwrites the render method', async () => { const promise = loader.load(auth); const mockRecaptcha = new MockReCaptcha(auth); const oldRenderMethod = mockRecaptcha.render; _window().grecaptcha = mockRecaptcha; spoofJsLoad(); expect((await promise).render).not.to.eq(oldRenderMethod); }); it('returns immediately if the new language code matches the old', async () => { const promise = loader.load(auth); _window().grecaptcha = new MockReCaptcha(auth); spoofJsLoad(); await promise; // Notice no call to spoofJsLoad.. expect(await loader.load(auth)).to.eq(_window().grecaptcha); }); it('returns immediately if grecaptcha is already set on window', async () => { _window().grecaptcha = new MockReCaptcha(auth); const loader = new ReCaptchaLoaderImpl(); expect(await loader.load(auth)).to.eq(_window().grecaptcha); }); it('fails if the host language is invalid', async () => { expect(() => loader.load(auth, 'javascript:injection')).to.throw( FirebaseError, 'auth/argument-error' ); }); }); }); });