Delete Account unit tests: added tests related to Google reauthentication

This commit is contained in:
gianantoniopini
2021-05-20 15:57:01 +02:00
parent 7cb469657d
commit 9e63d0b2c7
18 changed files with 363 additions and 56 deletions

View File

@ -24,7 +24,7 @@ test('initializing data sets up resumes and users', async () => {
const resumesDataSnapshot = await resumesRef.once('value'); const resumesDataSnapshot = await resumesRef.once('value');
const resumes = resumesDataSnapshot.val(); const resumes = resumesDataSnapshot.val();
expect(resumes).toBeTruthy(); expect(resumes).toBeTruthy();
expect(Object.keys(resumes)).toHaveLength(3); expect(Object.keys(resumes)).toHaveLength(5);
const demoStateResume1 = resumes[DatabaseConstants.demoStateResume1Id]; const demoStateResume1 = resumes[DatabaseConstants.demoStateResume1Id];
expect(demoStateResume1).toBeTruthy(); expect(demoStateResume1).toBeTruthy();
expect(demoStateResume1.id).toEqual(DatabaseConstants.demoStateResume1Id); expect(demoStateResume1.id).toEqual(DatabaseConstants.demoStateResume1Id);
@ -33,20 +33,35 @@ test('initializing data sets up resumes and users', async () => {
expect(demoStateResume2).toBeTruthy(); expect(demoStateResume2).toBeTruthy();
expect(demoStateResume2.id).toEqual(DatabaseConstants.demoStateResume2Id); expect(demoStateResume2.id).toEqual(DatabaseConstants.demoStateResume2Id);
expect(demoStateResume2.user).toEqual(DatabaseConstants.user2.uid); expect(demoStateResume2.user).toEqual(DatabaseConstants.user2.uid);
const initialStateResume = resumes[DatabaseConstants.initialStateResumeId]; const initialStateResume1 = resumes[DatabaseConstants.initialStateResume1Id];
expect(initialStateResume).toBeTruthy(); expect(initialStateResume1).toBeTruthy();
expect(initialStateResume.id).toEqual(DatabaseConstants.initialStateResumeId); expect(initialStateResume1.id).toEqual(
expect(initialStateResume.user).toEqual(DatabaseConstants.user1.uid); DatabaseConstants.initialStateResume1Id,
);
expect(initialStateResume1.user).toEqual(DatabaseConstants.user1.uid);
const demoStateResume3 = resumes[DatabaseConstants.demoStateResume3Id];
expect(demoStateResume3).toBeTruthy();
expect(demoStateResume3.id).toEqual(DatabaseConstants.demoStateResume3Id);
expect(demoStateResume3.user).toEqual(DatabaseConstants.user3.uid);
const initialStateResume2 = resumes[DatabaseConstants.initialStateResume2Id];
expect(initialStateResume2).toBeTruthy();
expect(initialStateResume2.id).toEqual(
DatabaseConstants.initialStateResume2Id,
);
expect(initialStateResume2.user).toEqual(DatabaseConstants.user3.uid);
const usersRef = FirebaseStub.database().ref(DatabaseConstants.usersPath); const usersRef = FirebaseStub.database().ref(DatabaseConstants.usersPath);
const usersDataSnapshot = await usersRef.once('value'); const usersDataSnapshot = await usersRef.once('value');
const users = usersDataSnapshot.val(); const users = usersDataSnapshot.val();
expect(users).toBeTruthy(); expect(users).toBeTruthy();
expect(Object.keys(users)).toHaveLength(2); expect(Object.keys(users)).toHaveLength(3);
const anonymousUser1 = users[DatabaseConstants.user1.uid]; const anonymousUser1 = users[DatabaseConstants.user1.uid];
expect(anonymousUser1).toBeTruthy(); expect(anonymousUser1).toBeTruthy();
expect(anonymousUser1).toEqual(DatabaseConstants.user1); expect(anonymousUser1).toEqual(DatabaseConstants.user1);
const anonymousUser2 = users[DatabaseConstants.user2.uid]; const anonymousUser2 = users[DatabaseConstants.user2.uid];
expect(anonymousUser2).toBeTruthy(); expect(anonymousUser2).toBeTruthy();
expect(anonymousUser2).toEqual(DatabaseConstants.user2); expect(anonymousUser2).toEqual(DatabaseConstants.user2);
const googleUser3 = users[DatabaseConstants.user3.uid];
expect(googleUser3).toBeTruthy();
expect(googleUser3).toEqual(DatabaseConstants.user3);
}); });

