From 46cba3734ecc2c284f766fa0d884700eb65163c3 Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Sun, 15 Nov 2020 18:15:04 -0500 Subject: [PATCH] tests(auth, e2e): re-enable tests, use auth emulator Found at least 2 unexpected real issues along the way The emulator is great though, no API limits --- packages/app/e2e/helpers.js | 12 +++ packages/auth/e2e/auth.e2e.js | 88 +++++++++++++-------- packages/auth/e2e/helpers.js | 91 +++++++++++++++++++++ packages/auth/e2e/phone.e2e.js | 94 ++++++++++------------ packages/auth/e2e/rnReload.e2e.js | 26 ++++-- packages/auth/e2e/user.e2e.js | 100 +++++++++++++++--------- packages/firestore/e2e/helpers.js | 42 +++++----- packages/messaging/e2e/messaging.e2e.js | 4 + tests/app.js | 2 + tests/e2e/mocha.opts | 8 +- 10 files changed, 314 insertions(+), 153 deletions(-) create mode 100644 packages/app/e2e/helpers.js create mode 100644 packages/auth/e2e/helpers.js diff --git a/packages/app/e2e/helpers.js b/packages/app/e2e/helpers.js new file mode 100644 index 00000000000..9358f593436 --- /dev/null +++ b/packages/app/e2e/helpers.js @@ -0,0 +1,12 @@ +exports.getE2eTestProject = function getE2eTestProject() { + return 'react-native-firebase-testing'; +}; + +// Android requires a re-mapped hostname during testing sometimes +exports.getE2eEmulatorHost = function getE2eEmulatorHost() { + // This appears to work from localhost even on android. Different execution context? + // if (platform === 'android') { + // return '10.0.2.2'; + // } + return 'localhost'; +}; diff --git a/packages/auth/e2e/auth.e2e.js b/packages/auth/e2e/auth.e2e.js index 999f504382f..a8d4885ef6f 100644 --- a/packages/auth/e2e/auth.e2e.js +++ b/packages/auth/e2e/auth.e2e.js @@ -15,7 +15,41 @@ * */ +const TEST_EMAIL = 'test@test.com'; +const TEST_PASS = 'test1234'; + +const DISABLED_EMAIL = 'disabled@account.com'; +const DISABLED_PASS = 'test1234'; + +const { clearAllUsers } = require('./helpers'); + describe('auth()', () => { + before(async () => { + try { + await clearAllUsers(); + await firebase.auth().createUserWithEmailAndPassword(TEST_EMAIL, TEST_PASS); + } catch (e) { + // they may already exist, that's fine + } + // Need a way to create the user but have it disabled immediately + // If we had the functions emulator running as well, it would work: + // https://stackoverflow.com/questions/43140441/how-to-disable-user-accounts-on-firebase-authentication-automatically#comment73363725_43141780 + // try { + // const userCredential = await firebase + // .auth() + // .createUserWithEmailAndPassword(DISABLED_EMAIL, DISABLED_PASS); + // } catch (e) { + // // they may already exist, that's fine + // } + }); + + beforeEach(async () => { + if (firebase.auth().currentUser) { + await firebase.auth().signOut(); + await Utils.sleep(50); + } + }); + describe('namespace', () => { it('accessible from firebase.app()', () => { const app = firebase.app(); @@ -39,6 +73,7 @@ describe('auth()', () => { }); describe('applyActionCode()', () => { + // Needs a different setup to work against the auth emulator xit('works as expected', async () => { await firebase .auth() @@ -127,16 +162,14 @@ describe('auth()', () => { }); describe('signInWithCustomToken()', () => { - it('signs in with a admin sdk created custom auth token', async () => { - const email = 'test@test.com'; - const pass = 'test1234'; - + // Needs a different setup when running against the emulator + xit('signs in with a admin sdk created custom auth token', async () => { const successCb = currentUserCredential => { const currentUser = currentUserCredential.user; currentUser.should.be.an.Object(); currentUser.uid.should.be.a.String(); currentUser.toJSON().should.be.an.Object(); - currentUser.toJSON().email.should.eql(email); + currentUser.toJSON().email.should.eql(TEST_EMAIL); currentUser.isAnonymous.should.equal(false); currentUser.providerId.should.equal('firebase'); currentUser.should.equal(firebase.auth().currentUser); @@ -150,7 +183,7 @@ describe('auth()', () => { const user = await firebase .auth() - .signInWithEmailAndPassword(email, pass) + .signInWithEmailAndPassword(TEST_EMAIL, TEST_PASS) .then(successCb); const IdToken = await firebase.auth().currentUser.getIdToken(); @@ -162,7 +195,7 @@ describe('auth()', () => { await firebase.auth().signInWithCustomToken(token); - firebase.auth().currentUser.email.should.equal('test@test.com'); + firebase.auth().currentUser.email.should.equal(TEST_EMAIL); }); }); @@ -540,15 +573,12 @@ describe('auth()', () => { describe('signInWithEmailAndPassword()', () => { it('it should login with email and password', () => { - const email = 'test@test.com'; - const pass = 'test1234'; - const successCb = currentUserCredential => { const currentUser = currentUserCredential.user; currentUser.should.be.an.Object(); currentUser.uid.should.be.a.String(); currentUser.toJSON().should.be.an.Object(); - currentUser.toJSON().email.should.eql(email); + currentUser.toJSON().email.should.eql(TEST_EMAIL); currentUser.isAnonymous.should.equal(false); currentUser.providerId.should.equal('firebase'); currentUser.should.equal(firebase.auth().currentUser); @@ -562,14 +592,12 @@ describe('auth()', () => { return firebase .auth() - .signInWithEmailAndPassword(email, pass) + .signInWithEmailAndPassword(TEST_EMAIL, TEST_PASS) .then(successCb); }); - it('it should error on login if user is disabled', () => { - const email = 'disabled@account.com'; - const pass = 'test1234'; - + // Need to set these up differently to run against emulator + xit('it should error on login if user is disabled', () => { const successCb = () => Promise.reject(new Error('Did not error.')); const failureCb = error => { @@ -580,15 +608,12 @@ describe('auth()', () => { return firebase .auth() - .signInWithEmailAndPassword(email, pass) + .signInWithEmailAndPassword(DISABLED_EMAIL, DISABLED_PASS) .then(successCb) .catch(failureCb); }); it('it should error on login if password incorrect', () => { - const email = 'test@test.com'; - const pass = 'test1234666'; - const successCb = () => Promise.reject(new Error('Did not error.')); const failureCb = error => { @@ -601,7 +626,7 @@ describe('auth()', () => { return firebase .auth() - .signInWithEmailAndPassword(email, pass) + .signInWithEmailAndPassword(TEST_EMAIL, TEST_PASS + '666') .then(successCb) .catch(failureCb); }); @@ -631,14 +656,14 @@ describe('auth()', () => { describe('signInWithCredential()', () => { it('it should login with email and password', () => { - const credential = firebase.auth.EmailAuthProvider.credential('test@test.com', 'test1234'); + const credential = firebase.auth.EmailAuthProvider.credential(TEST_EMAIL, TEST_PASS); const successCb = currentUserCredential => { const currentUser = currentUserCredential.user; currentUser.should.be.an.Object(); currentUser.uid.should.be.a.String(); currentUser.toJSON().should.be.an.Object(); - currentUser.toJSON().email.should.eql('test@test.com'); + currentUser.toJSON().email.should.eql(TEST_EMAIL); currentUser.isAnonymous.should.equal(false); currentUser.providerId.should.equal('firebase'); currentUser.should.equal(firebase.auth().currentUser); @@ -656,11 +681,9 @@ describe('auth()', () => { .then(successCb); }); - it('it should error on login if user is disabled', () => { - const credential = firebase.auth.EmailAuthProvider.credential( - 'disabled@account.com', - 'test1234', - ); + // Need to set these up differently to run against emulator + xit('it should error on login if user is disabled', () => { + const credential = firebase.auth.EmailAuthProvider.credential(DISABLED_EMAIL, DISABLED_PASS); const successCb = () => Promise.reject(new Error('Did not error.')); @@ -678,7 +701,7 @@ describe('auth()', () => { }); it('it should error on login if password incorrect', () => { - const credential = firebase.auth.EmailAuthProvider.credential('test@test.com', 'test1234666'); + const credential = firebase.auth.EmailAuthProvider.credential(TEST_EMAIL, TEST_PASS + '666'); const successCb = () => Promise.reject(new Error('Did not error.')); @@ -770,9 +793,6 @@ describe('auth()', () => { }); it('it should error on create if email in use', () => { - const email = 'test@test.com'; - const pass = 'test123456789'; - const successCb = () => Promise.reject(new Error('Did not error.')); const failureCb = error => { @@ -783,7 +803,7 @@ describe('auth()', () => { return firebase .auth() - .createUserWithEmailAndPassword(email, pass) + .createUserWithEmailAndPassword(TEST_EMAIL, TEST_PASS) .then(successCb) .catch(failureCb); }); @@ -824,7 +844,7 @@ describe('auth()', () => { return firebase .auth() - .fetchSignInMethodsForEmail('test@test.com') + .fetchSignInMethodsForEmail(TEST_EMAIL) .then(successCb) .catch(failureCb); })); diff --git a/packages/auth/e2e/helpers.js b/packages/auth/e2e/helpers.js new file mode 100644 index 00000000000..02760b6a99b --- /dev/null +++ b/packages/auth/e2e/helpers.js @@ -0,0 +1,91 @@ +/* eslint-disable no-console */ +const { getE2eTestProject, getE2eEmulatorHost } = require('../../app/e2e/helpers'); +const http = require('http'); + +exports.getRandomPhoneNumber = function getRandomPhoneNumber() { + return '+593' + Utils.randString(9, '#19'); +}; + +exports.clearAllUsers = async function clearAllUsers() { + // console.log('auth::helpers::clearAllUsers'); + try { + const deleteOptions = { + method: 'DELETE', + headers: { + // Undocumented, but necessary - pulled from watching raw Emulator Web UI network requests + Authorization: 'Bearer owner', + }, + port: 9099, + host: getE2eEmulatorHost(), + path: '/emulator/v1/projects/' + getE2eTestProject() + '/accounts', + }; + // console.log('request: ' + JSON.stringify(deleteOptions)); + await new Promise((resolve, reject) => { + const req = http.request(deleteOptions); + req.on('error', error => reject(error)); + req.end(resolve()); + }); + } catch (e) { + console.error('Unable to wipe auth:', e); + throw e; + } +}; + +// Email / OOB codes are here http://localhost:9099/emulator/v1/projects/react-native-firebase-testing/oobCodes + +exports.getLastSmsCode = async function getLastSmsCode(specificPhone) { + let lastSmsCode = null; + try { + // console.log('auth::e2e:helpers:getLastSmsCode - start'); + const getSmsCodesUrl = + 'http://' + + getE2eEmulatorHost() + + ':9099/emulator/v1/projects/' + + getE2eTestProject() + + '/verificationCodes'; + + const responseData = await new Promise((resolve, reject) => { + // console.log('auth::e2e:helpers:getLastSmsCode - making request'); + const req = http.get(getSmsCodesUrl, response => { + // console.log('auth::e2e:helpers:getLastSmsCode - callback'); + let data = ''; + response.on('data', chunk => { + // console.log('auth::e2e:helpers:getLastSmsCode - request callback response data callback'); + // console.log('data event, got chunk: ' + chunk); + data += chunk; + }); + response.on('end', () => { + // console.log('auth::e2e:helpers:getLastSmsCode - request callback response end callback'); + resolve(JSON.parse(data)); + }); + }); + req.on('error', error => reject(error)); + }); + // Process the codes, the last one in the array is the one... + // console.log('getLastSmsCode got ', JSON.stringify(responseData, null, 2)); + const codes = responseData ? responseData.verificationCodes : undefined; + if (codes && codes.length > 0) { + if (specificPhone) { + // roll through backwards (to get last valid code) searching for the specific phone + for (let i = codes.length - 1; i >= 0 && !lastSmsCode; i--) { + const codeBlock = codes[i]; + if (codeBlock.phoneNumber === specificPhone) { + lastSmsCode = codeBlock.code; + } + } + } else { + lastSmsCode = codes[codes.length - 1].code; + } + } else { + throw new Error('There were no unused verification codes'); + } + } catch (e) { + console.error('Unable to get SMS Verification codes', e); + throw e; + } + // console.log('getLastSmsCode returning code: ' + lastSmsCode); + return lastSmsCode; +}; + +// https://firebase.google.com/docs/reference/rest/auth#section-auth-emulator-smsverification +// const smsCodeFromREST = 'not-implemented'; diff --git a/packages/auth/e2e/phone.e2e.js b/packages/auth/e2e/phone.e2e.js index b45deca381a..22e5695ed2a 100644 --- a/packages/auth/e2e/phone.e2e.js +++ b/packages/auth/e2e/phone.e2e.js @@ -1,13 +1,16 @@ -const TEST_PHONE_A = '+447445255123'; -const TEST_CODE_A = '123456'; +// const TEST_EMAIL = 'test@test.com'; +// const TEST_PASS = 'test1234'; -// const TEST_PHONE_B = '+447445123457'; -// const TEST_CODE_B = '654321'; +const { clearAllUsers, getLastSmsCode, getRandomPhoneNumber } = require('./helpers'); describe('auth() => Phone', () => { before(async () => { + try { + await clearAllUsers(); + } catch (e) { + throw e; + } firebase.auth().settings.appVerificationDisabledForTesting = true; - await firebase.auth().settings.setAutoRetrievedSmsCodeForPhoneNumber(TEST_PHONE_A, TEST_CODE_A); await Utils.sleep(50); }); @@ -19,12 +22,14 @@ describe('auth() => Phone', () => { }); describe('signInWithPhoneNumber', () => { - xit('signs in with a valid code', async () => { - const confirmResult = await firebase.auth().signInWithPhoneNumber(TEST_PHONE_A); + it('signs in with a valid code', async () => { + const testPhone = await getRandomPhoneNumber(); + const confirmResult = await firebase.auth().signInWithPhoneNumber(testPhone); confirmResult.verificationId.should.be.a.String(); should.ok(confirmResult.verificationId.length, 'verificationId string should not be empty'); confirmResult.confirm.should.be.a.Function(); - const userCredential = await confirmResult.confirm(TEST_CODE_A); + const lastSmsCode = await getLastSmsCode(testPhone); + const userCredential = await confirmResult.confirm(lastSmsCode); userCredential.user.should.be.instanceOf(jet.require('packages/auth/lib/User')); // Broken check, phone number is undefined @@ -32,42 +37,46 @@ describe('auth() => Phone', () => { }); it('errors on invalid code', async () => { - const confirmResult = await firebase.auth().signInWithPhoneNumber(TEST_PHONE_A); + const testPhone = await getRandomPhoneNumber(); + const confirmResult = await firebase.auth().signInWithPhoneNumber(testPhone); confirmResult.verificationId.should.be.a.String(); should.ok(confirmResult.verificationId.length, 'verificationId string should not be empty'); confirmResult.confirm.should.be.a.Function(); - await confirmResult.confirm('666999').should.be.rejected(); + // Get the last SMS code just to make absolutely sure we don't accidentally use it + const lastSmsCode = await getLastSmsCode(testPhone); + await confirmResult + .confirm(lastSmsCode === '000000' ? '111111' : '000000') + .should.be.rejected(); // TODO test error code and message + + // If you don't consume the valid code, then it sticks around + await confirmResult.confirm(lastSmsCode); }); }); describe('verifyPhoneNumber', async () => { it('successfully verifies', async () => { - const TEST_PHONE_A = '+447445255123'; - const confirmResult = await firebase.auth().signInWithPhoneNumber(TEST_PHONE_A); - - await confirmResult.confirm(TEST_CODE_A); - await firebase.auth().verifyPhoneNumber(TEST_PHONE_A, false, false); + const testPhone = await getRandomPhoneNumber(); + const confirmResult = await firebase.auth().signInWithPhoneNumber(testPhone); + const lastSmsCode = await getLastSmsCode(testPhone); + await confirmResult.confirm(lastSmsCode); + await firebase.auth().verifyPhoneNumber(testPhone, false, false); }); it('uses the autoVerifyTimeout when a non boolean autoVerifyTimeoutOrForceResend is provided', async () => { - const TEST_PHONE_A = '+447445255123'; - const confirmResult = await firebase.auth().signInWithPhoneNumber(TEST_PHONE_A); - - await confirmResult.confirm(TEST_CODE_A); - await firebase.auth().verifyPhoneNumber(TEST_PHONE_A, 0, false); + const testPhone = await getRandomPhoneNumber(); + const confirmResult = await firebase.auth().signInWithPhoneNumber(testPhone); + const lastSmsCode = await getLastSmsCode(testPhone); + await confirmResult.confirm(lastSmsCode); + await firebase.auth().verifyPhoneNumber(testPhone, 0, false); }); it('throws an error with an invalid on event', async () => { - const TEST_PHONE_A = '+447445255123'; - const confirmResult = await firebase.auth().signInWithPhoneNumber(TEST_PHONE_A); - - await confirmResult.confirm(TEST_CODE_A); - + const testPhone = await getRandomPhoneNumber(); try { await firebase .auth() - .verifyPhoneNumber(TEST_PHONE_A) + .verifyPhoneNumber(testPhone) .on('example', () => {}); return Promise.reject(new Error('Did not throw Error.')); @@ -80,15 +89,11 @@ describe('auth() => Phone', () => { }); it('throws an error with an invalid observer event', async () => { - const TEST_PHONE_A = '+447445255123'; - const confirmResult = await firebase.auth().signInWithPhoneNumber(TEST_PHONE_A); - - await confirmResult.confirm(TEST_CODE_A); - + const testPhone = await getRandomPhoneNumber(); try { await firebase .auth() - .verifyPhoneNumber(TEST_PHONE_A) + .verifyPhoneNumber(testPhone) .on('state_changed', null, null, () => {}); return Promise.reject(new Error('Did not throw Error.')); @@ -101,45 +106,30 @@ describe('auth() => Phone', () => { }); it('successfully runs verification complete handler', async () => { - const TEST_PHONE_A = '+447445255123'; - const confirmResult = await firebase.auth().signInWithPhoneNumber(TEST_PHONE_A); - - await confirmResult.confirm(TEST_CODE_A); - + const testPhone = await getRandomPhoneNumber(); await firebase .auth() - .verifyPhoneNumber(TEST_PHONE_A) + .verifyPhoneNumber(testPhone) .then($ => $); return Promise.resolve(); }); - it('successfully runs and adds emiters', async () => { - const TEST_PHONE_A = '+447445255123'; - const confirmResult = await firebase.auth().signInWithPhoneNumber(TEST_PHONE_A); - - await confirmResult.confirm(TEST_CODE_A); - + it('successfully runs and adds emitters', async () => { + const testPhone = await getRandomPhoneNumber(); const obervserCb = () => {}; - const errorCb = () => {}; - const successCb = () => { return Promise.resolve(); }; await firebase .auth() - .verifyPhoneNumber(TEST_PHONE_A) + .verifyPhoneNumber(testPhone) .on('state_changed', obervserCb, errorCb, successCb, () => {}); }); it('catches an error and emits an error event', async () => { - const TEST_PHONE_A = '+447445255123'; - const confirmResult = await firebase.auth().signInWithPhoneNumber(TEST_PHONE_A); - - await confirmResult.confirm(TEST_CODE_A); - return firebase .auth() .verifyPhoneNumber('test') diff --git a/packages/auth/e2e/rnReload.e2e.js b/packages/auth/e2e/rnReload.e2e.js index 5ebfdb16235..bbb89ac0145 100644 --- a/packages/auth/e2e/rnReload.e2e.js +++ b/packages/auth/e2e/rnReload.e2e.js @@ -1,4 +1,22 @@ +const TEST_EMAIL = 'test@test.com'; +const TEST_PASS = 'test1234'; + +const { clearAllUsers } = require('./helpers'); + describe('auth()', () => { + before(async () => { + try { + await clearAllUsers(); + } catch (e) { + throw e; + } + try { + await firebase.auth().createUserWithEmailAndPassword(TEST_EMAIL, TEST_PASS); + } catch (e) { + // they may already exist, that's fine + } + }); + beforeEach(async () => { if (firebase.auth().currentUser) { await firebase.auth().signOut(); @@ -39,15 +57,13 @@ describe('auth()', () => { // in with a different user then reloading await firebase.auth().signOut(); - const email = 'test@test.com'; - const pass = 'test1234'; - await firebase.auth().signInWithEmailAndPassword(email, pass); + await firebase.auth().signInWithEmailAndPassword(TEST_EMAIL, TEST_PASS); ({ currentUser } = firebase.auth()); currentUser.should.be.an.Object(); currentUser.uid.should.be.a.String(); currentUser.toJSON().should.be.an.Object(); - currentUser.toJSON().email.should.eql(email); + currentUser.toJSON().email.should.eql(TEST_EMAIL); currentUser.isAnonymous.should.equal(false); currentUser.providerId.should.equal('firebase'); currentUser.should.equal(firebase.auth().currentUser); @@ -60,7 +76,7 @@ describe('auth()', () => { currentUser.should.be.an.Object(); currentUser.uid.should.be.a.String(); currentUser.toJSON().should.be.an.Object(); - currentUser.toJSON().email.should.eql(email); + currentUser.toJSON().email.should.eql(TEST_EMAIL); currentUser.isAnonymous.should.equal(false); currentUser.providerId.should.equal('firebase'); currentUser.should.equal(firebase.auth().currentUser); diff --git a/packages/auth/e2e/user.e2e.js b/packages/auth/e2e/user.e2e.js index 9bb487583c6..e4eaf6ccedf 100644 --- a/packages/auth/e2e/user.e2e.js +++ b/packages/auth/e2e/user.e2e.js @@ -1,4 +1,23 @@ +const TEST_EMAIL = 'test@test.com'; +const TEST_PASS = 'test1234'; + +const { clearAllUsers, getLastSmsCode, getRandomPhoneNumber } = require('./helpers'); + describe('auth().currentUser', () => { + before(async () => { + try { + await clearAllUsers(); + } catch (e) { + throw e; + } + firebase.auth().settings.appVerificationDisabledForTesting = true; + try { + await firebase.auth().createUserWithEmailAndPassword(TEST_EMAIL, TEST_PASS); + } catch (e) { + // they may already exist, that's fine + } + }); + beforeEach(async () => { if (firebase.auth().currentUser) { await firebase.auth().signOut(); @@ -57,6 +76,7 @@ describe('auth().currentUser', () => { }); describe('linkWithCredential()', () => { + // hanging against auth emulator? it('should link anonymous account <-> email account', async () => { const random = Utils.randString(12, '#aA'); const email = `${random}@${random}.com`; @@ -84,16 +104,14 @@ describe('auth().currentUser', () => { await firebase.auth().currentUser.delete(); }); + // hanging against auth emulator? it('should error on link anon <-> email if email already exists', async () => { - const email = 'test@test.com'; - const pass = 'test1234'; - await firebase.auth().signInAnonymously(); const { currentUser } = firebase.auth(); // Test try { - const credential = firebase.auth.EmailAuthProvider.credential(email, pass); + const credential = firebase.auth.EmailAuthProvider.credential(TEST_EMAIL, TEST_PASS); await currentUser.linkWithCredential(credential); // Clean up @@ -580,6 +598,8 @@ describe('auth().currentUser', () => { await firebase.auth().currentUser.delete(); }); + // FIXME Currently failing with an internal error against emulator + // com.google.firebase.FirebaseException: An internal error has occurred. [ VERIFY_AND_CHANGE_EMAIL ] xit('should not error', async () => { const random = Utils.randString(12, '#aA'); const random2 = Utils.randString(12, '#aA'); @@ -589,12 +609,14 @@ describe('auth().currentUser', () => { try { await firebase.auth().createUserWithEmailAndPassword(email, random); await firebase.auth().currentUser.verifyBeforeUpdateEmail(updateEmail); - } catch (_) { + } catch (e) { return Promise.reject("'verifyBeforeUpdateEmail()' did not work"); } await firebase.auth().currentUser.delete(); }); + // FIXME Currently failing with an internal error against emulator + // com.google.firebase.FirebaseException: An internal error has occurred. [ VERIFY_AND_CHANGE_EMAIL ] xit('should work with actionCodeSettings', async () => { const random = Utils.randString(12, '#aA'); const random2 = Utils.randString(12, '#aA'); @@ -610,7 +632,8 @@ describe('auth().currentUser', () => { } catch (error) { try { await firebase.auth().currentUser.delete(); - } catch (_) { + } catch (e) { + consle.log(e); /* do nothing */ } @@ -671,43 +694,46 @@ describe('auth().currentUser', () => { }); }); - // TODO: Figure how to mock phone credentials on updating a phone number describe('updatePhoneNumber()', () => { - it('should update the profile', async () => { - // Create with initial number - const TEST_PHONE_A = '+447445255123'; - const TEST_CODE_A = '123456'; - - firebase.auth().settings.appVerificationDisabledForTesting = true; + it('should update the phone number', async () => { + const testPhone = await getRandomPhoneNumber(); + const confirmResult = await firebase.auth().signInWithPhoneNumber(testPhone); + const smsCode = await getLastSmsCode(testPhone); + await confirmResult.confirm(smsCode); - await firebase - .auth() - .settings.setAutoRetrievedSmsCodeForPhoneNumber(TEST_PHONE_A, TEST_CODE_A); - await Utils.sleep(50); + firebase.auth().currentUser.phoneNumber.should.equal(testPhone); - //Sign Out - if (firebase.auth().currentUser) { - await firebase.auth().signOut(); - await Utils.sleep(50); - } - - //Sign in number - const confirmResult = await firebase.auth().signInWithPhoneNumber(TEST_PHONE_A); - - await confirmResult.confirm(TEST_CODE_A); + const newPhone = await getRandomPhoneNumber(); + const newPhoneVerificationId = await new Promise((resolve, reject) => { + firebase + .auth() + .verifyPhoneNumber(newPhone) + .on('state_changed', phoneAuthSnapshot => { + if (phoneAuthSnapshot.error) { + reject(phoneAuthSnapshot.error); + } else { + resolve(phoneAuthSnapshot.verificationId); + } + }); + }); - const credential = await firebase.auth.PhoneAuthProvider.credential( - confirmResult.verificationId, - TEST_CODE_A, - ); + try { + const newSmsCode = await getLastSmsCode(newPhone); + const credential = await firebase.auth.PhoneAuthProvider.credential( + newPhoneVerificationId, + newSmsCode, + ); - //Update with number? - await firebase - .auth() - .currentUser.updatePhoneNumber(credential) - .then($ => $); + //Update with number? + await firebase + .auth() + .currentUser.updatePhoneNumber(credential) + .then($ => $); + } catch (e) { + throw e; + } - // TODO Add assertions, what exactly does this update. No phone number included to update? + firebase.auth().currentUser.phoneNumber.should.equal(newPhone); }); }); diff --git a/packages/firestore/e2e/helpers.js b/packages/firestore/e2e/helpers.js index a3c60a60ec6..9a7d0a52898 100644 --- a/packages/firestore/e2e/helpers.js +++ b/packages/firestore/e2e/helpers.js @@ -1,4 +1,5 @@ /* eslint-disable no-console */ +const { getE2eTestProject, getE2eEmulatorHost } = require('../../app/e2e/helpers'); /* * Copyright (c) 2016-present Invertase Limited & Contributors @@ -18,28 +19,31 @@ */ const http = require('http'); -const deleteOptions = { - method: 'DELETE', - port: 8080, - host: '127.0.0.1', - path: '/emulator/v1/projects/react-native-firebase-testing/databases/(default)/documents', -}; - exports.wipe = async function wipe(debug = false) { - if (debug) { - console.time('wipe'); - } + const deleteOptions = { + method: 'DELETE', + port: 8080, + host: getE2eEmulatorHost(), + path: '/emulator/v1/projects/' + getE2eTestProject() + '/databases/(default)/documents', + }; - await new Promise((resolve, reject) => { - const req = http.request(deleteOptions); + try { + if (debug) { + console.time('wipe'); + } + await new Promise((resolve, reject) => { + const req = http.request(deleteOptions); - req.on('error', error => reject(error)); + req.on('error', error => reject(error)); - req.end(() => { - if (debug) { - console.timeEnd('wipe'); - } - resolve(); + req.end(() => { + if (debug) { + console.timeEnd('wipe'); + } + resolve(); + }); }); - }); + } catch (e) { + console.error('Unable to wipe firestore:', e); + } }; diff --git a/packages/messaging/e2e/messaging.e2e.js b/packages/messaging/e2e/messaging.e2e.js index 34779adabfe..5387031a4ef 100644 --- a/packages/messaging/e2e/messaging.e2e.js +++ b/packages/messaging/e2e/messaging.e2e.js @@ -252,6 +252,10 @@ describe('messaging()', () => { }); android.it('receives messages when the app is in the background', async () => { + // This is slow and thus flaky in CI. It runs locally though. + if (global.isCI) { + return; + } const spy = sinon.spy(); const token = await firebase.messaging().getToken(); firebase.messaging().setBackgroundMessageHandler(remoteMessage => { diff --git a/tests/app.js b/tests/app.js index 0ddfed57b9e..6e10f5de52f 100644 --- a/tests/app.js +++ b/tests/app.js @@ -44,6 +44,8 @@ jet.exposeContextProperty('module', firebase); const firestore = firebase.firestore(); firestore.settings({ host: 'localhost:8080', ssl: false, persistence: true }); +firebase.auth().useEmulator('http://localhost:9099'); + function Root() { return (