Add some additional authTests

This commit is contained in:
Chris Bianca 2018-03-01 18:01:11 +00:00
parent fdd8df6966
commit 8160431811
3 changed files with 1315 additions and 1114 deletions

View File

@ -15,8 +15,9 @@ const randomString = (length, chars) => {
return result;
};
export default (authTests = ({ tryCatch, describe, it, firebase }) => {
describe('onAuthStateChanged', () => {
export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
describe('auth()', () => {
context('onAuthStateChanged', () => {
it('calls callback with the current user and when auth state changes', async () => {
await firebase.native.auth().signInAnonymously();
@ -100,7 +101,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('onIdTokenChanged', () => {
context('onIdTokenChanged', () => {
it('calls callback with the current user and when auth state changes', async () => {
await firebase.native.auth().signInAnonymously();
@ -184,7 +185,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('onUserChanged', () => {
context('onUserChanged', () => {
it('calls callback with the current user and when auth state changes', async () => {
await firebase.native.auth().signInAnonymously();
@ -274,7 +275,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('signInAnonymously', () => {
context('signInAnonymously', () => {
it('it should sign in anonymously', () => {
const successCb = currentUser => {
currentUser.should.be.an.Object();
@ -296,7 +297,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('signInAnonymouslyAndRetrieveData', () => {
context('signInAnonymouslyAndRetrieveData', () => {
it('it should sign in anonymously', () => {
const successCb = currentUserCredential => {
const currentUser = currentUserCredential.user;
@ -321,207 +322,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('linkWithCredential', () => {
it('it should link anonymous account <-> email account', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
const pass = random;
const successCb = currentUser => {
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
firebase.native.auth().currentUser.uid.should.be.a.String();
const credential = firebase.native.auth.EmailAuthProvider.credential(
email,
pass
);
return currentUser
.linkWithCredential(credential)
.then(linkedUser => {
linkedUser.should.be.an.Object();
linkedUser.should.equal(firebase.native.auth().currentUser);
linkedUser.uid.should.be.a.String();
linkedUser.toJSON().should.be.an.Object();
// iOS and Android are inconsistent in returning lowercase / mixed case
linkedUser
.toJSON()
.email.toLowerCase()
.should.eql(email.toLowerCase());
linkedUser.isAnonymous.should.equal(false);
linkedUser.providerId.should.equal('firebase');
return firebase.native.auth().signOut();
})
.catch(error =>
firebase.native
.auth()
.signOut()
.then(() => Promise.reject(error))
);
};
return firebase.native
.auth()
.signInAnonymously()
.then(successCb);
});
it('it should error on link anon <-> email if email already exists', () => {
const email = 'test@test.com';
const pass = 'test1234';
const successCb = currentUser => {
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
firebase.native.auth().currentUser.uid.should.be.a.String();
const credential = firebase.native.auth.EmailAuthProvider.credential(
email,
pass
);
return currentUser
.linkWithCredential(credential)
.then(() =>
firebase.native
.auth()
.signOut()
.then(() => Promise.reject(new Error('Did not error on link')))
)
.catch(error =>
firebase.native
.auth()
.signOut()
.then(() => {
error.code.should.equal('auth/email-already-in-use');
error.message.should.equal(
'The email address is already in use by another account.'
);
return Promise.resolve();
})
);
};
return firebase.native
.auth()
.signInAnonymously()
.then(successCb);
});
});
describe('linkAndRetrieveDataWithCredential', () => {
it('it should link anonymous account <-> email account', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
const pass = random;
const successCb = currentUser => {
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
firebase.native.auth().currentUser.uid.should.be.a.String();
const credential = firebase.native.auth.EmailAuthProvider.credential(
email,
pass
);
return currentUser
.linkAndRetrieveDataWithCredential(credential)
.then(linkedUserCredential => {
linkedUserCredential.should.be.an.Object();
const linkedUser = linkedUserCredential.user;
linkedUser.should.be.an.Object();
linkedUser.should.equal(firebase.native.auth().currentUser);
linkedUser.uid.should.be.a.String();
linkedUser.toJSON().should.be.an.Object();
// iOS and Android are inconsistent in returning lowercase / mixed case
linkedUser
.toJSON()
.email.toLowerCase()
.should.eql(email.toLowerCase());
linkedUser.isAnonymous.should.equal(false);
linkedUser.providerId.should.equal('firebase');
// TODO: iOS is incorrect, passes on Android
// const additionalUserInfo = linkedUserCredential.additionalUserInfo;
// additionalUserInfo.should.be.an.Object();
// additionalUserInfo.isNewUser.should.equal(false);
return firebase.native.auth().signOut();
})
.catch(error =>
firebase.native
.auth()
.signOut()
.then(() => Promise.reject(error))
);
};
return firebase.native
.auth()
.signInAnonymously()
.then(successCb);
});
it('it should error on link anon <-> email if email already exists', () => {
const email = 'test@test.com';
const pass = 'test1234';
const successCb = currentUser => {
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
firebase.native.auth().currentUser.uid.should.be.a.String();
const credential = firebase.native.auth.EmailAuthProvider.credential(
email,
pass
);
return currentUser
.linkAndRetrieveDataWithCredential(credential)
.then(() =>
firebase.native
.auth()
.signOut()
.then(() => Promise.reject(new Error('Did not error on link')))
)
.catch(error =>
firebase.native
.auth()
.signOut()
.then(() => {
error.code.should.equal('auth/email-already-in-use');
error.message.should.equal(
'The email address is already in use by another account.'
);
return Promise.resolve();
})
);
};
return firebase.native
.auth()
.signInAnonymously()
.then(successCb);
});
});
describe('signInWithEmailAndPassword', () => {
context('signInWithEmailAndPassword', () => {
it('it should login with email and password', () => {
const email = 'test@test.com';
const pass = 'test1234';
@ -608,7 +409,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('signInAndRetrieveDataWithEmailAndPassword', () => {
context('signInAndRetrieveDataWithEmailAndPassword', () => {
it('it should login with email and password', () => {
const email = 'test@test.com';
const pass = 'test1234';
@ -700,7 +501,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('signInWithCredential', () => {
context('signInWithCredential', () => {
it('it should login with email and password', () => {
const credential = firebase.native.auth.EmailAuthProvider.credential(
'test@test.com',
@ -795,7 +596,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('signInAndRetrieveDataWithCredential', () => {
context('signInAndRetrieveDataWithCredential', () => {
it('it should login with email and password', () => {
const credential = firebase.native.auth.EmailAuthProvider.credential(
'test@test.com',
@ -895,7 +696,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('createUserWithEmailAndPassword', () => {
context('createUserWithEmailAndPassword', () => {
it('it should create a user with an email and password', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
@ -978,7 +779,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('createUserAndRetrieveDataWithEmailAndPassword', () => {
context('createUserAndRetrieveDataWithEmailAndPassword', () => {
it('it should create a user with an email and password', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
@ -1065,7 +866,7 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
});
});
describe('fetchProvidersForEmail', () => {
context('fetchProvidersForEmail', () => {
it('it should return password provider for an email address', () =>
new Promise((resolve, reject) => {
const successCb = tryCatch(providers => {
@ -1124,8 +925,8 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
}));
});
describe('Misc', () => {
it('it should delete a user', () => {
context('delete()', () => {
it('should delete a user', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
const pass = random;
@ -1144,61 +945,9 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
.createUserWithEmailAndPassword(email, pass)
.then(successCb);
});
it('it should return a token via getIdToken', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
const pass = random;
const successCb = newUser => {
newUser.uid.should.be.a.String();
newUser.email.should.equal(email.toLowerCase());
newUser.emailVerified.should.equal(false);
newUser.isAnonymous.should.equal(false);
newUser.providerId.should.equal('firebase');
return newUser.getIdToken().then(token => {
token.should.be.a.String();
token.length.should.be.greaterThan(24);
return firebase.native.auth().currentUser.delete();
});
};
return firebase.native
.auth()
.createUserWithEmailAndPassword(email, pass)
.then(successCb);
});
it('it should reject signOut if no currentUser', () =>
new Promise((resolve, reject) => {
if (firebase.native.auth().currentUser) {
return reject(
new Error(
`A user is currently signed in. ${
firebase.native.auth().currentUser.uid
}`
)
);
}
const successCb = tryCatch(() => {
reject(new Error('No signOut error returned'));
}, reject);
const failureCb = tryCatch(error => {
error.code.should.equal('auth/no-current-user');
error.message.should.equal('No user currently signed in.');
resolve();
}, reject);
return firebase.native
.auth()
.signOut()
.then(successCb)
.catch(failureCb);
}));
context('languageCode', () => {
it('it should change the language code', () => {
// eslint-disable-next-line no-param-reassign
firebase.native.auth().languageCode = 'en';
@ -1214,4 +963,55 @@ export default (authTests = ({ tryCatch, describe, it, firebase }) => {
firebase.native.auth().languageCode = 'en';
});
});
context('getRedirectResult', () => {
it('should throw an unsupported error', () => {
(() => {
firebase.native.auth().getRedirectResult();
}).should.throw(
'firebase.auth().getRedirectResult() is unsupported by the native Firebase SDKs.'
);
});
});
context('setPersistence', () => {
it('should throw an unsupported error', () => {
(() => {
firebase.native.auth().setPersistence();
}).should.throw(
'firebase.auth().setPersistence() is unsupported by the native Firebase SDKs.'
);
});
});
context('signInWithPopup', () => {
it('should throw an unsupported error', () => {
(() => {
firebase.native.auth().signInWithPopup();
}).should.throw(
'firebase.auth().signInWithPopup() is unsupported by the native Firebase SDKs.'
);
});
});
context('signInWithRedirect', () => {
it('should throw an unsupported error', () => {
(() => {
firebase.native.auth().signInWithRedirect();
}).should.throw(
'firebase.auth().signInWithRedirect() is unsupported by the native Firebase SDKs.'
);
});
});
context('useDeviceLanguage', () => {
it('should throw an unsupported error', () => {
(() => {
firebase.native.auth().useDeviceLanguage();
}).should.throw(
'firebase.auth().useDeviceLanguage() is unsupported by the native Firebase SDKs.'
);
});
});
});
});

View File

@ -2,9 +2,11 @@ import firebase from '../../firebase';
import TestSuite from '../../../lib/TestSuite';
import authTests from './authTests';
import userTests from './userTests';
const suite = new TestSuite('Auth', 'firebase.auth()', firebase);
suite.addTests(authTests);
suite.addTests(userTests);
export default suite;

View File

@ -0,0 +1,399 @@
import should from 'should';
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;
};
export default (userTests = ({ tryCatch, context, describe, it, firebase }) => {
describe('User', () => {
context('getIdToken()', () => {
it('should return a token', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
const pass = random;
const successCb = newUser => {
newUser.uid.should.be.a.String();
newUser.email.should.equal(email.toLowerCase());
newUser.emailVerified.should.equal(false);
newUser.isAnonymous.should.equal(false);
newUser.providerId.should.equal('firebase');
return newUser.getIdToken().then(token => {
token.should.be.a.String();
token.length.should.be.greaterThan(24);
return firebase.native.auth().currentUser.delete();
});
};
return firebase.native
.auth()
.createUserWithEmailAndPassword(email, pass)
.then(successCb);
});
});
context('getToken()', () => {
it('should return a token', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
const pass = random;
const successCb = newUser => {
newUser.uid.should.be.a.String();
newUser.email.should.equal(email.toLowerCase());
newUser.emailVerified.should.equal(false);
newUser.isAnonymous.should.equal(false);
newUser.providerId.should.equal('firebase');
return newUser.getToken().then(token => {
token.should.be.a.String();
token.length.should.be.greaterThan(24);
return firebase.native.auth().currentUser.delete();
});
};
return firebase.native
.auth()
.createUserWithEmailAndPassword(email, pass)
.then(successCb);
});
});
context('linkWithCredential()', () => {
it('it should link anonymous account <-> email account', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
const pass = random;
const successCb = currentUser => {
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
firebase.native.auth().currentUser.uid.should.be.a.String();
const credential = firebase.native.auth.EmailAuthProvider.credential(
email,
pass
);
return currentUser
.linkWithCredential(credential)
.then(linkedUser => {
linkedUser.should.be.an.Object();
linkedUser.should.equal(firebase.native.auth().currentUser);
linkedUser.uid.should.be.a.String();
linkedUser.toJSON().should.be.an.Object();
// iOS and Android are inconsistent in returning lowercase / mixed case
linkedUser
.toJSON()
.email.toLowerCase()
.should.eql(email.toLowerCase());
linkedUser.isAnonymous.should.equal(false);
linkedUser.providerId.should.equal('firebase');
return firebase.native.auth().signOut();
})
.catch(error =>
firebase.native
.auth()
.signOut()
.then(() => Promise.reject(error))
);
};
return firebase.native
.auth()
.signInAnonymously()
.then(successCb);
});
it('it should error on link anon <-> email if email already exists', () => {
const email = 'test@test.com';
const pass = 'test1234';
const successCb = currentUser => {
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
firebase.native.auth().currentUser.uid.should.be.a.String();
const credential = firebase.native.auth.EmailAuthProvider.credential(
email,
pass
);
return currentUser
.linkWithCredential(credential)
.then(() =>
firebase.native
.auth()
.signOut()
.then(() => Promise.reject(new Error('Did not error on link')))
)
.catch(error =>
firebase.native
.auth()
.signOut()
.then(() => {
error.code.should.equal('auth/email-already-in-use');
error.message.should.equal(
'The email address is already in use by another account.'
);
return Promise.resolve();
})
);
};
return firebase.native
.auth()
.signInAnonymously()
.then(successCb);
});
});
context('linkAndRetrieveDataWithCredential()', () => {
it('it should link anonymous account <-> email account', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
const pass = random;
const successCb = currentUser => {
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
firebase.native.auth().currentUser.uid.should.be.a.String();
const credential = firebase.native.auth.EmailAuthProvider.credential(
email,
pass
);
return currentUser
.linkAndRetrieveDataWithCredential(credential)
.then(linkedUserCredential => {
linkedUserCredential.should.be.an.Object();
const linkedUser = linkedUserCredential.user;
linkedUser.should.be.an.Object();
linkedUser.should.equal(firebase.native.auth().currentUser);
linkedUser.uid.should.be.a.String();
linkedUser.toJSON().should.be.an.Object();
// iOS and Android are inconsistent in returning lowercase / mixed case
linkedUser
.toJSON()
.email.toLowerCase()
.should.eql(email.toLowerCase());
linkedUser.isAnonymous.should.equal(false);
linkedUser.providerId.should.equal('firebase');
// TODO: iOS is incorrect, passes on Android
// const additionalUserInfo = linkedUserCredential.additionalUserInfo;
// additionalUserInfo.should.be.an.Object();
// additionalUserInfo.isNewUser.should.equal(false);
return firebase.native.auth().signOut();
})
.catch(error =>
firebase.native
.auth()
.signOut()
.then(() => Promise.reject(error))
);
};
return firebase.native
.auth()
.signInAnonymously()
.then(successCb);
});
it('it should error on link anon <-> email if email already exists', () => {
const email = 'test@test.com';
const pass = 'test1234';
const successCb = currentUser => {
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
firebase.native.auth().currentUser.uid.should.be.a.String();
const credential = firebase.native.auth.EmailAuthProvider.credential(
email,
pass
);
return currentUser
.linkAndRetrieveDataWithCredential(credential)
.then(() =>
firebase.native
.auth()
.signOut()
.then(() => Promise.reject(new Error('Did not error on link')))
)
.catch(error =>
firebase.native
.auth()
.signOut()
.then(() => {
error.code.should.equal('auth/email-already-in-use');
error.message.should.equal(
'The email address is already in use by another account.'
);
return Promise.resolve();
})
);
};
return firebase.native
.auth()
.signInAnonymously()
.then(successCb);
});
});
context('signOut()', () => {
it('it should reject signOut if no currentUser', () =>
new Promise((resolve, reject) => {
if (firebase.native.auth().currentUser) {
return reject(
new Error(
`A user is currently signed in. ${
firebase.native.auth().currentUser.uid
}`
)
);
}
const successCb = tryCatch(() => {
reject(new Error('No signOut error returned'));
}, reject);
const failureCb = tryCatch(error => {
error.code.should.equal('auth/no-current-user');
error.message.should.equal('No user currently signed in.');
resolve();
}, reject);
return firebase.native
.auth()
.signOut()
.then(successCb)
.catch(failureCb);
}));
});
context('linkWithPhoneNumber()', () => {
it('should throw an unsupported error', async () => {
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
(() => {
firebase.native.auth().currentUser.linkWithPhoneNumber();
}).should.throw(
'User.linkWithPhoneNumber() is unsupported by the native Firebase SDKs.'
);
await firebase.native.auth().signOut();
});
});
context('linkWithPopup()', () => {
it('should throw an unsupported error', async () => {
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
(() => {
firebase.native.auth().currentUser.linkWithPopup();
}).should.throw(
'User.linkWithPopup() is unsupported by the native Firebase SDKs.'
);
await firebase.native.auth().signOut();
});
});
context('linkWithRedirect()', () => {
it('should throw an unsupported error', async () => {
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
(() => {
firebase.native.auth().currentUser.linkWithRedirect();
}).should.throw(
'User.linkWithRedirect() is unsupported by the native Firebase SDKs.'
);
await firebase.native.auth().signOut();
});
});
context('reauthenticateWithPhoneNumber()', () => {
it('should throw an unsupported error', async () => {
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
(() => {
firebase.native.auth().currentUser.reauthenticateWithPhoneNumber();
}).should.throw(
'User.reauthenticateWithPhoneNumber() is unsupported by the native Firebase SDKs.'
);
await firebase.native.auth().signOut();
});
});
context('reauthenticateWithPopup()', () => {
it('should throw an unsupported error', async () => {
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
(() => {
firebase.native.auth().currentUser.reauthenticateWithPopup();
}).should.throw(
'User.reauthenticateWithPopup() is unsupported by the native Firebase SDKs.'
);
await firebase.native.auth().signOut();
});
});
context('reauthenticateWithRedirect()', () => {
it('should throw an unsupported error', async () => {
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
(() => {
firebase.native.auth().currentUser.reauthenticateWithRedirect();
}).should.throw(
'User.reauthenticateWithRedirect() is unsupported by the native Firebase SDKs.'
);
await firebase.native.auth().signOut();
});
});
context('updatePhoneNumber()', () => {
it('should throw an unsupported error', async () => {
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
(() => {
firebase.native.auth().currentUser.updatePhoneNumber();
}).should.throw(
'User.updatePhoneNumber() is unsupported by the native Firebase SDKs.'
);
await firebase.native.auth().signOut();
});
});
context('refreshToken', () => {
it('should throw an unsupported error', async () => {
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
(() => {
firebase.native.auth().currentUser.refreshToken;
}).should.throw(
'User.refreshToken is unsupported by the native Firebase SDKs.'
);
await firebase.native.auth().signOut();
});
});
});
});