UNPKG

voluptasmollitia

Version:
449 lines (402 loc) 12.2 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 sinonChai from 'sinon-chai'; import { ActionCodeOperation, OperationType } from '../../model/public_types'; import { FirebaseError } from '@firebase/util'; import { mockEndpoint } from '../../../test/helpers/api/helper'; import { testAuth, TestAuth } from '../../../test/helpers/mock_auth'; import * as mockFetch from '../../../test/helpers/mock_fetch'; import { Endpoint } from '../../api'; import { APIUserInfo } from '../../api/account_management/account'; import { ServerError } from '../../api/errors'; import { UserCredentialInternal } from '../../model/user'; import { applyActionCode, checkActionCode, confirmPasswordReset, createUserWithEmailAndPassword, sendPasswordResetEmail, signInWithEmailAndPassword, verifyPasswordResetCode } from './email_and_password'; use(chaiAsPromised); use(sinonChai); describe('core/strategies/sendPasswordResetEmail', () => { const email = 'foo@bar.com'; let auth: TestAuth; beforeEach(async () => { auth = await testAuth(); mockFetch.setUp(); }); afterEach(mockFetch.tearDown); it('should send a password reset email', async () => { const mock = mockEndpoint(Endpoint.SEND_OOB_CODE, { email }); await sendPasswordResetEmail(auth, email); expect(mock.calls[0].request).to.eql({ requestType: ActionCodeOperation.PASSWORD_RESET, email }); }); it('should surface errors', async () => { const mock = mockEndpoint( Endpoint.SEND_OOB_CODE, { error: { code: 400, message: ServerError.INVALID_EMAIL } }, 400 ); await expect(sendPasswordResetEmail(auth, email)).to.be.rejectedWith( FirebaseError, 'Firebase: The email address is badly formatted. (auth/invalid-email).' ); expect(mock.calls.length).to.eq(1); }); context('on iOS', () => { it('should pass action code parameters', async () => { const mock = mockEndpoint(Endpoint.SEND_OOB_CODE, { email }); await sendPasswordResetEmail(auth, email, { handleCodeInApp: true, iOS: { bundleId: 'my-bundle' }, url: 'my-url', dynamicLinkDomain: 'fdl-domain' }); expect(mock.calls[0].request).to.eql({ requestType: ActionCodeOperation.PASSWORD_RESET, email, continueUrl: 'my-url', dynamicLinkDomain: 'fdl-domain', canHandleCodeInApp: true, iosBundleId: 'my-bundle' }); }); }); context('on Android', () => { it('should pass action code parameters', async () => { const mock = mockEndpoint(Endpoint.SEND_OOB_CODE, { email }); await sendPasswordResetEmail(auth, email, { handleCodeInApp: true, android: { installApp: false, minimumVersion: 'my-version', packageName: 'my-package' }, url: 'my-url', dynamicLinkDomain: 'fdl-domain' }); expect(mock.calls[0].request).to.eql({ requestType: ActionCodeOperation.PASSWORD_RESET, email, continueUrl: 'my-url', dynamicLinkDomain: 'fdl-domain', canHandleCodeInApp: true, androidInstallApp: false, androidMinimumVersionCode: 'my-version', androidPackageName: 'my-package' }); }); }); }); describe('core/strategies/confirmPasswordReset', () => { const oobCode = 'oob-code'; const newPassword = 'new-password'; let auth: TestAuth; beforeEach(async () => { auth = await testAuth(); mockFetch.setUp(); }); afterEach(mockFetch.tearDown); it('should confirm the password reset and not return the email', async () => { const mock = mockEndpoint(Endpoint.RESET_PASSWORD, { email: 'foo@bar.com' }); const response = await confirmPasswordReset(auth, oobCode, newPassword); expect(response).to.be.undefined; expect(mock.calls[0].request).to.eql({ oobCode, newPassword }); }); it('should surface errors', async () => { const mock = mockEndpoint( Endpoint.RESET_PASSWORD, { error: { code: 400, message: ServerError.INVALID_OOB_CODE } }, 400 ); await expect( confirmPasswordReset(auth, oobCode, newPassword) ).to.be.rejectedWith( FirebaseError, 'Firebase: The action code is invalid. This can happen if the code is malformed, expired, or has already been used. (auth/invalid-action-code).' ); expect(mock.calls.length).to.eq(1); }); }); describe('core/strategies/applyActionCode', () => { const oobCode = 'oob-code'; let auth: TestAuth; beforeEach(async () => { auth = await testAuth(); mockFetch.setUp(); }); afterEach(mockFetch.tearDown); it('should apply the oob code', async () => { const mock = mockEndpoint(Endpoint.SET_ACCOUNT_INFO, {}); await applyActionCode(auth, oobCode); expect(mock.calls[0].request).to.eql({ oobCode }); }); it('should surface errors', async () => { const mock = mockEndpoint( Endpoint.SET_ACCOUNT_INFO, { error: { code: 400, message: ServerError.INVALID_OOB_CODE } }, 400 ); await expect(applyActionCode(auth, oobCode)).to.be.rejectedWith( FirebaseError, 'Firebase: The action code is invalid. This can happen if the code is malformed, expired, or has already been used. (auth/invalid-action-code).' ); expect(mock.calls.length).to.eq(1); }); }); describe('core/strategies/checkActionCode', () => { const oobCode = 'oob-code'; const email = 'foo@bar.com'; const newEmail = 'new@email.com'; let auth: TestAuth; beforeEach(async () => { auth = await testAuth(); mockFetch.setUp(); }); afterEach(mockFetch.tearDown); it('should verify the oob code', async () => { const mock = mockEndpoint(Endpoint.RESET_PASSWORD, { requestType: ActionCodeOperation.PASSWORD_RESET, email: 'foo@bar.com' }); const response = await checkActionCode(auth, oobCode); expect(response).to.eql({ data: { email, previousEmail: null, multiFactorInfo: null }, operation: ActionCodeOperation.PASSWORD_RESET }); expect(mock.calls[0].request).to.eql({ oobCode }); }); it('should return the newEmail', async () => { const mock = mockEndpoint(Endpoint.RESET_PASSWORD, { requestType: ActionCodeOperation.PASSWORD_RESET, email, newEmail }); const response = await checkActionCode(auth, oobCode); expect(response).to.eql({ data: { email, previousEmail: newEmail, multiFactorInfo: null }, operation: ActionCodeOperation.PASSWORD_RESET }); expect(mock.calls[0].request).to.eql({ oobCode }); }); it('should expect a requestType', async () => { const mock = mockEndpoint(Endpoint.RESET_PASSWORD, { email }); await expect(checkActionCode(auth, oobCode)).to.be.rejectedWith( FirebaseError, 'Firebase: An internal AuthError has occurred. (auth/internal-error).' ); expect(mock.calls.length).to.eq(1); }); it('should surface errors', async () => { const mock = mockEndpoint( Endpoint.RESET_PASSWORD, { error: { code: 400, message: ServerError.INVALID_OOB_CODE } }, 400 ); await expect(checkActionCode(auth, oobCode)).to.be.rejectedWith( FirebaseError, 'Firebase: The action code is invalid. This can happen if the code is malformed, expired, or has already been used. (auth/invalid-action-code).' ); expect(mock.calls.length).to.eq(1); }); }); describe('core/strategies/verifyPasswordResetCode', () => { const oobCode = 'oob-code'; const email = 'foo@bar.com'; let auth: TestAuth; beforeEach(async () => { auth = await testAuth(); mockFetch.setUp(); }); afterEach(mockFetch.tearDown); it('should verify the oob code', async () => { const mock = mockEndpoint(Endpoint.RESET_PASSWORD, { requestType: ActionCodeOperation.PASSWORD_RESET, email: 'foo@bar.com', previousEmail: null }); const response = await verifyPasswordResetCode(auth, oobCode); expect(response).to.eq(email); expect(mock.calls[0].request).to.eql({ oobCode }); }); it('should expect a requestType', async () => { const mock = mockEndpoint(Endpoint.RESET_PASSWORD, { email }); await expect(verifyPasswordResetCode(auth, oobCode)).to.be.rejectedWith( FirebaseError, 'Firebase: An internal AuthError has occurred. (auth/internal-error).' ); expect(mock.calls.length).to.eq(1); }); it('should surface errors', async () => { const mock = mockEndpoint( Endpoint.RESET_PASSWORD, { error: { code: 400, message: ServerError.INVALID_OOB_CODE } }, 400 ); await expect(verifyPasswordResetCode(auth, oobCode)).to.be.rejectedWith( FirebaseError, 'Firebase: The action code is invalid. This can happen if the code is malformed, expired, or has already been used. (auth/invalid-action-code).' ); expect(mock.calls.length).to.eq(1); }); }); describe('core/strategies/email_and_password/createUserWithEmailAndPassword', () => { let auth: TestAuth; const serverUser: APIUserInfo = { localId: 'local-id' }; beforeEach(async () => { auth = await testAuth(); mockFetch.setUp(); mockEndpoint(Endpoint.SIGN_UP, { idToken: 'id-token', refreshToken: 'refresh-token', expiresIn: '1234', localId: serverUser.localId! }); mockEndpoint(Endpoint.GET_ACCOUNT_INFO, { users: [serverUser] }); }); afterEach(mockFetch.tearDown); it('should sign in the user', async () => { const { _tokenResponse, user, operationType } = (await createUserWithEmailAndPassword( auth, 'some-email', 'some-password' )) as UserCredentialInternal; expect(_tokenResponse).to.eql({ idToken: 'id-token', refreshToken: 'refresh-token', expiresIn: '1234', localId: serverUser.localId! }); expect(operationType).to.eq(OperationType.SIGN_IN); expect(user.uid).to.eq(serverUser.localId); expect(user.isAnonymous).to.be.false; }); }); describe('core/strategies/email_and_password/signInWithEmailAndPassword', () => { let auth: TestAuth; const serverUser: APIUserInfo = { localId: 'local-id' }; beforeEach(async () => { auth = await testAuth(); mockFetch.setUp(); mockEndpoint(Endpoint.SIGN_IN_WITH_PASSWORD, { idToken: 'id-token', refreshToken: 'refresh-token', expiresIn: '1234', localId: serverUser.localId! }); mockEndpoint(Endpoint.GET_ACCOUNT_INFO, { users: [serverUser] }); }); afterEach(mockFetch.tearDown); it('should sign in the user', async () => { const { _tokenResponse, user, operationType } = (await signInWithEmailAndPassword( auth, 'some-email', 'some-password' )) as UserCredentialInternal; expect(_tokenResponse).to.eql({ idToken: 'id-token', refreshToken: 'refresh-token', expiresIn: '1234', localId: serverUser.localId! }); expect(operationType).to.eq(OperationType.SIGN_IN); expect(user.uid).to.eq(serverUser.localId); expect(user.isAnonymous).to.be.false; }); });