diff --git a/bridge/e2e/auth/module.e2e.js b/bridge/e2e/auth/module.e2e.js index 4550ebda..350feda5 100644 --- a/bridge/e2e/auth/module.e2e.js +++ b/bridge/e2e/auth/module.e2e.js @@ -1,17 +1,4 @@ -const randomString = (length, chars) => { - let mask = ''; - if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz'; - if (chars.indexOf('A') > -1) mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - if (chars.indexOf('#') > -1) mask += '0123456789'; - if (chars.indexOf('!') > -1) mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\'; - let result = ''; - for (let i = length; i > 0; --i) { - result += mask[Math.round(Math.random() * (mask.length - 1))]; - } - return result; -}; - -describe.only('auth()', () => { +describe('auth()', () => { beforeEach(async () => { // await device.reloadReactNative(); }); diff --git a/bridge/e2e/auth/user.e2e.js b/bridge/e2e/auth/user.e2e.js new file mode 100644 index 00000000..3bfc4b81 --- /dev/null +++ b/bridge/e2e/auth/user.e2e.js @@ -0,0 +1,485 @@ +describe.only('auth().currentUser', () => { + describe('getIdToken()', () => { + it('should return a token', async () => { + const random = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const pass = random; + + const newUser = await firebase + .auth() + .createUserWithEmailAndPassword(email, pass); + + // Test + const token = await newUser.getIdToken(); + + // Assertions + token.should.be.a.String(); + token.length.should.be.greaterThan(24); + + // Clean up + await firebase.auth().currentUser.delete(); + }); + }); + + describe('getToken()', () => { + it('should return a token', async () => { + const random = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const pass = random; + + const newUser = await firebase + .auth() + .createUserWithEmailAndPassword(email, pass); + + // Test + const token = await newUser.getToken(); + + // Assertions + token.should.be.a.String(); + token.length.should.be.greaterThan(24); + + // Clean up + await firebase.auth().currentUser.delete(); + }); + }); + + describe('linkWithCredential()', () => { + it('should link anonymous account <-> email account', async () => { + const random = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const pass = random; + + await firebase.auth().signInAnonymouslyAndRetrieveData(); + const currentUser = firebase.auth().currentUser; + + // Test + const credential = firebase.auth.EmailAuthProvider.credential( + email, + pass + ); + + const linkedUser = await currentUser.linkWithCredential(credential); + + // Assertions + linkedUser.should.be.an.Object(); + linkedUser.should.equal(firebase.auth().currentUser); + linkedUser.email.toLowerCase().should.equal(email.toLowerCase()); + linkedUser.isAnonymous.should.equal(false); + linkedUser.providerId.should.equal('firebase'); + linkedUser.providerData.should.be.an.Array(); + linkedUser.providerData.length.should.equal(1); + + // Clean up + await firebase.auth().currentUser.delete(); + }); + + it('should error on link anon <-> email if email already exists', async () => { + const email = 'test@test.com'; + const pass = 'test1234'; + + await firebase.auth().signInAnonymouslyAndRetrieveData(); + const currentUser = firebase.auth().currentUser; + + // Test + try { + const credential = firebase.auth.EmailAuthProvider.credential( + email, + pass + ); + await currentUser.linkWithCredential(credential); + + // Clean up + await firebase.auth().signOut(); + + // Reject + Promise.reject(new Error('Did not error on link')); + } catch (error) { + // Assertions + error.code.should.equal('auth/email-already-in-use'); + error.message.should.equal( + 'The email address is already in use by another account.' + ); + + // Clean up + await firebase.auth().currentUser.delete(); + } + }); + }); + + describe('linkAndRetrieveDataWithCredential()', () => { + it('should link anonymous account <-> email account', async () => { + const random = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const pass = random; + + await firebase.auth().signInAnonymouslyAndRetrieveData(); + const currentUser = firebase.auth().currentUser; + + // Test + const credential = firebase.auth.EmailAuthProvider.credential( + email, + pass + ); + + const linkedUserCredential = await currentUser.linkAndRetrieveDataWithCredential( + credential + ); + + // Assertions + const linkedUser = linkedUserCredential.user; + linkedUser.should.be.an.Object(); + linkedUser.should.equal(firebase.auth().currentUser); + linkedUser.email.toLowerCase().should.equal(email.toLowerCase()); + linkedUser.isAnonymous.should.equal(false); + linkedUser.providerId.should.equal('firebase'); + linkedUser.providerData.should.be.an.Array(); + linkedUser.providerData.length.should.equal(1); + + // Clean up + await firebase.auth().currentUser.delete(); + }); + + it('should error on link anon <-> email if email already exists', async () => { + const email = 'test@test.com'; + const pass = 'test1234'; + + await firebase.auth().signInAnonymouslyAndRetrieveData(); + const currentUser = firebase.auth().currentUser; + + // Test + try { + const credential = firebase.auth.EmailAuthProvider.credential( + email, + pass + ); + await currentUser.linkAndRetrieveDataWithCredential(credential); + + // Clean up + await firebase.auth().signOut(); + + // Reject + Promise.reject(new Error('Did not error on link')); + } catch (error) { + // Assertions + error.code.should.equal('auth/email-already-in-use'); + error.message.should.equal( + 'The email address is already in use by another account.' + ); + + // Clean up + await firebase.auth().currentUser.delete(); + } + }); + }); + + describe('reauthenticateWithCredential()', () => { + it('should reauthenticate correctly', async () => { + const random = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const pass = random; + + await firebase + .auth() + .createUserAndRetrieveDataWithEmailAndPassword(email, pass); + + // Test + const credential = firebase.auth.EmailAuthProvider.credential( + email, + pass + ); + await firebase + .auth() + .currentUser.reauthenticateWithCredential(credential); + + // Assertions + const currentUser = firebase.auth().currentUser; + currentUser.email.should.equal(email.toLowerCase()); + + // Clean up + await firebase.auth().currentUser.delete(); + }); + }); + + describe('reauthenticateAndRetrieveDataWithCredential()', () => { + it('should reauthenticate correctly', async () => { + const random = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const pass = random; + + await firebase + .auth() + .createUserAndRetrieveDataWithEmailAndPassword(email, pass); + + // Test + const credential = firebase.auth.EmailAuthProvider.credential( + email, + pass + ); + await firebase + .auth() + .currentUser.reauthenticateAndRetrieveDataWithCredential(credential); + + // Assertions + const currentUser = firebase.auth().currentUser; + currentUser.email.should.equal(email.toLowerCase()); + + // Clean up + await firebase.auth().currentUser.delete(); + }); + }); + + describe('reload()', () => { + it('should not error', async () => { + await firebase.auth().signInAnonymouslyAndRetrieveData(); + + try { + await firebase.auth().currentUser.reload(); + await firebase.auth().signOut(); + } catch (error) { + // Reject + await firebase.auth().signOut(); + Promise.reject(new Error('reload() caused an error', error)); + } + }); + }); + + describe('sendEmailVerification()', () => { + it('should not error', async () => { + const random = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const pass = random; + + await firebase + .auth() + .createUserAndRetrieveDataWithEmailAndPassword(email, pass); + + try { + await firebase.auth().currentUser.sendEmailVerification(); + await firebase.auth().currentUser.delete(); + } catch (error) { + // Reject + await firebase.auth().currentUser.delete(); + Promise.reject( + new Error('sendEmailVerification() caused an error', error) + ); + } + }); + }); + + describe('unlink()', () => { + it('should unlink the email address', async () => { + const random = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const pass = random; + + await firebase.auth().signInAnonymouslyAndRetrieveData(); + const currentUser = firebase.auth().currentUser; + + const credential = firebase.auth.EmailAuthProvider.credential( + email, + pass + ); + await currentUser.linkAndRetrieveDataWithCredential(credential); + + // Test + await currentUser.unlink(firebase.auth.EmailAuthProvider.PROVIDER_ID); + + // Assertions + const unlinkedUser = firebase.auth().currentUser; + unlinkedUser.providerData.should.be.an.Array(); + unlinkedUser.providerData.length.should.equal(0); + + // Clean up + await firebase.auth().currentUser.delete(); + }); + }); + + describe('updateEmail()', () => { + it('should update the email address', async () => { + const random = randomString(12, '#aA'); + const random2 = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const email2 = `${random2}@${random2}.com`; + const pass = random; + + // Setup + await firebase + .auth() + .createUserAndRetrieveDataWithEmailAndPassword(email, pass); + firebase + .auth() + .currentUser.email.toLowerCase() + .should.equal(email.toLowerCase()); + + // Update user email + await firebase.auth().currentUser.updateEmail(email2); + + // Assertions + firebase + .auth() + .currentUser.email.toLowerCase() + .should.equal(email2.toLowerCase()); + + // Clean up + await firebase.auth().currentUser.delete(); + }); + }); + + describe('updatePassword()', () => { + it('should update the password', async () => { + const random = randomString(12, '#aA'); + const random2 = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const pass = random; + const pass2 = random2; + + // Setup + await firebase + .auth() + .createUserAndRetrieveDataWithEmailAndPassword(email, pass); + + // Update user password + await firebase.auth().currentUser.updatePassword(pass2); + + // Sign out + await firebase.auth().signOut(); + + // Log in with the new password + await firebase + .auth() + .signInAndRetrieveDataWithEmailAndPassword(email, pass2); + + // Assertions + firebase.auth().currentUser.should.be.an.Object(); + firebase.auth().currentUser.email.should.equal(email.toLowerCase()); + + // Clean up + await firebase.auth().currentUser.delete(); + }); + }); + + describe('updateProfile()', () => { + it('should update the profile', async () => { + const random = randomString(12, '#aA'); + const email = `${random}@${random}.com`; + const pass = random; + const displayName = random; + const photoURL = `http://${random}.com/${random}.jpg`; + + // Setup + await firebase + .auth() + .createUserAndRetrieveDataWithEmailAndPassword(email, pass); + + // Update user profile + await firebase.auth().currentUser.updateProfile({ + displayName, + photoURL, + }); + + // Assertions + const user = firebase.auth().currentUser; + user.should.be.an.Object(); + user.email.should.equal(email.toLowerCase()); + user.displayName.should.equal(displayName); + user.photoURL.should.equal(photoURL); + + // Clean up + await firebase.auth().currentUser.delete(); + }); + }); + + describe('linkWithPhoneNumber()', () => { + it('should throw an unsupported error', async () => { + await firebase.auth().signInAnonymouslyAndRetrieveData(); + (() => { + firebase.auth().currentUser.linkWithPhoneNumber(); + }).should.throw( + 'User.linkWithPhoneNumber() is unsupported by the native Firebase SDKs.' + ); + await firebase.auth().signOut(); + }); + }); + + describe('linkWithPopup()', () => { + it('should throw an unsupported error', async () => { + await firebase.auth().signInAnonymouslyAndRetrieveData(); + (() => { + firebase.auth().currentUser.linkWithPopup(); + }).should.throw( + 'User.linkWithPopup() is unsupported by the native Firebase SDKs.' + ); + await firebase.auth().signOut(); + }); + }); + + describe('linkWithRedirect()', () => { + it('should throw an unsupported error', async () => { + await firebase.auth().signInAnonymouslyAndRetrieveData(); + (() => { + firebase.auth().currentUser.linkWithRedirect(); + }).should.throw( + 'User.linkWithRedirect() is unsupported by the native Firebase SDKs.' + ); + await firebase.auth().signOut(); + }); + }); + + describe('reauthenticateWithPhoneNumber()', () => { + it('should throw an unsupported error', async () => { + await firebase.auth().signInAnonymouslyAndRetrieveData(); + (() => { + firebase.auth().currentUser.reauthenticateWithPhoneNumber(); + }).should.throw( + 'User.reauthenticateWithPhoneNumber() is unsupported by the native Firebase SDKs.' + ); + await firebase.auth().signOut(); + }); + }); + + describe('reauthenticateWithPopup()', () => { + it('should throw an unsupported error', async () => { + await firebase.auth().signInAnonymouslyAndRetrieveData(); + (() => { + firebase.auth().currentUser.reauthenticateWithPopup(); + }).should.throw( + 'User.reauthenticateWithPopup() is unsupported by the native Firebase SDKs.' + ); + await firebase.auth().signOut(); + }); + }); + + describe('reauthenticateWithRedirect()', () => { + it('should throw an unsupported error', async () => { + await firebase.auth().signInAnonymouslyAndRetrieveData(); + (() => { + firebase.auth().currentUser.reauthenticateWithRedirect(); + }).should.throw( + 'User.reauthenticateWithRedirect() is unsupported by the native Firebase SDKs.' + ); + await firebase.auth().signOut(); + }); + }); + + describe('updatePhoneNumber()', () => { + it('should throw an unsupported error', async () => { + await firebase.auth().signInAnonymouslyAndRetrieveData(); + (() => { + firebase.auth().currentUser.updatePhoneNumber(); + }).should.throw( + 'User.updatePhoneNumber() is unsupported by the native Firebase SDKs.' + ); + await firebase.auth().signOut(); + }); + }); + + describe('refreshToken', () => { + it('should throw an unsupported error', async () => { + await firebase.auth().signInAnonymouslyAndRetrieveData(); + (() => firebase.auth().currentUser.refreshToken).should.throw( + 'User.refreshToken is unsupported by the native Firebase SDKs.' + ); + await firebase.auth().signOut(); + }); + }); +}); diff --git a/bridge/e2e/init.js b/bridge/e2e/init.js index ec663762..f4684061 100755 --- a/bridge/e2e/init.js +++ b/bridge/e2e/init.js @@ -23,3 +23,16 @@ global.sleep = duration => new Promise(resolve => { setTimeout(resolve, duration); }); + +global.randomString = (length, chars) => { + let mask = ''; + if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz'; + if (chars.indexOf('A') > -1) mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + if (chars.indexOf('#') > -1) mask += '0123456789'; + if (chars.indexOf('!') > -1) mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\'; + let result = ''; + for (let i = length; i > 0; --i) { + result += mask[Math.round(Math.random() * (mask.length - 1))]; + } + return result; +};