View File

@ -1,4 +1,5 @@
import Auth from './gatsby-plugin-firebase/auth/auth'; import Auth from './gatsby-plugin-firebase/auth/auth';
import GoogleAuthProvider from './gatsby-plugin-firebase/auth/googleAuthProvider';
import Database from './gatsby-plugin-firebase/database/database'; import Database from './gatsby-plugin-firebase/database/database';
import Functions from './gatsby-plugin-firebase/functions/functions'; import Functions from './gatsby-plugin-firebase/functions/functions';
import AuthConstants from './gatsby-plugin-firebase/constants/auth'; import AuthConstants from './gatsby-plugin-firebase/constants/auth';
@ -19,6 +20,8 @@ class FirebaseStub {
} }
} }
FirebaseStub.auth.GoogleAuthProvider = GoogleAuthProvider;
FirebaseStub.database.ServerValue = {}; FirebaseStub.database.ServerValue = {};
Object.defineProperty(FirebaseStub.database.ServerValue, 'TIMESTAMP', { Object.defineProperty(FirebaseStub.database.ServerValue, 'TIMESTAMP', {
get() { get() {

View File

@ -2,6 +2,8 @@
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import Constants from '../constants/auth'; import Constants from '../constants/auth';
import AuthProvider from './authProvider';
import GoogleAuthProvider from './googleAuthProvider';
import User from './user'; import User from './user';
import { delay } from '../../../src/utils/index'; import { delay } from '../../../src/utils/index';
@ -55,8 +57,47 @@ class Auth {
this._currentUser = new User( this._currentUser = new User(
user.displayName, user.displayName,
user.email, user.email,
user.isAnonymous, user.providerId,
user.uid, user.uid,
user.isAnonymous,
this.signOut,
);
await delay(Constants.defaultDelayInMilliseconds);
this.onAuthStateChangedObservers.forEach((observer) =>
observer(this._currentUser),
);
return this._currentUser;
}
/**
* Authenticates with popup.
*
* @param {AuthProvider} provider The provider to authenticate.
*/
async signInWithPopup(provider) {
if (!provider) {
throw new Error('provider must be provided.');
} else if (!(provider instanceof AuthProvider)) {
throw new Error('provider should be an AuthProvider.');
}
if (!(provider instanceof GoogleAuthProvider)) {
throw new Error(
`${provider.constructor.name} is currently not supported.`,
);
}
const user = Constants.googleUser3;
this._currentUser = new User(
user.displayName,
user.email,
user.providerId,
user.uid,
user.isAnonymous,
this.signOut, this.signOut,
); );

View File

@ -0,0 +1,23 @@
/* eslint-disable no-underscore-dangle */
class AuthProvider {
/**
* Creates a new auth provider.
*
* @param {string} providerId Provider ID.
*/
constructor(providerId) {
if (!providerId) {
throw new Error('providerId must be provided.');
} else if (typeof providerId !== 'string') {
throw new Error('providerId should be a string.');
} else {
this._providerId = providerId;
}
}
get providerId() {
return this._providerId;
}
}
export default AuthProvider;

View File

@ -0,0 +1,10 @@
import AuthProvider from './authProvider';
import Constants from '../constants/auth';
class GoogleAuthProvider extends AuthProvider {
constructor() {
super(Constants.googleAuthProviderId);
}
}
export default GoogleAuthProvider;

View File

@ -1,25 +1,23 @@
/* eslint-disable no-underscore-dangle */ /* eslint-disable no-underscore-dangle */
import Constants from '../constants/auth'; import Constants from '../constants/auth';
// eslint-disable-next-line no-unused-vars
import AuthProvider from './authProvider';
import UserInfo from './userInfo';
import { delay } from '../../../src/utils/index'; import { delay } from '../../../src/utils/index';
class User { class User extends UserInfo {
/** /**
* Creates a new user. * Creates a new user.
* *
* @param {string|null} displayName Display name. * @param {string|null} displayName Display name.
* @param {string|null} email Email. * @param {string|null} email Email.
* @param {boolean} isAnonymous Is anonymous. * @param {string} providerId Auth provider ID.
* @param {string} uid The user's unique ID. * @param {string} uid The user's unique ID.
* @param {boolean} isAnonymous Is anonymous.
* @param {function():Promise<void>} deleteUser Delete user callback. * @param {function():Promise<void>} deleteUser Delete user callback.
*/ */
constructor(displayName, email, isAnonymous, uid, deleteUser) { constructor(displayName, email, providerId, uid, isAnonymous, deleteUser) {
if (!uid) { super(displayName, email, providerId, uid);
throw new Error('uid must be provided.');
} else if (typeof uid !== 'string') {
throw new Error('uid should be a string.');
} else {
this._uid = uid;
}
if (!deleteUser) { if (!deleteUser) {
throw new Error('deleteUser must be provided.'); throw new Error('deleteUser must be provided.');
@ -29,25 +27,22 @@ class User {
this._deleteUser = deleteUser; this._deleteUser = deleteUser;
} }
this._displayName = displayName;
this._email = email;
this._isAnonymous = isAnonymous; this._isAnonymous = isAnonymous;
}
get displayName() { this._providerData = [];
return this._displayName; if (!isAnonymous) {
} this._providerData.push(
new UserInfo(displayName, email, providerId, uid),
get email() { );
return this._email; }
} }
get isAnonymous() { get isAnonymous() {
return this._isAnonymous; return this._isAnonymous;
} }
get uid() { get providerData() {
return this._uid; return this._providerData;
} }
async delete() { async delete() {
@ -55,6 +50,18 @@ class User {
await this._deleteUser(); await this._deleteUser();
} }
/**
* Reauthenticates the user with popup.
*
* @param {AuthProvider} provider The provider to authenticate.
*/
// eslint-disable-next-line no-unused-vars
async reauthenticateWithPopup(provider) {
await delay(Constants.defaultDelayInMilliseconds);
return this;
}
} }
export default User; export default User;

View File

@ -0,0 +1,47 @@
/* eslint-disable no-underscore-dangle */
class UserInfo {
/**
* Creates a new user profile information.
*
* @param {string|null} displayName Display name.
* @param {string|null} email Email.
* @param {string} providerId Auth provider ID.
* @param {string} uid The user's unique ID.
*/
constructor(displayName, email, providerId, uid) {
if (!uid) {
throw new Error('uid must be provided.');
} else if (typeof uid !== 'string') {
throw new Error('uid should be a string.');
} else {
this._uid = uid;
}
if (typeof providerId !== 'string') {
throw new Error('providerId should be a string.');
} else {
this._providerId = providerId;
}
this._displayName = displayName;
this._email = email;
}
get displayName() {
return this._displayName;
}
get email() {
return this._email;
}
get providerId() {
return this._providerId;
}
get uid() {
return this._uid;
}
}
export default UserInfo;

View File

@ -1,20 +1,36 @@
const googleAuthProviderId = 'google.com';
const anonymousUser1 = { const anonymousUser1 = {
displayName: 'Anonymous User 1', displayName: 'Anonymous User 1',
email: 'anonymous1@noemail.com', email: 'anonymous1@noemail.com',
isAnonymous: true, isAnonymous: true,
uid: 'anonym123', providerId: '',
uid: 'anonym1',
}; };
const anonymousUser2 = { const anonymousUser2 = {
displayName: 'Anonymous User 2', displayName: 'Anonymous User 2',
email: 'anonymous2@noemail.com', email: 'anonymous2@noemail.com',
isAnonymous: true, isAnonymous: true,
uid: 'anonym456', providerId: '',
uid: 'anonym2',
};
const googleUser3 = {
displayName: 'Google User 3',
email: 'google3@noemail.com',
isAnonymous: false,
providerId: googleAuthProviderId,
uid: 'google3',
}; };
const defaultDelayInMilliseconds = 100; const defaultDelayInMilliseconds = 100;
class Auth { class Auth {
static get googleAuthProviderId() {
return googleAuthProviderId;
}
static get anonymousUser1() { static get anonymousUser1() {
return anonymousUser1; return anonymousUser1;
} }
@ -23,6 +39,10 @@ class Auth {
return anonymousUser2; return anonymousUser2;
} }
static get googleUser3() {
return googleUser3;
}
static get defaultDelayInMilliseconds() { static get defaultDelayInMilliseconds() {
return defaultDelayInMilliseconds; return defaultDelayInMilliseconds;
} }

View File

@ -9,7 +9,9 @@ const connectedPath = '.info/connected';
const demoStateResume1Id = 'demo_1'; const demoStateResume1Id = 'demo_1';
const demoStateResume2Id = 'demo_2'; const demoStateResume2Id = 'demo_2';
const initialStateResumeId = 'initst'; const demoStateResume3Id = 'demo_3';
const initialStateResume1Id = 'init_1';
const initialStateResume2Id = 'init_2';
const user1 = { const user1 = {
uid: AuthConstants.anonymousUser1.uid, uid: AuthConstants.anonymousUser1.uid,
@ -19,6 +21,10 @@ const user2 = {
uid: AuthConstants.anonymousUser2.uid, uid: AuthConstants.anonymousUser2.uid,
isAnonymous: AuthConstants.anonymousUser2.isAnonymous, isAnonymous: AuthConstants.anonymousUser2.isAnonymous,
}; };
const user3 = {
uid: AuthConstants.googleUser3.uid,
isAnonymous: AuthConstants.googleUser3.isAnonymous,
};
const defaultDelayInMilliseconds = 100; const defaultDelayInMilliseconds = 100;
@ -51,8 +57,16 @@ class Database {
return demoStateResume2Id; return demoStateResume2Id;
} }
static get initialStateResumeId() { static get demoStateResume3Id() {
return initialStateResumeId; return demoStateResume3Id;
}
static get initialStateResume1Id() {
return initialStateResume1Id;
}
static get initialStateResume2Id() {
return initialStateResume2Id;
} }
static get user1() { static get user1() {
@ -63,6 +77,10 @@ class Database {
return user2; return user2;
} }
static get user3() {
return user3;
}
static get defaultDelayInMilliseconds() { static get defaultDelayInMilliseconds() {
return defaultDelayInMilliseconds; return defaultDelayInMilliseconds;
} }

View File

@ -101,9 +101,9 @@ class Database {
initializeData() { initializeData() {
const resumes = {}; const resumes = {};
const date = new Date('December 15, 2020 11:20:25');
const demoStateResume1 = readFile('../../../src/data/demoState.json'); const demoStateResume1 = readFile('../../../src/data/demoState.json');
const date = new Date('December 15, 2020 11:20:25');
demoStateResume1.updatedAt = date.valueOf(); demoStateResume1.updatedAt = date.valueOf();
date.setMonth(date.getMonth() - 2); date.setMonth(date.getMonth() - 2);
demoStateResume1.createdAt = date.valueOf(); demoStateResume1.createdAt = date.valueOf();
@ -114,11 +114,24 @@ class Database {
demoStateResume2.user = DatabaseConstants.user2.uid; demoStateResume2.user = DatabaseConstants.user2.uid;
resumes[DatabaseConstants.demoStateResume2Id] = demoStateResume2; resumes[DatabaseConstants.demoStateResume2Id] = demoStateResume2;
const initialStateResume = readFile('../../../src/data/initialState.json'); const initialStateResume1 = readFile('../../../src/data/initialState.json');
initialStateResume.updatedAt = date.valueOf(); initialStateResume1.updatedAt = date.valueOf();
initialStateResume.createdAt = date.valueOf(); initialStateResume1.createdAt = date.valueOf();
initialStateResume.user = DatabaseConstants.user1.uid; initialStateResume1.user = DatabaseConstants.user1.uid;
resumes[DatabaseConstants.initialStateResumeId] = initialStateResume; resumes[DatabaseConstants.initialStateResume1Id] = initialStateResume1;
const demoStateResume3 = readFile('../../../src/data/demoState.json');
demoStateResume3.updatedAt = date.valueOf();
date.setMonth(date.getMonth() - 2);
demoStateResume3.createdAt = date.valueOf();
demoStateResume3.user = DatabaseConstants.user3.uid;
resumes[DatabaseConstants.demoStateResume3Id] = demoStateResume3;
const initialStateResume2 = readFile('../../../src/data/initialState.json');
initialStateResume2.updatedAt = date.valueOf();
initialStateResume2.createdAt = date.valueOf();
initialStateResume2.user = DatabaseConstants.user3.uid;
resumes[DatabaseConstants.initialStateResume2Id] = initialStateResume2;
Object.keys(resumes).forEach((key) => { Object.keys(resumes).forEach((key) => {
const resume = resumes[key]; const resume = resumes[key];
@ -131,6 +144,7 @@ class Database {
const users = {}; const users = {};
users[DatabaseConstants.user1.uid] = DatabaseConstants.user1; users[DatabaseConstants.user1.uid] = DatabaseConstants.user1;
users[DatabaseConstants.user2.uid] = DatabaseConstants.user2; users[DatabaseConstants.user2.uid] = DatabaseConstants.user2;
users[DatabaseConstants.user3.uid] = DatabaseConstants.user3;
this._data[DatabaseConstants.usersPath] = users; this._data[DatabaseConstants.usersPath] = users;
} }

View File

@ -7,13 +7,14 @@ import {
expectDatabaseUpdateToHaveCompleted, expectDatabaseUpdateToHaveCompleted,
} from './helpers/builder'; } from './helpers/builder';
const testTimeoutInMilliseconds = 20000; const testTimeoutInMilliseconds = 30000;
jest.setTimeout(testTimeoutInMilliseconds); jest.setTimeout(testTimeoutInMilliseconds);
test('when input value is changed, updates database', async () => { test('when input value is changed, updates database', async () => {
const resumeId = DatabaseConstants.demoStateResume1Id; const resumeId = DatabaseConstants.demoStateResume1Id;
const { mockDatabaseUpdateFunction } = await setupAndWait( const { mockDatabaseUpdateFunction } = await setupAndWait(
resumeId, resumeId,
false,
true, true,
true, true,
); );

View File

@ -20,6 +20,7 @@ jest.setTimeout(testTimeoutInMilliseconds);
test('renders first and last name', async () => { test('renders first and last name', async () => {
const { resume } = await setupAndWait( const { resume } = await setupAndWait(
DatabaseConstants.demoStateResume1Id, DatabaseConstants.demoStateResume1Id,
false,
true, true,
true, true,
); );
@ -53,7 +54,7 @@ test('renders loading screen', async () => {
}); });
test('if resume is in initial state, renders load demo data notification', async () => { test('if resume is in initial state, renders load demo data notification', async () => {
await setup(DatabaseConstants.initialStateResumeId); await setup(DatabaseConstants.initialStateResume1Id);
const notification = await screen.findByRole('alert'); const notification = await screen.findByRole('alert');
expect( expect(

View File

@ -14,9 +14,32 @@ import { delay } from '../../../utils/index';
const testTimeoutInMilliseconds = 60000; const testTimeoutInMilliseconds = 60000;
jest.setTimeout(testTimeoutInMilliseconds); jest.setTimeout(testTimeoutInMilliseconds);
async function setup() { async function setup(signInWithGoogle, failReauthentication) {
const resumeId = DatabaseConstants.demoStateResume1Id; const resumeId = signInWithGoogle
await setupAndWait(resumeId, true, true); ? DatabaseConstants.demoStateResume3Id
: DatabaseConstants.demoStateResume1Id;
await setupAndWait(resumeId, signInWithGoogle, true, true);
let mockFirebaseCurrentUserReauthenticateWithPopupErrorMessage;
let mockFirebaseCurrentUserReauthenticateWithPopup;
if (failReauthentication) {
mockFirebaseCurrentUserReauthenticateWithPopupErrorMessage =
'Error occurred while reauthenticating.';
mockFirebaseCurrentUserReauthenticateWithPopup = jest.fn(async () => {
await delay(AuthConstants.defaultDelayInMilliseconds);
throw new Error(
mockFirebaseCurrentUserReauthenticateWithPopupErrorMessage,
);
});
FirebaseStub.auth().currentUser.reauthenticateWithPopup = mockFirebaseCurrentUserReauthenticateWithPopup;
} else {
mockFirebaseCurrentUserReauthenticateWithPopupErrorMessage = null;
mockFirebaseCurrentUserReauthenticateWithPopup = jest.spyOn(
FirebaseStub.auth().currentUser,
'reauthenticateWithPopup',
);
}
const mockFirebaseDeleteUserCloudFunction = jest.fn(async () => { const mockFirebaseDeleteUserCloudFunction = jest.fn(async () => {
await delay(FunctionsConstants.defaultDelayInMilliseconds); await delay(FunctionsConstants.defaultDelayInMilliseconds);
@ -61,6 +84,8 @@ async function setup() {
areYouSureButtonText, areYouSureButtonText,
deleteAccountButtonText, deleteAccountButtonText,
waitForDeleteAccountButtonTextToChangeTo, waitForDeleteAccountButtonTextToChangeTo,
mockFirebaseCurrentUserReauthenticateWithPopup,
mockFirebaseCurrentUserReauthenticateWithPopupErrorMessage,
mockFirebaseDeleteUserCloudFunction, mockFirebaseDeleteUserCloudFunction,
mockFirebaseCurrentUserDelete, mockFirebaseCurrentUserDelete,
mockFirebaseAuthSignOut, mockFirebaseAuthSignOut,
@ -78,7 +103,7 @@ test('prompts for confirmation', async () => {
mockFirebaseCurrentUserDelete, mockFirebaseCurrentUserDelete,
mockFirebaseAuthSignOut, mockFirebaseAuthSignOut,
mockToastError, mockToastError,
} = await setup(); } = await setup(false, false);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
@ -98,7 +123,7 @@ test('calls Firebase delete user cloud function', async () => {
deleteAccountButtonText, deleteAccountButtonText,
mockFirebaseDeleteUserCloudFunction, mockFirebaseDeleteUserCloudFunction,
waitForDeleteAccountButtonTextToChangeTo, waitForDeleteAccountButtonTextToChangeTo,
} = await setup(); } = await setup(false, false);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
@ -116,7 +141,7 @@ test('calls Firebase current user delete', async () => {
deleteAccountButtonText, deleteAccountButtonText,
mockFirebaseCurrentUserDelete, mockFirebaseCurrentUserDelete,
waitForDeleteAccountButtonTextToChangeTo, waitForDeleteAccountButtonTextToChangeTo,
} = await setup(); } = await setup(false, false);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
@ -134,7 +159,7 @@ test('calls Firebase auth sign out', async () => {
deleteAccountButtonText, deleteAccountButtonText,
mockFirebaseAuthSignOut, mockFirebaseAuthSignOut,
waitForDeleteAccountButtonTextToChangeTo, waitForDeleteAccountButtonTextToChangeTo,
} = await setup(); } = await setup(false, false);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
@ -150,7 +175,7 @@ describe('if an error occurs while signing out the current user', () => {
deleteAccountButton, deleteAccountButton,
deleteAccountButtonText, deleteAccountButtonText,
waitForDeleteAccountButtonTextToChangeTo, waitForDeleteAccountButtonTextToChangeTo,
} = await setup(); } = await setup(false, false);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
@ -167,7 +192,7 @@ describe('if an error occurs while signing out the current user', () => {
mockFirebaseAuthSignOutErrorMessage, mockFirebaseAuthSignOutErrorMessage,
waitForDeleteAccountButtonTextToChangeTo, waitForDeleteAccountButtonTextToChangeTo,
mockToastError, mockToastError,
} = await setup(); } = await setup(false, false);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
fireEvent.click(deleteAccountButton); fireEvent.click(deleteAccountButton);
@ -185,3 +210,75 @@ describe('if an error occurs while signing out the current user', () => {
); );
}); });
}); });
describe('if the current user is signed in with Google', () => {
test('reauthenticates the user', async () => {
const googleAuthProvider = new FirebaseStub.auth.GoogleAuthProvider();
const {
deleteAccountButton,
deleteAccountButtonText,
mockFirebaseCurrentUserReauthenticateWithPopup,
waitForDeleteAccountButtonTextToChangeTo,
} = await setup(true, false);
fireEvent.click(deleteAccountButton);
fireEvent.click(deleteAccountButton);
await waitForDeleteAccountButtonTextToChangeTo(deleteAccountButtonText);
expect(
mockFirebaseCurrentUserReauthenticateWithPopup,
).toHaveBeenCalledTimes(1);
expect(mockFirebaseCurrentUserReauthenticateWithPopup).toHaveBeenCalledWith(
googleAuthProvider,
);
});
describe('and reauthentication fails', () => {
test('does not proceed further', async () => {
const {
deleteAccountButton,
deleteAccountButtonText,
waitForDeleteAccountButtonTextToChangeTo,
mockFirebaseDeleteUserCloudFunction,
mockFirebaseCurrentUserDelete,
mockFirebaseAuthSignOut,
} = await setup(true, true);
fireEvent.click(deleteAccountButton);
fireEvent.click(deleteAccountButton);
await waitForDeleteAccountButtonTextToChangeTo(deleteAccountButtonText);
expect(mockFirebaseDeleteUserCloudFunction).not.toHaveBeenCalled();
expect(mockFirebaseCurrentUserDelete).not.toHaveBeenCalled();
expect(mockFirebaseAuthSignOut).not.toHaveBeenCalled();
expect(mockNavigateFunction).not.toHaveBeenCalled();
});
test('displays error notifications', async () => {
const {
deleteAccountButton,
deleteAccountButtonText,
waitForDeleteAccountButtonTextToChangeTo,
mockFirebaseCurrentUserReauthenticateWithPopupErrorMessage,
mockToastError,
} = await setup(true, true);
fireEvent.click(deleteAccountButton);
fireEvent.click(deleteAccountButton);
await waitForDeleteAccountButtonTextToChangeTo(deleteAccountButtonText);
expect(mockToastError).toHaveBeenCalledTimes(2);
expect(mockToastError).toHaveBeenNthCalledWith(
1,
mockFirebaseCurrentUserReauthenticateWithPopupErrorMessage,
);
expect(mockToastError).toHaveBeenNthCalledWith(
2,
'An error occurred deleting your account.',
);
});
});
});

View File

@ -16,6 +16,7 @@ test('allows to change the language', async () => {
const resumeId = DatabaseConstants.demoStateResume1Id; const resumeId = DatabaseConstants.demoStateResume1Id;
const { mockDatabaseUpdateFunction } = await setupAndWait( const { mockDatabaseUpdateFunction } = await setupAndWait(
resumeId, resumeId,
false,
true, true,
true, true,
); );

View File

@ -19,6 +19,7 @@ test('allows to drag & drop', async () => {
const resumeId = DatabaseConstants.demoStateResume1Id; const resumeId = DatabaseConstants.demoStateResume1Id;
const { resume, mockDatabaseUpdateFunction } = await setupAndWait( const { resume, mockDatabaseUpdateFunction } = await setupAndWait(
resumeId, resumeId,
false,
true, true,
true, true,
); );

View File

@ -44,7 +44,7 @@ async function setup() {
); );
const resumeToDeleteId = resumeToDelete.id; const resumeToDeleteId = resumeToDelete.id;
const [undeletedResume] = Object.values(userResumes).filter( const [undeletedResume] = Object.values(userResumes).filter(
(resume) => resume.id === DatabaseConstants.initialStateResumeId, (resume) => resume.id === DatabaseConstants.initialStateResume1Id,
); );
const mockDatabaseRemoveFunction = jest.spyOn( const mockDatabaseRemoveFunction = jest.spyOn(

View File

@ -80,6 +80,7 @@ const dragAndDropListItem = (listItemElement, direction) => {
// eslint-disable-next-line no-underscore-dangle // eslint-disable-next-line no-underscore-dangle
async function _setup( async function _setup(
resumeId, resumeId,
signInWithGoogle,
waitForLoadingScreenToDisappear, waitForLoadingScreenToDisappear,
waitForDatabaseUpdateToHaveCompleted, waitForDatabaseUpdateToHaveCompleted,
) { ) {
@ -96,7 +97,12 @@ async function _setup(
'update', 'update',
); );
FirebaseStub.auth().signInAnonymously(); if (signInWithGoogle) {
const provider = new FirebaseStub.auth.GoogleAuthProvider();
FirebaseStub.auth().signInWithPopup(provider);
} else {
FirebaseStub.auth().signInAnonymously();
}
render( render(
<SettingsProvider> <SettingsProvider>
@ -132,17 +138,19 @@ async function _setup(
} }
async function setup(resumeId) { async function setup(resumeId) {
const returnValue = await _setup(resumeId, false, false); const returnValue = await _setup(resumeId, false, false, false);
return returnValue; return returnValue;
} }
async function setupAndWait( async function setupAndWait(
resumeId, resumeId,
signInWithGoogle,
waitForLoadingScreenToDisappear, waitForLoadingScreenToDisappear,
waitForDatabaseUpdateToHaveCompleted, waitForDatabaseUpdateToHaveCompleted,
) { ) {
const returnValue = await _setup( const returnValue = await _setup(
resumeId, resumeId,
signInWithGoogle,
waitForLoadingScreenToDisappear, waitForLoadingScreenToDisappear,
waitForDatabaseUpdateToHaveCompleted, waitForDatabaseUpdateToHaveCompleted,
); );

View File

@ -21,7 +21,7 @@ async function setup(resumeId) {
} }
test('renders correctly', async () => { test('renders correctly', async () => {
const resume = await setup(DatabaseConstants.initialStateResumeId); const resume = await setup(DatabaseConstants.initialStateResume1Id);
const { container } = render(<Castform data={resume} />); const { container } = render(<Castform data={resume} />);
@ -30,7 +30,7 @@ test('renders correctly', async () => {
}); });
test('date of birth is not shown if not provided', async () => { test('date of birth is not shown if not provided', async () => {
const resume = await setup(DatabaseConstants.initialStateResumeId); const resume = await setup(DatabaseConstants.initialStateResume1Id);
render(<Castform data={resume} />); render(<Castform data={resume} />);
@ -38,7 +38,7 @@ test('date of birth is not shown if not provided', async () => {
}); });
test('date of birth is shown if provided', async () => { test('date of birth is shown if provided', async () => {
const resume = await setup(DatabaseConstants.initialStateResumeId); const resume = await setup(DatabaseConstants.initialStateResume1Id);
const birthDate = new Date(1990, 0, 20); const birthDate = new Date(1990, 0, 20);
const birthDateFormatted = '20 January 1990'; const birthDateFormatted = '20 January 1990';