Merge branch 'master' into firestore-transactions
This commit is contained in:
commit
f1a7a13587
@ -1060,6 +1060,15 @@ class RNFirebaseAuth extends ReactContextBaseJavaModule {
|
|||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void reauthenticateWithCredential(String appName, String provider, String authToken, String authSecret, final Promise promise) {
|
public void reauthenticateWithCredential(String appName, String provider, String authToken, String authSecret, final Promise promise) {
|
||||||
|
reauthenticate(appName, provider, authToken, authSecret, promise, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void reauthenticateAndRetrieveDataWithCredential(String appName, String provider, String authToken, String authSecret, final Promise promise) {
|
||||||
|
reauthenticate(appName, provider, authToken, authSecret, promise, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reauthenticate(String appName, String provider, String authToken, String authSecret, final Promise promise, final boolean withData) {
|
||||||
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
|
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
|
||||||
final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp);
|
final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp);
|
||||||
|
|
||||||
@ -1072,13 +1081,17 @@ class RNFirebaseAuth extends ReactContextBaseJavaModule {
|
|||||||
Log.d(TAG, "reauthenticate");
|
Log.d(TAG, "reauthenticate");
|
||||||
|
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
user.reauthenticate(credential)
|
user.reauthenticateAndRetrieveData(credential)
|
||||||
.addOnCompleteListener(new OnCompleteListener<Void>() {
|
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(@NonNull Task<Void> task) {
|
public void onComplete(@NonNull Task<AuthResult> task) {
|
||||||
if (task.isSuccessful()) {
|
if (task.isSuccessful()) {
|
||||||
Log.d(TAG, "reauthenticate:onComplete:success");
|
Log.d(TAG, "reauthenticate:onComplete:success");
|
||||||
promiseWithUser(firebaseAuth.getCurrentUser(), promise);
|
if (withData) {
|
||||||
|
promiseWithAuthResult(task.getResult(), promise);
|
||||||
|
} else {
|
||||||
|
promiseWithUser(task.getResult().getUser(), promise);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Exception exception = task.getException();
|
Exception exception = task.getException();
|
||||||
Log.e(TAG, "reauthenticate:onComplete:failure", exception);
|
Log.e(TAG, "reauthenticate:onComplete:failure", exception);
|
||||||
|
@ -940,18 +940,12 @@ RCT_EXPORT_METHOD(unlink:
|
|||||||
@param RCTPromiseRejectBlock reject
|
@param RCTPromiseRejectBlock reject
|
||||||
@return
|
@return
|
||||||
*/
|
*/
|
||||||
RCT_EXPORT_METHOD(reauthenticateWithCredential:
|
RCT_EXPORT_METHOD(reauthenticateWithCredential:(NSString *) appDisplayName
|
||||||
(NSString *) appDisplayName
|
provider:(NSString *) provider
|
||||||
provider:
|
authToken:(NSString *) authToken
|
||||||
(NSString *) provider
|
authSecret:(NSString *) authSecret
|
||||||
authToken:
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
(NSString *) authToken
|
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||||
authSecret:
|
|
||||||
(NSString *) authSecret
|
|
||||||
resolver:
|
|
||||||
(RCTPromiseResolveBlock) resolve
|
|
||||||
rejecter:
|
|
||||||
(RCTPromiseRejectBlock) reject) {
|
|
||||||
FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName];
|
FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName];
|
||||||
|
|
||||||
FIRAuthCredential *credential = [self getCredentialForProvider:provider token:authToken secret:authSecret];
|
FIRAuthCredential *credential = [self getCredentialForProvider:provider token:authToken secret:authSecret];
|
||||||
@ -976,6 +970,45 @@ RCT_EXPORT_METHOD(reauthenticateWithCredential:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
reauthenticateAndRetrieveDataWithCredential
|
||||||
|
|
||||||
|
@param NSString provider
|
||||||
|
@param NSString authToken
|
||||||
|
@param NSString authSecret
|
||||||
|
@param RCTPromiseResolveBlock resolve
|
||||||
|
@param RCTPromiseRejectBlock reject
|
||||||
|
@return
|
||||||
|
*/
|
||||||
|
RCT_EXPORT_METHOD(reauthenticateAndRetrieveDataWithCredential:(NSString *) appDisplayName
|
||||||
|
provider:(NSString *) provider
|
||||||
|
authToken:(NSString *) authToken
|
||||||
|
authSecret:(NSString *) authSecret
|
||||||
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
|
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||||
|
FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName];
|
||||||
|
|
||||||
|
FIRAuthCredential *credential = [self getCredentialForProvider:provider token:authToken secret:authSecret];
|
||||||
|
|
||||||
|
if (credential == nil) {
|
||||||
|
return reject(@"auth/invalid-credential", @"The supplied auth credential is malformed, has expired or is not currently supported.", nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
FIRUser *user = [FIRAuth authWithApp:firApp].currentUser;
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
[user reauthenticateAndRetrieveDataWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
|
||||||
|
if (error) {
|
||||||
|
[self promiseRejectAuthException:reject error:error];
|
||||||
|
} else {
|
||||||
|
[self promiseWithAuthResult:resolve rejecter:reject authResult:authResult];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
[self promiseNoUser:resolve rejecter:reject isError:YES];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
fetchProvidersForEmail
|
fetchProvidersForEmail
|
||||||
|
|
||||||
|
@ -322,7 +322,12 @@ export default class Query {
|
|||||||
// validate.isFieldPath('fieldPath', fieldPath);
|
// validate.isFieldPath('fieldPath', fieldPath);
|
||||||
// validate.isOptionalFieldOrder('directionStr', directionStr);
|
// validate.isOptionalFieldOrder('directionStr', directionStr);
|
||||||
|
|
||||||
if (this._queryOptions.startAt || this._queryOptions.endAt) {
|
if (
|
||||||
|
this._queryOptions.startAt ||
|
||||||
|
this._queryOptions.startAfter ||
|
||||||
|
this._queryOptions.endAt ||
|
||||||
|
this._queryOptions.endBefore
|
||||||
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Cannot specify an orderBy() constraint after calling ' +
|
'Cannot specify an orderBy() constraint after calling ' +
|
||||||
'startAt(), startAfter(), endBefore() or endAt().'
|
'startAt(), startAfter(), endBefore() or endAt().'
|
||||||
|
@ -19,7 +19,7 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
describe('auth()', () => {
|
describe('auth()', () => {
|
||||||
context('onAuthStateChanged', () => {
|
context('onAuthStateChanged', () => {
|
||||||
it('calls callback with the current user and when auth state changes', async () => {
|
it('calls callback with the current user and when auth state changes', async () => {
|
||||||
await firebase.native.auth().signInAnonymously();
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
const callback = sinon.spy();
|
const callback = sinon.spy();
|
||||||
@ -54,7 +54,7 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('stops listening when unsubscribed', async () => {
|
it('stops listening when unsubscribed', async () => {
|
||||||
await firebase.native.auth().signInAnonymously();
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
const callback = sinon.spy();
|
const callback = sinon.spy();
|
||||||
@ -89,7 +89,7 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
|
|
||||||
// Sign back in
|
// Sign back in
|
||||||
|
|
||||||
await firebase.native.auth().signInAnonymously();
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
|
||||||
// Assertions
|
// Assertions
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
|
|
||||||
context('onIdTokenChanged', () => {
|
context('onIdTokenChanged', () => {
|
||||||
it('calls callback with the current user and when auth state changes', async () => {
|
it('calls callback with the current user and when auth state changes', async () => {
|
||||||
await firebase.native.auth().signInAnonymously();
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
const callback = sinon.spy();
|
const callback = sinon.spy();
|
||||||
@ -138,7 +138,7 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('stops listening when unsubscribed', async () => {
|
it('stops listening when unsubscribed', async () => {
|
||||||
await firebase.native.auth().signInAnonymously();
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
const callback = sinon.spy();
|
const callback = sinon.spy();
|
||||||
@ -173,7 +173,7 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
|
|
||||||
// Sign back in
|
// Sign back in
|
||||||
|
|
||||||
await firebase.native.auth().signInAnonymously();
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
|
||||||
// Assertions
|
// Assertions
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
|
|
||||||
context('onUserChanged', () => {
|
context('onUserChanged', () => {
|
||||||
it('calls callback with the current user and when auth state changes', async () => {
|
it('calls callback with the current user and when auth state changes', async () => {
|
||||||
await firebase.native.auth().signInAnonymously();
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
const callback = sinon.spy();
|
const callback = sinon.spy();
|
||||||
@ -225,7 +225,7 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('stops listening when unsubscribed', async () => {
|
it('stops listening when unsubscribed', async () => {
|
||||||
await firebase.native.auth().signInAnonymously();
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
const callback = sinon.spy();
|
const callback = sinon.spy();
|
||||||
@ -263,7 +263,7 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
|
|
||||||
// Sign back in
|
// Sign back in
|
||||||
|
|
||||||
await firebase.native.auth().signInAnonymously();
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
|
||||||
// Assertions
|
// Assertions
|
||||||
|
|
||||||
@ -709,6 +709,10 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
newUser.isAnonymous.should.equal(false);
|
newUser.isAnonymous.should.equal(false);
|
||||||
newUser.providerId.should.equal('firebase');
|
newUser.providerId.should.equal('firebase');
|
||||||
newUser.should.equal(firebase.native.auth().currentUser);
|
newUser.should.equal(firebase.native.auth().currentUser);
|
||||||
|
newUser.metadata.should.be.an.Object();
|
||||||
|
should.equal(newUser.phoneNumber, null);
|
||||||
|
|
||||||
|
return newUser.delete();
|
||||||
};
|
};
|
||||||
|
|
||||||
return firebase.native
|
return firebase.native
|
||||||
@ -796,6 +800,8 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
const { additionalUserInfo } = newUserCredential;
|
const { additionalUserInfo } = newUserCredential;
|
||||||
additionalUserInfo.should.be.an.Object();
|
additionalUserInfo.should.be.an.Object();
|
||||||
additionalUserInfo.isNewUser.should.equal(true);
|
additionalUserInfo.isNewUser.should.equal(true);
|
||||||
|
|
||||||
|
return newUser.delete();
|
||||||
};
|
};
|
||||||
|
|
||||||
return firebase.native
|
return firebase.native
|
||||||
@ -925,6 +931,37 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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('delete()', () => {
|
context('delete()', () => {
|
||||||
it('should delete a user', () => {
|
it('should delete a user', () => {
|
||||||
const random = randomString(12, '#aA');
|
const random = randomString(12, '#aA');
|
||||||
@ -994,6 +1031,29 @@ export default (authTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
context('sendPasswordResetEmail()', () => {
|
||||||
|
it('should not error', async () => {
|
||||||
|
const random = randomString(12, '#aA');
|
||||||
|
const email = `${random}@${random}.com`;
|
||||||
|
const pass = random;
|
||||||
|
|
||||||
|
await firebase.native
|
||||||
|
.auth()
|
||||||
|
.createUserAndRetrieveDataWithEmailAndPassword(email, pass);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await firebase.native.auth().sendPasswordResetEmail(email);
|
||||||
|
await firebase.native.auth().currentUser.delete();
|
||||||
|
} catch (error) {
|
||||||
|
// Reject
|
||||||
|
await firebase.native.auth().currentUser.delete();
|
||||||
|
Promise.reject(
|
||||||
|
new Error('sendPasswordResetEmail() caused an error', error)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
context('signInWithRedirect', () => {
|
context('signInWithRedirect', () => {
|
||||||
it('should throw an unsupported error', () => {
|
it('should throw an unsupported error', () => {
|
||||||
(() => {
|
(() => {
|
||||||
|
@ -2,11 +2,13 @@ import firebase from '../../firebase';
|
|||||||
import TestSuite from '../../../lib/TestSuite';
|
import TestSuite from '../../../lib/TestSuite';
|
||||||
|
|
||||||
import authTests from './authTests';
|
import authTests from './authTests';
|
||||||
|
import providerTests from './providerTests';
|
||||||
import userTests from './userTests';
|
import userTests from './userTests';
|
||||||
|
|
||||||
const suite = new TestSuite('Auth', 'firebase.auth()', firebase);
|
const suite = new TestSuite('Auth', 'firebase.auth()', firebase);
|
||||||
|
|
||||||
suite.addTests(authTests);
|
suite.addTests(authTests);
|
||||||
|
suite.addTests(providerTests);
|
||||||
suite.addTests(userTests);
|
suite.addTests(userTests);
|
||||||
|
|
||||||
export default suite;
|
export default suite;
|
||||||
|
219
tests/src/tests/auth/providerTests.js
Normal file
219
tests/src/tests/auth/providerTests.js
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
export default (providerTests = ({ context, describe, it, firebase }) => {
|
||||||
|
describe('EmailAuthProvider', () => {
|
||||||
|
context('constructor', () => {
|
||||||
|
it('should throw an unsupported error', () => {
|
||||||
|
(() => new firebase.native.auth.EmailAuthProvider()).should.throw(
|
||||||
|
'`new EmailAuthProvider()` is not supported on the native Firebase SDKs.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('credential', () => {
|
||||||
|
it('should return a credential object', () => {
|
||||||
|
const email = 'email@email.com';
|
||||||
|
const password = 'password';
|
||||||
|
const credential = firebase.native.auth.EmailAuthProvider.credential(
|
||||||
|
email,
|
||||||
|
password
|
||||||
|
);
|
||||||
|
credential.providerId.should.equal('password');
|
||||||
|
credential.token.should.equal(email);
|
||||||
|
credential.secret.should.equal(password);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('PROVIDER_ID', () => {
|
||||||
|
it('should return password', () => {
|
||||||
|
firebase.native.auth.EmailAuthProvider.PROVIDER_ID.should.equal(
|
||||||
|
'password'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('FacebookAuthProvider', () => {
|
||||||
|
context('constructor', () => {
|
||||||
|
it('should throw an unsupported error', () => {
|
||||||
|
(() => new firebase.native.auth.FacebookAuthProvider()).should.throw(
|
||||||
|
'`new FacebookAuthProvider()` is not supported on the native Firebase SDKs.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('credential', () => {
|
||||||
|
it('should return a credential object', () => {
|
||||||
|
const token = '123456';
|
||||||
|
const credential = firebase.native.auth.FacebookAuthProvider.credential(
|
||||||
|
token
|
||||||
|
);
|
||||||
|
credential.providerId.should.equal('facebook.com');
|
||||||
|
credential.token.should.equal(token);
|
||||||
|
credential.secret.should.equal('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('PROVIDER_ID', () => {
|
||||||
|
it('should return facebook.com', () => {
|
||||||
|
firebase.native.auth.FacebookAuthProvider.PROVIDER_ID.should.equal(
|
||||||
|
'facebook.com'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GithubAuthProvider', () => {
|
||||||
|
context('constructor', () => {
|
||||||
|
it('should throw an unsupported error', () => {
|
||||||
|
(() => new firebase.native.auth.GithubAuthProvider()).should.throw(
|
||||||
|
'`new GithubAuthProvider()` is not supported on the native Firebase SDKs.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('credential', () => {
|
||||||
|
it('should return a credential object', () => {
|
||||||
|
const token = '123456';
|
||||||
|
const credential = firebase.native.auth.GithubAuthProvider.credential(
|
||||||
|
token
|
||||||
|
);
|
||||||
|
credential.providerId.should.equal('github.com');
|
||||||
|
credential.token.should.equal(token);
|
||||||
|
credential.secret.should.equal('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('PROVIDER_ID', () => {
|
||||||
|
it('should return github.com', () => {
|
||||||
|
firebase.native.auth.GithubAuthProvider.PROVIDER_ID.should.equal(
|
||||||
|
'github.com'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GoogleAuthProvider', () => {
|
||||||
|
context('constructor', () => {
|
||||||
|
it('should throw an unsupported error', () => {
|
||||||
|
(() => new firebase.native.auth.GoogleAuthProvider()).should.throw(
|
||||||
|
'`new GoogleAuthProvider()` is not supported on the native Firebase SDKs.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('credential', () => {
|
||||||
|
it('should return a credential object', () => {
|
||||||
|
const token = '123456';
|
||||||
|
const secret = '654321';
|
||||||
|
const credential = firebase.native.auth.GoogleAuthProvider.credential(
|
||||||
|
token,
|
||||||
|
secret
|
||||||
|
);
|
||||||
|
credential.providerId.should.equal('google.com');
|
||||||
|
credential.token.should.equal(token);
|
||||||
|
credential.secret.should.equal(secret);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('PROVIDER_ID', () => {
|
||||||
|
it('should return google.com', () => {
|
||||||
|
firebase.native.auth.GoogleAuthProvider.PROVIDER_ID.should.equal(
|
||||||
|
'google.com'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('OAuthProvider', () => {
|
||||||
|
context('constructor', () => {
|
||||||
|
it('should throw an unsupported error', () => {
|
||||||
|
(() => new firebase.native.auth.OAuthProvider()).should.throw(
|
||||||
|
'`new OAuthProvider()` is not supported on the native Firebase SDKs.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('credential', () => {
|
||||||
|
it('should return a credential object', () => {
|
||||||
|
const idToken = '123456';
|
||||||
|
const accessToken = '654321';
|
||||||
|
const credential = firebase.native.auth.OAuthProvider.credential(
|
||||||
|
idToken,
|
||||||
|
accessToken
|
||||||
|
);
|
||||||
|
credential.providerId.should.equal('oauth');
|
||||||
|
credential.token.should.equal(idToken);
|
||||||
|
credential.secret.should.equal(accessToken);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('PROVIDER_ID', () => {
|
||||||
|
it('should return oauth', () => {
|
||||||
|
firebase.native.auth.OAuthProvider.PROVIDER_ID.should.equal('oauth');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('PhoneAuthProvider', () => {
|
||||||
|
context('constructor', () => {
|
||||||
|
it('should throw an unsupported error', () => {
|
||||||
|
(() => new firebase.native.auth.PhoneAuthProvider()).should.throw(
|
||||||
|
'`new PhoneAuthProvider()` is not supported on the native Firebase SDKs.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('credential', () => {
|
||||||
|
it('should return a credential object', () => {
|
||||||
|
const verificationId = '123456';
|
||||||
|
const code = '654321';
|
||||||
|
const credential = firebase.native.auth.PhoneAuthProvider.credential(
|
||||||
|
verificationId,
|
||||||
|
code
|
||||||
|
);
|
||||||
|
credential.providerId.should.equal('phone');
|
||||||
|
credential.token.should.equal(verificationId);
|
||||||
|
credential.secret.should.equal(code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('PROVIDER_ID', () => {
|
||||||
|
it('should return phone', () => {
|
||||||
|
firebase.native.auth.PhoneAuthProvider.PROVIDER_ID.should.equal(
|
||||||
|
'phone'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('TwitterAuthProvider', () => {
|
||||||
|
context('constructor', () => {
|
||||||
|
it('should throw an unsupported error', () => {
|
||||||
|
(() => new firebase.native.auth.TwitterAuthProvider()).should.throw(
|
||||||
|
'`new TwitterAuthProvider()` is not supported on the native Firebase SDKs.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('credential', () => {
|
||||||
|
it('should return a credential object', () => {
|
||||||
|
const token = '123456';
|
||||||
|
const secret = '654321';
|
||||||
|
const credential = firebase.native.auth.TwitterAuthProvider.credential(
|
||||||
|
token,
|
||||||
|
secret
|
||||||
|
);
|
||||||
|
credential.providerId.should.equal('twitter.com');
|
||||||
|
credential.token.should.equal(token);
|
||||||
|
credential.secret.should.equal(secret);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('PROVIDER_ID', () => {
|
||||||
|
it('should return twitter.com', () => {
|
||||||
|
firebase.native.auth.TwitterAuthProvider.PROVIDER_ID.should.equal(
|
||||||
|
'twitter.com'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,5 +1,3 @@
|
|||||||
import should from 'should';
|
|
||||||
|
|
||||||
const randomString = (length, chars) => {
|
const randomString = (length, chars) => {
|
||||||
let mask = '';
|
let mask = '';
|
||||||
if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz';
|
if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz';
|
||||||
@ -13,291 +11,400 @@ const randomString = (length, chars) => {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default (userTests = ({ tryCatch, context, describe, it, firebase }) => {
|
export default (userTests = ({ context, describe, it, firebase }) => {
|
||||||
describe('User', () => {
|
describe('User', () => {
|
||||||
context('getIdToken()', () => {
|
context('getIdToken()', () => {
|
||||||
it('should return a token', () => {
|
it('should return a token', async () => {
|
||||||
const random = randomString(12, '#aA');
|
const random = randomString(12, '#aA');
|
||||||
const email = `${random}@${random}.com`;
|
const email = `${random}@${random}.com`;
|
||||||
const pass = random;
|
const pass = random;
|
||||||
|
|
||||||
const successCb = newUser => {
|
const newUser = await firebase.native
|
||||||
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()
|
.auth()
|
||||||
.createUserWithEmailAndPassword(email, pass)
|
.createUserWithEmailAndPassword(email, pass);
|
||||||
.then(successCb);
|
|
||||||
|
// Test
|
||||||
|
const token = await newUser.getIdToken();
|
||||||
|
|
||||||
|
// Assertions
|
||||||
|
token.should.be.a.String();
|
||||||
|
token.length.should.be.greaterThan(24);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
await firebase.native.auth().currentUser.delete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('getToken()', () => {
|
context('getToken()', () => {
|
||||||
it('should return a token', () => {
|
it('should return a token', async () => {
|
||||||
const random = randomString(12, '#aA');
|
const random = randomString(12, '#aA');
|
||||||
const email = `${random}@${random}.com`;
|
const email = `${random}@${random}.com`;
|
||||||
const pass = random;
|
const pass = random;
|
||||||
|
|
||||||
const successCb = newUser => {
|
const newUser = await firebase.native
|
||||||
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()
|
.auth()
|
||||||
.createUserWithEmailAndPassword(email, pass)
|
.createUserWithEmailAndPassword(email, pass);
|
||||||
.then(successCb);
|
|
||||||
|
// Test
|
||||||
|
const token = await newUser.getToken();
|
||||||
|
|
||||||
|
// Assertions
|
||||||
|
token.should.be.a.String();
|
||||||
|
token.length.should.be.greaterThan(24);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
await firebase.native.auth().currentUser.delete();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('linkWithCredential()', () => {
|
context('linkWithCredential()', () => {
|
||||||
it('it should link anonymous account <-> email account', () => {
|
it('should link anonymous account <-> email account', async () => {
|
||||||
const random = randomString(12, '#aA');
|
const random = randomString(12, '#aA');
|
||||||
const email = `${random}@${random}.com`;
|
const email = `${random}@${random}.com`;
|
||||||
const pass = random;
|
const pass = random;
|
||||||
|
|
||||||
const successCb = currentUser => {
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
currentUser.should.be.an.Object();
|
const currentUser = firebase.native.auth().currentUser;
|
||||||
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(
|
// Test
|
||||||
email,
|
const credential = firebase.native.auth.EmailAuthProvider.credential(
|
||||||
pass
|
email,
|
||||||
);
|
pass
|
||||||
|
);
|
||||||
|
|
||||||
return currentUser
|
const linkedUser = await currentUser.linkWithCredential(credential);
|
||||||
.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
|
// Assertions
|
||||||
.auth()
|
linkedUser.should.be.an.Object();
|
||||||
.signInAnonymously()
|
linkedUser.should.equal(firebase.native.auth().currentUser);
|
||||||
.then(successCb);
|
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.native.auth().currentUser.delete();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it should error on link anon <-> email if email already exists', () => {
|
it('should error on link anon <-> email if email already exists', async () => {
|
||||||
const email = 'test@test.com';
|
const email = 'test@test.com';
|
||||||
const pass = 'test1234';
|
const pass = 'test1234';
|
||||||
|
|
||||||
const successCb = currentUser => {
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
currentUser.should.be.an.Object();
|
const currentUser = firebase.native.auth().currentUser;
|
||||||
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();
|
|
||||||
|
|
||||||
|
// Test
|
||||||
|
try {
|
||||||
const credential = firebase.native.auth.EmailAuthProvider.credential(
|
const credential = firebase.native.auth.EmailAuthProvider.credential(
|
||||||
email,
|
email,
|
||||||
pass
|
pass
|
||||||
);
|
);
|
||||||
|
await currentUser.linkWithCredential(credential);
|
||||||
|
|
||||||
return currentUser
|
// Clean up
|
||||||
.linkWithCredential(credential)
|
await firebase.native.auth().signOut();
|
||||||
.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
|
// Reject
|
||||||
.auth()
|
Promise.reject(new Error('Did not error on link'));
|
||||||
.signInAnonymously()
|
} catch (error) {
|
||||||
.then(successCb);
|
// 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.native.auth().currentUser.delete();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('linkAndRetrieveDataWithCredential()', () => {
|
context('linkAndRetrieveDataWithCredential()', () => {
|
||||||
it('it should link anonymous account <-> email account', () => {
|
it('should link anonymous account <-> email account', async () => {
|
||||||
const random = randomString(12, '#aA');
|
const random = randomString(12, '#aA');
|
||||||
const email = `${random}@${random}.com`;
|
const email = `${random}@${random}.com`;
|
||||||
const pass = random;
|
const pass = random;
|
||||||
|
|
||||||
const successCb = currentUser => {
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
currentUser.should.be.an.Object();
|
const currentUser = firebase.native.auth().currentUser;
|
||||||
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(
|
// Test
|
||||||
email,
|
const credential = firebase.native.auth.EmailAuthProvider.credential(
|
||||||
pass
|
email,
|
||||||
);
|
pass
|
||||||
|
);
|
||||||
|
|
||||||
return currentUser
|
const linkedUserCredential = await currentUser.linkAndRetrieveDataWithCredential(
|
||||||
.linkAndRetrieveDataWithCredential(credential)
|
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
|
// Assertions
|
||||||
.auth()
|
const linkedUser = linkedUserCredential.user;
|
||||||
.signInAnonymously()
|
linkedUser.should.be.an.Object();
|
||||||
.then(successCb);
|
linkedUser.should.equal(firebase.native.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.native.auth().currentUser.delete();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it should error on link anon <-> email if email already exists', () => {
|
it('should error on link anon <-> email if email already exists', async () => {
|
||||||
const email = 'test@test.com';
|
const email = 'test@test.com';
|
||||||
const pass = 'test1234';
|
const pass = 'test1234';
|
||||||
|
|
||||||
const successCb = currentUser => {
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
currentUser.should.be.an.Object();
|
const currentUser = firebase.native.auth().currentUser;
|
||||||
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();
|
|
||||||
|
|
||||||
|
// Test
|
||||||
|
try {
|
||||||
const credential = firebase.native.auth.EmailAuthProvider.credential(
|
const credential = firebase.native.auth.EmailAuthProvider.credential(
|
||||||
email,
|
email,
|
||||||
pass
|
pass
|
||||||
);
|
);
|
||||||
|
await currentUser.linkAndRetrieveDataWithCredential(credential);
|
||||||
|
|
||||||
return currentUser
|
// Clean up
|
||||||
.linkAndRetrieveDataWithCredential(credential)
|
await firebase.native.auth().signOut();
|
||||||
.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
|
// Reject
|
||||||
.auth()
|
Promise.reject(new Error('Did not error on link'));
|
||||||
.signInAnonymously()
|
} catch (error) {
|
||||||
.then(successCb);
|
// 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.native.auth().currentUser.delete();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('signOut()', () => {
|
context('reauthenticateWithCredential()', () => {
|
||||||
it('it should reject signOut if no currentUser', () =>
|
it('should reauthenticate correctly', async () => {
|
||||||
new Promise((resolve, reject) => {
|
const random = randomString(12, '#aA');
|
||||||
if (firebase.native.auth().currentUser) {
|
const email = `${random}@${random}.com`;
|
||||||
return reject(
|
const pass = random;
|
||||||
new Error(
|
|
||||||
`A user is currently signed in. ${
|
|
||||||
firebase.native.auth().currentUser.uid
|
|
||||||
}`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const successCb = tryCatch(() => {
|
await firebase.native
|
||||||
reject(new Error('No signOut error returned'));
|
.auth()
|
||||||
}, reject);
|
.createUserAndRetrieveDataWithEmailAndPassword(email, pass);
|
||||||
|
|
||||||
const failureCb = tryCatch(error => {
|
// Test
|
||||||
error.code.should.equal('auth/no-current-user');
|
const credential = firebase.native.auth.EmailAuthProvider.credential(
|
||||||
error.message.should.equal('No user currently signed in.');
|
email,
|
||||||
resolve();
|
pass
|
||||||
}, reject);
|
);
|
||||||
|
await firebase.native
|
||||||
|
.auth()
|
||||||
|
.currentUser.reauthenticateWithCredential(credential);
|
||||||
|
|
||||||
return firebase.native
|
// Assertions
|
||||||
.auth()
|
const currentUser = firebase.native.auth().currentUser;
|
||||||
.signOut()
|
currentUser.email.should.equal(email.toLowerCase());
|
||||||
.then(successCb)
|
|
||||||
.catch(failureCb);
|
// Clean up
|
||||||
}));
|
await firebase.native.auth().currentUser.delete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('reauthenticateAndRetrieveDataWithCredential()', () => {
|
||||||
|
it('should reauthenticate correctly', async () => {
|
||||||
|
const random = randomString(12, '#aA');
|
||||||
|
const email = `${random}@${random}.com`;
|
||||||
|
const pass = random;
|
||||||
|
|
||||||
|
await firebase.native
|
||||||
|
.auth()
|
||||||
|
.createUserAndRetrieveDataWithEmailAndPassword(email, pass);
|
||||||
|
|
||||||
|
// Test
|
||||||
|
const credential = firebase.native.auth.EmailAuthProvider.credential(
|
||||||
|
email,
|
||||||
|
pass
|
||||||
|
);
|
||||||
|
await firebase.native
|
||||||
|
.auth()
|
||||||
|
.currentUser.reauthenticateAndRetrieveDataWithCredential(credential);
|
||||||
|
|
||||||
|
// Assertions
|
||||||
|
const currentUser = firebase.native.auth().currentUser;
|
||||||
|
currentUser.email.should.equal(email.toLowerCase());
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
await firebase.native.auth().currentUser.delete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('reload()', () => {
|
||||||
|
it('should not error', async () => {
|
||||||
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await firebase.native.auth().currentUser.reload();
|
||||||
|
await firebase.native.auth().signOut();
|
||||||
|
} catch (error) {
|
||||||
|
// Reject
|
||||||
|
await firebase.native.auth().signOut();
|
||||||
|
Promise.reject(new Error('reload() caused an error', error));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('sendEmailVerification()', () => {
|
||||||
|
it('should not error', async () => {
|
||||||
|
const random = randomString(12, '#aA');
|
||||||
|
const email = `${random}@${random}.com`;
|
||||||
|
const pass = random;
|
||||||
|
|
||||||
|
await firebase.native
|
||||||
|
.auth()
|
||||||
|
.createUserAndRetrieveDataWithEmailAndPassword(email, pass);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await firebase.native.auth().currentUser.sendEmailVerification();
|
||||||
|
await firebase.native.auth().currentUser.delete();
|
||||||
|
} catch (error) {
|
||||||
|
// Reject
|
||||||
|
await firebase.native.auth().currentUser.delete();
|
||||||
|
Promise.reject(
|
||||||
|
new Error('sendEmailVerification() caused an error', error)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('unlink()', () => {
|
||||||
|
it('should unlink the email address', async () => {
|
||||||
|
const random = randomString(12, '#aA');
|
||||||
|
const email = `${random}@${random}.com`;
|
||||||
|
const pass = random;
|
||||||
|
|
||||||
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
|
const currentUser = firebase.native.auth().currentUser;
|
||||||
|
|
||||||
|
const credential = firebase.native.auth.EmailAuthProvider.credential(
|
||||||
|
email,
|
||||||
|
pass
|
||||||
|
);
|
||||||
|
await currentUser.linkAndRetrieveDataWithCredential(credential);
|
||||||
|
|
||||||
|
// Test
|
||||||
|
await currentUser.unlink(
|
||||||
|
firebase.native.auth.EmailAuthProvider.PROVIDER_ID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assertions
|
||||||
|
const unlinkedUser = firebase.native.auth().currentUser;
|
||||||
|
unlinkedUser.providerData.should.be.an.Array();
|
||||||
|
unlinkedUser.providerData.length.should.equal(0);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
await firebase.native.auth().currentUser.delete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('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.native
|
||||||
|
.auth()
|
||||||
|
.createUserAndRetrieveDataWithEmailAndPassword(email, pass);
|
||||||
|
firebase.native
|
||||||
|
.auth()
|
||||||
|
.currentUser.email.toLowerCase()
|
||||||
|
.should.equal(email.toLowerCase());
|
||||||
|
|
||||||
|
// Update user email
|
||||||
|
await firebase.native.auth().currentUser.updateEmail(email2);
|
||||||
|
|
||||||
|
// Assertions
|
||||||
|
firebase.native
|
||||||
|
.auth()
|
||||||
|
.currentUser.email.toLowerCase()
|
||||||
|
.should.equal(email2.toLowerCase());
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
await firebase.native.auth().currentUser.delete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('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.native
|
||||||
|
.auth()
|
||||||
|
.createUserAndRetrieveDataWithEmailAndPassword(email, pass);
|
||||||
|
|
||||||
|
// Update user password
|
||||||
|
await firebase.native.auth().currentUser.updatePassword(pass2);
|
||||||
|
|
||||||
|
// Sign out
|
||||||
|
await firebase.native.auth().signOut();
|
||||||
|
|
||||||
|
// Log in with the new password
|
||||||
|
await firebase.native
|
||||||
|
.auth()
|
||||||
|
.signInAndRetrieveDataWithEmailAndPassword(email, pass2);
|
||||||
|
|
||||||
|
// Assertions
|
||||||
|
firebase.native.auth().currentUser.should.be.an.Object();
|
||||||
|
firebase.native
|
||||||
|
.auth()
|
||||||
|
.currentUser.email.should.equal(email.toLowerCase());
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
await firebase.native.auth().currentUser.delete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('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.native
|
||||||
|
.auth()
|
||||||
|
.createUserAndRetrieveDataWithEmailAndPassword(email, pass);
|
||||||
|
|
||||||
|
// Update user profile
|
||||||
|
await firebase.native.auth().currentUser.updateProfile({
|
||||||
|
displayName,
|
||||||
|
photoURL,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assertions
|
||||||
|
const user = firebase.native.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.native.auth().currentUser.delete();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('linkWithPhoneNumber()', () => {
|
context('linkWithPhoneNumber()', () => {
|
||||||
@ -387,9 +494,7 @@ export default (userTests = ({ tryCatch, context, describe, it, firebase }) => {
|
|||||||
context('refreshToken', () => {
|
context('refreshToken', () => {
|
||||||
it('should throw an unsupported error', async () => {
|
it('should throw an unsupported error', async () => {
|
||||||
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
await firebase.native.auth().signInAnonymouslyAndRetrieveData();
|
||||||
(() => {
|
(() => firebase.native.auth().currentUser.refreshToken).should.throw(
|
||||||
firebase.native.auth().currentUser.refreshToken;
|
|
||||||
}).should.throw(
|
|
||||||
'User.refreshToken is unsupported by the native Firebase SDKs.'
|
'User.refreshToken is unsupported by the native Firebase SDKs.'
|
||||||
);
|
);
|
||||||
await firebase.native.auth().signOut();
|
await firebase.native.auth().signOut();
|
||||||
|
@ -508,6 +508,13 @@ function collectionReferenceTests({
|
|||||||
}).should.throw(
|
}).should.throw(
|
||||||
'Query.onSnapshot failed: Observer.error must be a valid function.'
|
'Query.onSnapshot failed: Observer.error must be a valid function.'
|
||||||
);
|
);
|
||||||
|
(() => {
|
||||||
|
colRef.onSnapshot({
|
||||||
|
next: 'error',
|
||||||
|
});
|
||||||
|
}).should.throw(
|
||||||
|
'Query.onSnapshot failed: Observer.next must be a valid function.'
|
||||||
|
);
|
||||||
(() => {
|
(() => {
|
||||||
colRef.onSnapshot(
|
colRef.onSnapshot(
|
||||||
{
|
{
|
||||||
@ -1129,6 +1136,56 @@ function collectionReferenceTests({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
context('orderBy()', () => {
|
||||||
|
it('errors if called after startAt', () => {
|
||||||
|
(() => {
|
||||||
|
firebase.native
|
||||||
|
.firestore()
|
||||||
|
.collection('collections')
|
||||||
|
.startAt({})
|
||||||
|
.orderBy('test');
|
||||||
|
}).should.throw(
|
||||||
|
'Cannot specify an orderBy() constraint after calling startAt(), startAfter(), endBefore() or endAt().'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('errors if called after startAfter', () => {
|
||||||
|
(() => {
|
||||||
|
firebase.native
|
||||||
|
.firestore()
|
||||||
|
.collection('collections')
|
||||||
|
.startAfter({})
|
||||||
|
.orderBy('test');
|
||||||
|
}).should.throw(
|
||||||
|
'Cannot specify an orderBy() constraint after calling startAt(), startAfter(), endBefore() or endAt().'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('errors if called after endBefore', () => {
|
||||||
|
(() => {
|
||||||
|
firebase.native
|
||||||
|
.firestore()
|
||||||
|
.collection('collections')
|
||||||
|
.endBefore({})
|
||||||
|
.orderBy('test');
|
||||||
|
}).should.throw(
|
||||||
|
'Cannot specify an orderBy() constraint after calling startAt(), startAfter(), endBefore() or endAt().'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('errors if called after endAt', () => {
|
||||||
|
(() => {
|
||||||
|
firebase.native
|
||||||
|
.firestore()
|
||||||
|
.collection('collections')
|
||||||
|
.endAt({})
|
||||||
|
.orderBy('test');
|
||||||
|
}).should.throw(
|
||||||
|
'Cannot specify an orderBy() constraint after calling startAt(), startAfter(), endBefore() or endAt().'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
context('onSnapshot()', () => {
|
context('onSnapshot()', () => {
|
||||||
it('gets called correctly', async () => {
|
it('gets called correctly', async () => {
|
||||||
const collectionRef = collectionTests
|
const collectionRef = collectionTests
|
||||||
|
@ -126,6 +126,26 @@ function firestoreTests({ describe, it, context, fcontext, firebase }) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
context('disableNetwork()', () => {
|
||||||
|
it('should throw an unsupported error', () => {
|
||||||
|
(() => {
|
||||||
|
firebase.native.firestore().disableNetwork();
|
||||||
|
}).should.throw(
|
||||||
|
'firebase.firestore().disableNetwork() is unsupported by the native Firebase SDKs.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('enableNetwork()', () => {
|
||||||
|
it('should throw an unsupported error', () => {
|
||||||
|
(() => {
|
||||||
|
firebase.native.firestore().enableNetwork();
|
||||||
|
}).should.throw(
|
||||||
|
'firebase.firestore().enableNetwork() is unsupported by the native Firebase SDKs.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
context('enablePersistence()', () => {
|
context('enablePersistence()', () => {
|
||||||
it('should throw an unsupported error', () => {
|
it('should throw an unsupported error', () => {
|
||||||
(() => {
|
(() => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user