diff --git a/__mocks__/__tests__/gatsby-plugin-firebase.test.js b/__mocks__/__tests__/gatsby-plugin-firebase.test.js index 84e0a9ca..f80e06c0 100644 --- a/__mocks__/__tests__/gatsby-plugin-firebase.test.js +++ b/__mocks__/__tests__/gatsby-plugin-firebase.test.js @@ -6,10 +6,6 @@ import FirebaseStub, { describe('FirebaseStub', () => { describe('auth', () => { - afterEach(() => { - FirebaseStub.auth().dispose(); - }); - it('reuses existing Auth instance', () => { const auth1 = FirebaseStub.auth(); const auth2 = FirebaseStub.auth(); @@ -49,14 +45,15 @@ describe('FirebaseStub', () => { const observer = () => {}; const unsubscribe = FirebaseStub.auth().onAuthStateChanged(observer); expect(unsubscribe).toBeTruthy(); - expect(FirebaseStub.auth().onAuthStateChangedObservers).toHaveLength(1); - expect(FirebaseStub.auth().onAuthStateChangedObservers[0]).toEqual( - observer, - ); + expect( + FirebaseStub.auth().onAuthStateChangedObservers.indexOf(observer), + ).toBeGreaterThanOrEqual(0); unsubscribe(); - expect(FirebaseStub.auth().onAuthStateChangedObservers).toHaveLength(0); + expect( + FirebaseStub.auth().onAuthStateChangedObservers.indexOf(observer), + ).not.toBeGreaterThanOrEqual(0); }); }); @@ -258,7 +255,7 @@ describe('FirebaseStub', () => { ); }); - it('previously set query parameters are not kept when retrieving reference again', async () => { + it('previously set query parameters are not kept when retrieving reference again', () => { let reference = null; reference = FirebaseStub.database().ref(DatabaseConstants.resumesPath); diff --git a/__mocks__/gatsby-plugin-firebase/auth/auth.js b/__mocks__/gatsby-plugin-firebase/auth/auth.js index fc5eb043..853bb133 100644 --- a/__mocks__/gatsby-plugin-firebase/auth/auth.js +++ b/__mocks__/gatsby-plugin-firebase/auth/auth.js @@ -33,10 +33,6 @@ class Auth { return this._onAuthStateChangedObservers; } - dispose() { - this._onAuthStateChangedObservers = []; - } - onAuthStateChanged(observer) { this.onAuthStateChangedObservers.push(observer); diff --git a/src/pages/app/__tests__/builder.test.js b/src/pages/app/__tests__/builder.test.js index cc9b80ef..4615e5aa 100644 --- a/src/pages/app/__tests__/builder.test.js +++ b/src/pages/app/__tests__/builder.test.js @@ -31,10 +31,31 @@ describe('Builder', () => { let resume = null; let mockDatabaseUpdateFunction = null; + const fnWaitForDatabaseUpdateToHaveCompleted = async () => { + await waitFor(() => mockDatabaseUpdateFunction.mock.calls[0][0], { + timeout: DebounceWaitTime, + }); + await waitFor(() => mockDatabaseUpdateFunction.mock.results[0].value); + }; + + const expectDatabaseUpdateToHaveCompleted = async () => { + await waitFor( + () => expect(mockDatabaseUpdateFunction).toHaveBeenCalledTimes(1), + { + timeout: DebounceWaitTime, + }, + ); + await waitFor(() => + expect( + mockDatabaseUpdateFunction.mock.results[0].value, + ).resolves.toBeUndefined(), + ); + }; + async function setup( resumeIdParameter, waitForLoadingScreenToDisappear = true, - waitForDatabaseUpdateFunctionToHaveCompleted = true, + waitForDatabaseUpdateToHaveCompleted = true, ) { FirebaseStub.database().initializeData(); @@ -78,29 +99,18 @@ describe('Builder', () => { ); } - if (waitForDatabaseUpdateFunctionToHaveCompleted) { - await waitFor(() => mockDatabaseUpdateFunction.mock.calls[0][0], { - timeout: DebounceWaitTime, - }); - await waitFor(() => mockDatabaseUpdateFunction.mock.results[0].value); + if (waitForDatabaseUpdateToHaveCompleted) { + await fnWaitForDatabaseUpdateToHaveCompleted(); mockDatabaseUpdateFunction.mockClear(); } } describe('handles errors', () => { describe('if resume does not exist', () => { - const waitForNavigateFunctionToHaveCompleted = async () => { - await waitFor(() => mockNavigateFunction.mock.results[0].value); - }; - beforeEach(async () => { await setup('xxxxxx', false, false); }); - afterEach(async () => { - await waitForNavigateFunctionToHaveCompleted(); - }); - it('navigates to Dashboard and displays notification', async () => { await waitFor(() => expect(mockNavigateFunction).toHaveBeenCalledTimes(1), @@ -110,6 +120,12 @@ describe('Builder', () => { await waitFor(() => { expect(screen.getByRole('alert')).toBeInTheDocument(); }); + + await waitFor(() => + expect( + mockNavigateFunction.mock.results[0].value, + ).resolves.toBeUndefined(), + ); }); }); }); @@ -157,12 +173,7 @@ describe('Builder', () => { const languageStorageItem = localStorage.getItem(languageStorageItemKey); expect(languageStorageItem).toBe(italianLanguageCode); - await waitFor( - () => expect(mockDatabaseUpdateFunction).toHaveBeenCalledTimes(1), - { - timeout: DebounceWaitTime, - }, - ); + await expectDatabaseUpdateToHaveCompleted(); const mockDatabaseUpdateFunctionCallArgument = mockDatabaseUpdateFunction.mock.calls[0][0]; expect(mockDatabaseUpdateFunctionCallArgument.id).toBe(resumeId); @@ -172,11 +183,6 @@ describe('Builder', () => { expect( mockDatabaseUpdateFunctionCallArgument.updatedAt, ).toBeGreaterThanOrEqual(now); - await waitFor(() => - expect( - mockDatabaseUpdateFunction.mock.results[0].value, - ).resolves.toBeUndefined(), - ); }); afterEach(() => { @@ -199,12 +205,7 @@ describe('Builder', () => { expect(input.value).toBe(newInputValue); - await waitFor( - () => expect(mockDatabaseUpdateFunction).toHaveBeenCalledTimes(1), - { - timeout: DebounceWaitTime, - }, - ); + await expectDatabaseUpdateToHaveCompleted(); const mockDatabaseUpdateFunctionCallArgument = mockDatabaseUpdateFunction.mock.calls[0][0]; expect(mockDatabaseUpdateFunctionCallArgument.id).toBe(resumeId); @@ -214,11 +215,6 @@ describe('Builder', () => { expect( mockDatabaseUpdateFunctionCallArgument.updatedAt, ).toBeGreaterThanOrEqual(now); - await waitFor(() => - expect( - mockDatabaseUpdateFunction.mock.results[0].value, - ).resolves.toBeUndefined(), - ); }); }); @@ -227,14 +223,14 @@ describe('Builder', () => { await setup(DatabaseConstants.demoStateResume1Id, false, false); }); - afterEach(async () => { + it('renders loading screen', async () => { + expect(screen.getByTestId(loadingScreenTestId)).toBeInTheDocument(); + await waitForElementToBeRemoved(() => screen.getByTestId(loadingScreenTestId), ); - }); - it('renders loading screen', () => { - expect(screen.getByTestId(loadingScreenTestId)).toBeInTheDocument(); + await fnWaitForDatabaseUpdateToHaveCompleted(); }); }); }); diff --git a/src/pages/app/__tests__/dashboard.test.js b/src/pages/app/__tests__/dashboard.test.js index 385493b9..26b8bccc 100644 --- a/src/pages/app/__tests__/dashboard.test.js +++ b/src/pages/app/__tests__/dashboard.test.js @@ -24,13 +24,23 @@ import Wrapper from '../../../components/shared/Wrapper'; import Dashboard from '../dashboard'; describe('Dashboard', () => { - let resumes = null; + let userResumes = null; const user = DatabaseConstants.user1; + const waitForResumeToBeRenderedInPreview = async (resume) => { + await screen.findByText(resume.name); + }; + + const expectResumeToBeRenderedInPreview = async (resume) => { + await waitFor(() => { + expect(screen.getByText(resume.name)).toBeInTheDocument(); + }); + }; + async function setup(waitForLoadingScreenToDisappear = true) { FirebaseStub.database().initializeData(); - resumes = ( + userResumes = ( await FirebaseStub.database() .ref(DatabaseConstants.resumesPath) .orderByChild('user') @@ -83,20 +93,10 @@ describe('Dashboard', () => { }); it('preview of user resumes', async () => { - expect(Object.keys(resumes)).toHaveLength(2); + expect(Object.keys(userResumes)).toHaveLength(2); - expect(Object.values(resumes)[0].user).toEqual(user.uid); - await waitFor(() => { - expect( - screen.getByText(Object.values(resumes)[0].name), - ).toBeInTheDocument(); - }); - expect(Object.values(resumes)[1].user).toEqual(user.uid); - await waitFor(() => { - expect( - screen.getByText(Object.values(resumes)[1].name), - ).toBeInTheDocument(); - }); + await expectResumeToBeRenderedInPreview(Object.values(userResumes)[0]); + await expectResumeToBeRenderedInPreview(Object.values(userResumes)[1]); }); }); @@ -106,14 +106,25 @@ describe('Dashboard', () => { let undeletedResume = null; let resumeToDeleteId = null; - const waitForDatabaseRemoveFunctionToHaveCompleted = async () => { + const waitForDatabaseRemoveToHaveCompleted = async () => { await waitFor(() => mockDatabaseRemoveFunction.mock.results[0].value); }; + const expectDatabaseRemoveToHaveCompleted = async () => { + await waitFor(() => + expect(mockDatabaseRemoveFunction).toHaveBeenCalledTimes(1), + ); + await waitFor(() => + expect( + mockDatabaseRemoveFunction.mock.results[0].value, + ).resolves.toBeUndefined(), + ); + }; + beforeEach(async () => { await setup(); - [resumeToDelete, undeletedResume] = Object.values(resumes); + [resumeToDelete, undeletedResume] = Object.values(userResumes); resumeToDeleteId = resumeToDelete.id; mockDatabaseRemoveFunction = jest.spyOn( @@ -123,13 +134,9 @@ describe('Dashboard', () => { 'remove', ); - let resumeToDeleteMenuToggle = null; - await waitFor(() => { - resumeToDeleteMenuToggle = screen.queryByTestId( - `${resumePreviewMenuToggleDataTestIdPrefix}${resumeToDeleteId}`, - ); - return resumeToDeleteMenuToggle ? Promise.resolve() : Promise.reject(); - }); + const resumeToDeleteMenuToggle = await screen.findByTestId( + `${resumePreviewMenuToggleDataTestIdPrefix}${resumeToDeleteId}`, + ); fireEvent.click(resumeToDeleteMenuToggle); const menuItems = screen.getAllByRole('menuitem'); @@ -143,32 +150,28 @@ describe('Dashboard', () => { fireEvent.click(deleteMenuItem); }); - afterEach(async () => { - await waitForDatabaseRemoveFunctionToHaveCompleted(); - }); - it('removes it from database and preview', async () => { - await waitFor(() => - expect(mockDatabaseRemoveFunction).toHaveBeenCalledTimes(1), - ); - - await waitForDatabaseRemoveFunctionToHaveCompleted(); + await expectDatabaseRemoveToHaveCompleted(); await waitFor(() => expect(screen.queryByText(resumeToDelete.name)).toBeNull(), ); - expect(screen.getByText(undeletedResume.name)).toBeInTheDocument(); + await expectResumeToBeRenderedInPreview(undeletedResume); }); it('displays notification', async () => { await waitFor(() => { expect(screen.getByRole('alert')).toBeInTheDocument(); }); + + await waitForDatabaseRemoveToHaveCompleted(); }); - it('closes menu', () => { + it('closes menu', async () => { const menuItems = screen.queryAllByRole('menuitem'); expect(menuItems).toHaveLength(0); + + await waitForDatabaseRemoveToHaveCompleted(); }); }); @@ -177,14 +180,15 @@ describe('Dashboard', () => { await setup(false); }); - afterEach(async () => { + it('renders loading screen', async () => { + expect(screen.getByTestId(loadingScreenTestId)).toBeInTheDocument(); + await waitForElementToBeRemoved(() => screen.getByTestId(loadingScreenTestId), ); - }); - it('renders loading screen', () => { - expect(screen.getByTestId(loadingScreenTestId)).toBeInTheDocument(); + await waitForResumeToBeRenderedInPreview(Object.values(userResumes)[0]); + await waitForResumeToBeRenderedInPreview(Object.values(userResumes)[1]); }); }); });