Firebase Stub: introduced a delay in all async functions to better mimic real Firebase

This commit is contained in:
gianantoniopini
2021-01-21 16:45:33 +01:00
parent 562a07619c
commit af966bdf7b
6 changed files with 42 additions and 18 deletions

View File

@ -2,6 +2,7 @@
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import Constants from '../constants/auth'; import Constants from '../constants/auth';
import delay from '../utils/index';
const singleton = Symbol(''); const singleton = Symbol('');
const singletonEnforcer = Symbol(''); const singletonEnforcer = Symbol('');
@ -49,6 +50,8 @@ class Auth {
async signInAnonymously() { async signInAnonymously() {
const user = Constants.anonymousUser1; const user = Constants.anonymousUser1;
await delay(Constants.defaultDelayInMilliseconds);
this.onAuthStateChangedObservers.forEach((observer) => observer(user)); this.onAuthStateChangedObservers.forEach((observer) => observer(user));
return Promise.resolve(user); return Promise.resolve(user);

View File

@ -14,6 +14,8 @@ const anonymousUser2 = {
uid: 'anonym456', uid: 'anonym456',
}; };
const defaultDelayInMilliseconds = 100;
class Auth { class Auth {
static get anonymousUser1() { static get anonymousUser1() {
return anonymousUser1; return anonymousUser1;
@ -22,6 +24,10 @@ class Auth {
static get anonymousUser2() { static get anonymousUser2() {
return anonymousUser2; return anonymousUser2;
} }
static get defaultDelayInMilliseconds() {
return defaultDelayInMilliseconds;
}
} }
export default Auth; export default Auth;

View File

@ -4,6 +4,7 @@ import { debounce } from 'lodash';
import DatabaseConstants from '../constants/database'; import DatabaseConstants from '../constants/database';
import DataSnapshot from './dataSnapshot'; import DataSnapshot from './dataSnapshot';
import delay from '../utils/index';
const parsePath = (path) => { const parsePath = (path) => {
if (!path) { if (!path) {
@ -183,9 +184,7 @@ class Reference {
throw new Error('eventType should be a string.'); throw new Error('eventType should be a string.');
} }
await new Promise((resolve) => await delay(DatabaseConstants.defaultDelayInMilliseconds);
setTimeout(resolve, DatabaseConstants.defaultDelayInMilliseconds),
);
return Promise.resolve(this._dataSnapshot); return Promise.resolve(this._dataSnapshot);
} }
@ -196,21 +195,27 @@ class Reference {
} }
async update(value) { async update(value) {
await delay(DatabaseConstants.defaultDelayInMilliseconds);
this._handleDataUpdate(value); this._handleDataUpdate(value);
return Promise.resolve(true); return Promise.resolve();
} }
async remove() { async remove() {
await delay(DatabaseConstants.defaultDelayInMilliseconds);
this._handleDataUpdate(null); this._handleDataUpdate(null);
return Promise.resolve(true); return Promise.resolve();
} }
async set(value) { async set(value) {
await delay(DatabaseConstants.defaultDelayInMilliseconds);
this._handleDataUpdate(value); this._handleDataUpdate(value);
return Promise.resolve(true); return Promise.resolve();
} }
} }

View File

@ -0,0 +1,5 @@
const delay = async (milliseconds) => {
await new Promise((resolve) => setTimeout(resolve, milliseconds));
};
export default delay;

View File

@ -1,7 +1,6 @@
import { navigate as mockNavigateFunction } from 'gatsby'; import { navigate as mockNavigateFunction } from 'gatsby';
import React from 'react'; import React from 'react';
import { import {
act,
fireEvent, fireEvent,
render, render,
screen, screen,
@ -31,7 +30,7 @@ describe('Builder', () => {
async function setup( async function setup(
resumeIdParameter, resumeIdParameter,
waitForLoadingScreenToDisappear = true, waitForLoadingScreenToDisappear = true,
waitForDatabaseUpdateFunctionToHaveBeenCalled = true, waitForDatabaseUpdateFunctionToHaveCompleted = true,
) { ) {
FirebaseStub.database().initializeData(); FirebaseStub.database().initializeData();
@ -49,6 +48,8 @@ describe('Builder', () => {
'update', 'update',
); );
FirebaseStub.auth().signInAnonymously();
render( render(
<SettingsProvider> <SettingsProvider>
<ModalProvider> <ModalProvider>
@ -65,20 +66,17 @@ describe('Builder', () => {
</SettingsProvider>, </SettingsProvider>,
); );
await act(async () => {
await FirebaseStub.auth().signInAnonymously();
});
if (waitForLoadingScreenToDisappear) { if (waitForLoadingScreenToDisappear) {
await waitForElementToBeRemoved(() => await waitForElementToBeRemoved(() =>
screen.getByTestId(loadingScreenTestId), screen.getByTestId(loadingScreenTestId),
); );
} }
if (waitForDatabaseUpdateFunctionToHaveBeenCalled) { if (waitForDatabaseUpdateFunctionToHaveCompleted) {
await waitFor(() => mockDatabaseUpdateFunction.mock.calls[0][0], { await waitFor(() => mockDatabaseUpdateFunction.mock.calls[0][0], {
timeout: DebounceWaitTime, timeout: DebounceWaitTime,
}); });
await waitFor(() => mockDatabaseUpdateFunction.mock.results[0].value);
mockDatabaseUpdateFunction.mockClear(); mockDatabaseUpdateFunction.mockClear();
} }
} }
@ -158,6 +156,11 @@ describe('Builder', () => {
expect( expect(
mockDatabaseUpdateFunctionCallArgument.updatedAt, mockDatabaseUpdateFunctionCallArgument.updatedAt,
).toBeGreaterThanOrEqual(now); ).toBeGreaterThanOrEqual(now);
await waitFor(() =>
expect(
mockDatabaseUpdateFunction.mock.results[0].value,
).resolves.toBeUndefined(),
);
}); });
afterEach(() => { afterEach(() => {
@ -195,6 +198,11 @@ describe('Builder', () => {
expect( expect(
mockDatabaseUpdateFunctionCallArgument.updatedAt, mockDatabaseUpdateFunctionCallArgument.updatedAt,
).toBeGreaterThanOrEqual(now); ).toBeGreaterThanOrEqual(now);
await waitFor(() =>
expect(
mockDatabaseUpdateFunction.mock.results[0].value,
).resolves.toBeUndefined(),
);
}); });
}); });

View File

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { import {
act,
render, render,
screen, screen,
waitForElementToBeRemoved, waitForElementToBeRemoved,
@ -34,6 +33,8 @@ describe('Dashboard', () => {
.once('value') .once('value')
).val(); ).val();
FirebaseStub.auth().signInAnonymously();
render( render(
<SettingsProvider> <SettingsProvider>
<ModalProvider> <ModalProvider>
@ -50,10 +51,6 @@ describe('Dashboard', () => {
</SettingsProvider>, </SettingsProvider>,
); );
await act(async () => {
await FirebaseStub.auth().signInAnonymously();
});
if (waitForLoadingScreenToDisappear) { if (waitForLoadingScreenToDisappear) {
await waitForElementToBeRemoved(() => await waitForElementToBeRemoved(() =>
screen.getByTestId(loadingScreenTestId), screen.getByTestId(loadingScreenTestId),