Skip to content

Commit ed56680

Browse files
committed
More integration tests
1 parent 0ac48bb commit ed56680

File tree

8 files changed

+234
-12
lines changed

8 files changed

+234
-12
lines changed

packages-exp/auth-exp/test/integration/flows/custom.local.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
Auth,
2020
createUserWithEmailAndPassword,
2121
EmailAuthProvider,
22+
getAdditionalUserInfo,
2223
linkWithCredential,
2324
OperationType,
2425
reload,
@@ -73,6 +74,9 @@ describe('Integration test: custom auth', () => {
7374
'some-claim'
7475
);
7576
expect(user.providerId).to.eq('firebase');
77+
const additionalUserInfo = await getAdditionalUserInfo(cred)!;
78+
expect(additionalUserInfo.providerId).to.be.null;
79+
expect(additionalUserInfo.isNewUser).to.be.true;
7680
});
7781

7882
it('uid will overwrite existing user, joining accounts', async () => {
@@ -128,6 +132,20 @@ describe('Integration test: custom auth', () => {
128132
expect(user.photoURL).to.eq('photo-url');
129133
});
130134

135+
it('token can be refreshed', async () => {
136+
const { user } = await signInWithCustomToken(auth, customToken);
137+
const origToken = await user.getIdToken();
138+
await new Promise(resolve => setTimeout(resolve, 1000));
139+
expect(await user.getIdToken(true)).not.to.eq(origToken);
140+
});
141+
142+
it('signing in will not override anonymous user', async () => {
143+
const { user: anonUser } = await signInAnonymously(auth);
144+
const { user: customUser } = await signInWithCustomToken(auth, customToken);
145+
expect(auth.currentUser).to.eql(customUser);
146+
expect(customUser.uid).not.to.eql(anonUser.uid);
147+
});
148+
131149
context('email/password interaction', () => {
132150
let email: string;
133151
let customToken: string;

packages-exp/auth-exp/test/integration/flows/email.test.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ import {
2727
updateProfile,
2828
Auth,
2929
OperationType,
30-
UserCredential
30+
UserCredential,
31+
getAdditionalUserInfo
3132
// eslint-disable-next-line import/no-extraneous-dependencies
3233
} from '@firebase/auth-exp';
3334
import { FirebaseError } from '@firebase/util';
@@ -64,6 +65,13 @@ describe('Integration test: email/password auth', () => {
6465
expect(user.uid).to.be.a('string');
6566
expect(user.email).to.eq(email);
6667
expect(user.emailVerified).to.be.false;
68+
expect(user.providerData.length).to.eq(1);
69+
expect(user.providerData[0].providerId).to.eq('password');
70+
expect(user.providerData[0].email).to.eq(email);
71+
72+
const additionalUserInfo = getAdditionalUserInfo(userCred)!;
73+
expect(additionalUserInfo.isNewUser).to.be.true;
74+
expect(additionalUserInfo.providerId).to.eq('password');
6775
});
6876

6977
it('errors when createUser called twice', async () => {
@@ -95,6 +103,9 @@ describe('Integration test: email/password auth', () => {
95103

96104
expect(signInCred.operationType).to.eq(OperationType.SIGN_IN);
97105
expect(signInCred.user.uid).to.eq(signUpCred.user.uid);
106+
const additionalUserInfo = getAdditionalUserInfo(signInCred)!;
107+
expect(additionalUserInfo.isNewUser).to.be.false;
108+
expect(additionalUserInfo.providerId).to.eq('password');
98109
});
99110

100111
it('allows the user to sign in with signInWithCredential', async () => {
@@ -104,6 +115,9 @@ describe('Integration test: email/password auth', () => {
104115

105116
expect(signInCred.operationType).to.eq(OperationType.SIGN_IN);
106117
expect(signInCred.user.uid).to.eq(signUpCred.user.uid);
118+
const additionalUserInfo = getAdditionalUserInfo(signInCred)!;
119+
expect(additionalUserInfo.isNewUser).to.be.false;
120+
expect(additionalUserInfo.providerId).to.eq('password');
107121
});
108122

109123
it('allows the user to update profile', async () => {

packages-exp/auth-exp/test/integration/flows/phone.test.ts

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ describe('Integration test: phone auth', () => {
8282
document.body.removeChild(fakeRecaptchaContainer);
8383
});
8484

85+
function resetVerifier(): void {
86+
verifier.clear();
87+
verifier = new RecaptchaVerifier(
88+
fakeRecaptchaContainer,
89+
undefined as any,
90+
auth
91+
);
92+
}
93+
8594
/** If in the emulator, search for the code in the API */
8695
async function code(
8796
crOrId: ConfirmationResult | string,
@@ -126,17 +135,40 @@ describe('Integration test: phone auth', () => {
126135
expect(auth.currentUser!.phoneNumber).to.be.null;
127136
});
128137

129-
context('with already-created user', () => {
130-
let signUpCred: UserCredential;
138+
it('anonymous users can upgrade using phone number', async () => {
139+
const { user } = await signInAnonymously(auth);
140+
const { uid: anonId } = user;
131141

132-
function resetVerifier(): void {
133-
verifier.clear();
134-
verifier = new RecaptchaVerifier(
135-
fakeRecaptchaContainer,
136-
undefined as any,
137-
auth
142+
const provider = new PhoneAuthProvider(auth);
143+
const verificationId = await provider.verifyPhoneNumber(
144+
PHONE_B.phoneNumber,
145+
verifier
138146
);
139-
}
147+
148+
await updatePhoneNumber(
149+
user,
150+
PhoneAuthProvider.credential(
151+
verificationId,
152+
await code(verificationId, PHONE_B.code)
153+
)
154+
);
155+
expect(user.phoneNumber).to.eq(PHONE_B.phoneNumber);
156+
157+
await auth.signOut();
158+
resetVerifier();
159+
160+
const cr = await signInWithPhoneNumber(auth, PHONE_B.phoneNumber, verifier);
161+
const { user: secondSignIn } = await cr.confirm(
162+
await code(cr, PHONE_B.code)
163+
);
164+
expect(secondSignIn.uid).to.eq(anonId);
165+
expect(secondSignIn.isAnonymous).to.be.false;
166+
expect(secondSignIn.providerData[0].phoneNumber).to.eq(PHONE_B.phoneNumber);
167+
expect(secondSignIn.providerData[0].providerId).to.eq('phone');
168+
});
169+
170+
context('with already-created user', () => {
171+
let signUpCred: UserCredential;
140172

141173
beforeEach(async () => {
142174
const cr = await signInWithPhoneNumber(

packages-exp/auth-exp/test/integration/webdriver/popup.test.ts

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { expect, use } from 'chai';
2626
import { IdPPage } from './util/idp_page';
2727
import * as chaiAsPromised from 'chai-as-promised';
2828
import { browserDescribe } from './util/test_runner';
29-
import { AnonFunction, CoreFunction, PopupFunction } from './util/functions';
29+
import { AnonFunction, CoreFunction, EmailFunction, PopupFunction } from './util/functions';
3030

3131
use(chaiAsPromised);
3232

@@ -146,6 +146,79 @@ browserDescribe('Popup IdP tests', driver => {
146146
]);
147147
});
148148

149+
it('does not auto-upgrade anon accounts', async () => {
150+
const {user: anonUser}: UserCredential = await driver.call(AnonFunction.SIGN_IN_ANONYMOUSLY);
151+
await driver.callNoWait(PopupFunction.IDP_POPUP);
152+
await driver.selectPopupWindow();
153+
const widget = new IdPPage(driver.webDriver);
154+
await widget.pageLoad();
155+
await widget.clickAddAccount();
156+
await widget.fillEmail('[email protected]');
157+
await widget.clickSignIn();
158+
159+
// On redirect, check that the signed in user is different
160+
await driver.selectMainWindow();
161+
const curUser = await driver.getUserSnapshot();
162+
expect(curUser.uid).not.to.eq(anonUser.uid);
163+
});
164+
165+
it('linking with anonymous user upgrades account', async () => {
166+
const {user: anonUser}: UserCredential = await driver.call(AnonFunction.SIGN_IN_ANONYMOUSLY);
167+
await driver.callNoWait(PopupFunction.IDP_LINK_POPUP);
168+
await driver.selectPopupWindow();
169+
const widget = new IdPPage(driver.webDriver);
170+
await widget.pageLoad();
171+
await widget.clickAddAccount();
172+
await widget.fillEmail('[email protected]');
173+
await widget.clickSignIn();
174+
175+
// On redirect, check that the signed in user is upgraded
176+
await driver.selectMainWindow();
177+
const curUser = await driver.getUserSnapshot();
178+
expect(curUser.uid).to.eq(anonUser.uid);
179+
expect(curUser.isAnonymous).to.be.false;
180+
});
181+
182+
it('is possible to link with different email', async () => {
183+
const {user: emailUser}: UserCredential = await driver.call(EmailFunction.CREATE_USER, '[email protected]');
184+
185+
// Link using pre-poulated user
186+
await driver.callNoWait(PopupFunction.IDP_LINK_POPUP);
187+
await driver.selectPopupWindow();
188+
const widget = new IdPPage(driver.webDriver);
189+
await widget.pageLoad();
190+
await widget.clickAddAccount();
191+
await widget.fillEmail('[email protected]');
192+
await widget.clickSignIn();
193+
194+
// Check the linked account
195+
await driver.selectMainWindow();
196+
const curUser = await driver.getUserSnapshot();
197+
expect(curUser.uid).to.eq(emailUser.uid);
198+
expect(curUser.emailVerified).to.be.false;
199+
expect(curUser.providerData.length).to.eq(2);
200+
});
201+
202+
it('is possible to link with the same email', async () => {
203+
const {user: emailUser}: UserCredential = await driver.call(EmailFunction.CREATE_USER, '[email protected]');
204+
205+
// Link using pre-poulated user
206+
await driver.callNoWait(PopupFunction.IDP_LINK_POPUP);
207+
await driver.selectPopupWindow();
208+
const widget = new IdPPage(driver.webDriver);
209+
await widget.pageLoad();
210+
await widget.clickAddAccount();
211+
await widget.fillEmail('[email protected]');
212+
await widget.clickSignIn();
213+
214+
// Check the linked account
215+
await driver.selectMainWindow();
216+
const curUser = await driver.getUserSnapshot();
217+
expect(curUser.uid).to.eq(emailUser.uid);
218+
expect(curUser.emailVerified).to.be.true;
219+
expect(curUser.providerData.length).to.eq(2);
220+
});
221+
149222
context('with existing user', () => {
150223
let user1: User;
151224
let user2: User;

packages-exp/auth-exp/test/integration/webdriver/redirect.test.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { expect, use } from 'chai';
2626
import { IdPPage } from './util/idp_page';
2727
import * as chaiAsPromised from 'chai-as-promised';
2828
import { browserDescribe } from './util/test_runner';
29-
import { AnonFunction, CoreFunction, RedirectFunction } from './util/functions';
29+
import { AnonFunction, CoreFunction, EmailFunction, RedirectFunction } from './util/functions';
3030

3131
use(chaiAsPromised);
3232

@@ -146,6 +146,77 @@ browserDescribe('WebDriver redirect IdP test', driver => {
146146
]);
147147
});
148148

149+
it('does not auto-upgrade anon accounts', async () => {
150+
const {user: anonUser}: UserCredential = await driver.call(AnonFunction.SIGN_IN_ANONYMOUSLY);
151+
await driver.callNoWait(RedirectFunction.IDP_REDIRECT);
152+
const widget = new IdPPage(driver.webDriver);
153+
await widget.pageLoad();
154+
await widget.clickAddAccount();
155+
await widget.fillEmail('[email protected]');
156+
await widget.clickSignIn();
157+
158+
// On redirect, check that the signed in user is different
159+
await driver.reinitOnRedirect();
160+
const curUser = await driver.getUserSnapshot();
161+
expect(curUser.uid).not.to.eq(anonUser.uid);
162+
});
163+
164+
it('linking with anonymous user upgrades account', async () => {
165+
const {user: anonUser}: UserCredential = await driver.call(AnonFunction.SIGN_IN_ANONYMOUSLY);
166+
await driver.callNoWait(RedirectFunction.IDP_LINK_REDIRECT);
167+
const widget = new IdPPage(driver.webDriver);
168+
await widget.pageLoad();
169+
await widget.clickAddAccount();
170+
await widget.fillEmail('[email protected]');
171+
await widget.clickSignIn();
172+
173+
// On redirect, check that the signed in user is upgraded
174+
await driver.reinitOnRedirect();
175+
const curUser = await driver.getUserSnapshot();
176+
expect(curUser.uid).to.eq(anonUser.uid);
177+
expect(curUser.isAnonymous).to.be.false;
178+
});
179+
180+
it('is possible to link with different email', async () => {
181+
const {user: emailUser}: UserCredential = await driver.call(EmailFunction.CREATE_USER, '[email protected]');
182+
183+
// Link using pre-poulated user
184+
await driver.callNoWait(RedirectFunction.IDP_LINK_REDIRECT);
185+
186+
const widget = new IdPPage(driver.webDriver);
187+
await widget.pageLoad();
188+
await widget.clickAddAccount();
189+
await widget.fillEmail('[email protected]');
190+
await widget.clickSignIn();
191+
192+
// Check the linked account
193+
await driver.reinitOnRedirect();
194+
const curUser = await driver.getUserSnapshot();
195+
expect(curUser.uid).to.eq(emailUser.uid);
196+
expect(curUser.emailVerified).to.be.false;
197+
expect(curUser.providerData.length).to.eq(2);
198+
});
199+
200+
it('is possible to link with the same email', async () => {
201+
const {user: emailUser}: UserCredential = await driver.call(EmailFunction.CREATE_USER, '[email protected]');
202+
203+
// Link using pre-poulated user
204+
await driver.callNoWait(RedirectFunction.IDP_LINK_REDIRECT);
205+
206+
const widget = new IdPPage(driver.webDriver);
207+
await widget.pageLoad();
208+
await widget.clickAddAccount();
209+
await widget.fillEmail('[email protected]');
210+
await widget.clickSignIn();
211+
212+
// Check the linked account
213+
await driver.reinitOnRedirect();
214+
const curUser = await driver.getUserSnapshot();
215+
expect(curUser.uid).to.eq(emailUser.uid);
216+
expect(curUser.emailVerified).to.be.true;
217+
expect(curUser.providerData.length).to.eq(2);
218+
});
219+
149220
context('with existing user', () => {
150221
let user1: User;
151222
let user2: User;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { createUserWithEmailAndPassword } from '@firebase/auth-exp';
2+
3+
const TEST_PASSWORD = 'password';
4+
5+
export function createUser(email) {
6+
return createUserWithEmailAndPassword(auth, email, TEST_PASSWORD);
7+
}

packages-exp/auth-exp/test/integration/webdriver/static/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ import * as redirect from './redirect';
1919
import * as anonymous from './anonymous';
2020
import * as core from './core';
2121
import * as popup from './popup';
22+
import * as email from './email';
2223
import { initializeApp } from '@firebase/app-exp';
2324
import { getAuth, useAuthEmulator } from '@firebase/auth-exp';
2425

2526
window.core = { ...core };
2627
window.anonymous = { ...anonymous };
2728
window.redirect = { ...redirect };
2829
window.popup = { ...popup };
30+
window.email = { ...email };
2931

3032
// The config and emulator URL are injected by the test. The test framework
3133
// calls this function after that injection.

packages-exp/auth-exp/test/integration/webdriver/util/functions.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ export enum PopupFunction {
4646
TRY_TO_SIGN_IN_UNVERIFIED = 'popup.tryToSignInUnverified'
4747
}
4848

49+
/** Available email functions. See static/email.js */
50+
export enum EmailFunction {
51+
CREATE_USER = 'email.createUser',
52+
}
53+
4954
/** Available core functions within the browser. See static/core.js */
5055
export enum CoreFunction {
5156
RESET = 'core.reset',

0 commit comments

Comments
 (0)