Jest mocks: added @reach/router and stub for Firebase auth signOut method

This commit is contained in:
gianantoniopini
2021-05-13 16:53:04 +02:00
parent ffb8ae45e0
commit d11d414504
5 changed files with 100 additions and 14 deletions

View File

@ -0,0 +1,17 @@
import { delay } from '../../src/utils/index';
const ReachRouter = jest.requireActual('@reach/router');
const defaultDelayInMilliseconds = 100;
// eslint-disable-next-line no-unused-vars
const navigate = async (to, options) => {
await delay(defaultDelayInMilliseconds);
return Promise.resolve();
};
module.exports = {
...ReachRouter,
navigate: jest.fn(navigate),
};

View File

@ -57,7 +57,7 @@ class Auth {
user.email, user.email,
user.isAnonymous, user.isAnonymous,
user.uid, user.uid,
async () => {}, this.signOut,
); );
await delay(Constants.defaultDelayInMilliseconds); await delay(Constants.defaultDelayInMilliseconds);
@ -68,6 +68,20 @@ class Auth {
return this._currentUser; return this._currentUser;
} }
async signOut() {
if (this._currentUser === null) {
return;
}
this._currentUser = null;
await delay(Constants.defaultDelayInMilliseconds);
this.onAuthStateChangedObservers.forEach((observer) =>
observer(this._currentUser),
);
}
} }
export default Auth; export default Auth;

View File

@ -1,6 +1,6 @@
const deleteUserFunctionName = 'deleteUser'; const deleteUserFunctionName = 'deleteUser';
const defaultDelayInMilliseconds = 2000; const defaultDelayInMilliseconds = 100;
class Functions { class Functions {
static get deleteUserFunctionName() { static get deleteUserFunctionName() {

View File

@ -1,8 +1,14 @@
import { fireEvent, screen } from '@testing-library/react'; import { navigate as mockNavigateFunction } from '@reach/router';
import { fireEvent, screen, waitFor } from '@testing-library/react';
import FirebaseStub, { DatabaseConstants } from 'gatsby-plugin-firebase'; import FirebaseStub, {
DatabaseConstants,
FunctionsConstants,
} from 'gatsby-plugin-firebase';
import { setupAndWait } from './helpers/builder'; import { delay } from '../../../utils/index';
import { setupAndWait, findAndDismissNotification } from './helpers/builder';
const testTimeoutInMilliseconds = 20000; const testTimeoutInMilliseconds = 20000;
jest.setTimeout(testTimeoutInMilliseconds); jest.setTimeout(testTimeoutInMilliseconds);
@ -11,37 +17,75 @@ async function setup() {
const resumeId = DatabaseConstants.demoStateResume1Id; const resumeId = DatabaseConstants.demoStateResume1Id;
await setupAndWait(resumeId, true, true); await setupAndWait(resumeId, true, true);
const button = screen.getByRole('button', { const mockFirebaseDeleteUserCloudFunction = jest.fn(async () => {
name: /Delete Account/i, await delay(FunctionsConstants.defaultDelayInMilliseconds);
}); });
const mockFirebaseFunctionsHttpsCallable = jest.fn((name) =>
name === FunctionsConstants.deleteUserFunctionName
? mockFirebaseDeleteUserCloudFunction
: undefined,
);
FirebaseStub.functions().httpsCallable = mockFirebaseFunctionsHttpsCallable;
const mockFirebaseUserDelete = jest.spyOn( const mockFirebaseCurrentUserDelete = jest.spyOn(
FirebaseStub.auth().currentUser, FirebaseStub.auth().currentUser,
'delete', 'delete',
); );
const button = screen.getByRole('button', {
name: /Delete Account/i,
});
return { return {
button, button,
mockFirebaseUserDelete, mockFirebaseCurrentUserDelete,
mockFirebaseDeleteUserCloudFunction,
}; };
} }
test('prompts for confirmation', async () => { test('prompts for confirmation', async () => {
const { button, mockFirebaseUserDelete } = await setup(); const {
button,
mockFirebaseDeleteUserCloudFunction,
mockFirebaseCurrentUserDelete,
} = await setup();
fireEvent.click(button); fireEvent.click(button);
expect(button).toHaveTextContent('Are you sure?'); expect(button).toHaveTextContent('Are you sure?');
expect(mockFirebaseUserDelete).not.toHaveBeenCalled();
await waitFor(() =>
expect(mockFirebaseDeleteUserCloudFunction).not.toHaveBeenCalledTimes(1),
);
await waitFor(() =>
expect(mockFirebaseCurrentUserDelete).not.toHaveBeenCalled(),
);
}); });
/* /*
test('calls Firebase user delete', async () => { test('calls Firebase delete user cloud function', async () => {
const { button, mockFirebaseUserDelete } = await setup(); const { button, mockFirebaseDeleteUserCloudFunction } = await setup();
fireEvent.click(button); fireEvent.click(button);
fireEvent.click(button); fireEvent.click(button);
expect(mockFirebaseUserDelete).toHaveBeenCalledTimes(1); await waitFor(() => expect(mockNavigateFunction).toHaveBeenCalledTimes(1));
await findAndDismissNotification();
await waitFor(() =>
expect(mockFirebaseDeleteUserCloudFunction).toHaveBeenCalledTimes(1),
);
});
test('calls Firebase current user delete', async () => {
const { button, mockFirebaseCurrentUserDelete } = await setup();
fireEvent.click(button);
fireEvent.click(button);
await waitFor(() => expect(mockNavigateFunction).toHaveBeenCalledTimes(1));
await findAndDismissNotification();
await waitFor(() =>
expect(mockFirebaseCurrentUserDelete).toHaveBeenCalledTimes(1),
);
}); });
*/ */

View File

@ -47,6 +47,15 @@ const expectDatabaseUpdateToHaveCompleted = async (
); );
}; };
const dismissNotification = (notification) => {
fireEvent.click(notification);
};
const findAndDismissNotification = async () => {
const notification = await screen.findByRole('alert');
dismissNotification(notification);
};
const dragAndDropDirectionUp = 'DND_DIRECTION_UP'; const dragAndDropDirectionUp = 'DND_DIRECTION_UP';
const dragAndDropDirectionDown = 'DND_DIRECTION_DOWN'; const dragAndDropDirectionDown = 'DND_DIRECTION_DOWN';
@ -158,4 +167,6 @@ export {
dragAndDropDirectionUp, dragAndDropDirectionUp,
dragAndDropDirectionDown, dragAndDropDirectionDown,
dragAndDropListItem, dragAndDropListItem,
dismissNotification,
findAndDismissNotification,
}; };