diff --git a/compose/neurosynth-frontend/cypress/e2e/pages/BaseStudyPage.cy.tsx b/compose/neurosynth-frontend/cypress/e2e/pages/BaseStudyPage.cy.tsx
index bd1a7dfe7..942000d33 100644
--- a/compose/neurosynth-frontend/cypress/e2e/pages/BaseStudyPage.cy.tsx
+++ b/compose/neurosynth-frontend/cypress/e2e/pages/BaseStudyPage.cy.tsx
@@ -22,7 +22,6 @@ describe(PAGE_NAME, () => {
cy.intercept('GET', `**/api/base-studies/**`, {
fixture: 'study',
}).as('studyFixture');
- cy.visit(PATH).wait('@semanticScholarFixture').wait('@studyFixture');
// .get('tr')
// .eq(2)
// .click()
diff --git a/compose/neurosynth-frontend/cypress/e2e/pages/EditStudyPage.cy.tsx b/compose/neurosynth-frontend/cypress/e2e/pages/EditStudyPage.cy.tsx
index 586d7573d..e03c08054 100644
--- a/compose/neurosynth-frontend/cypress/e2e/pages/EditStudyPage.cy.tsx
+++ b/compose/neurosynth-frontend/cypress/e2e/pages/EditStudyPage.cy.tsx
@@ -36,7 +36,6 @@ describe(PAGE_NAME, () => {
.wait('@studyFixture')
.wait('@projectFixture')
.wait('@annotationFixture')
- .wait('@semanticScholarFixture')
.wait('@studysetFixture');
});
@@ -48,7 +47,6 @@ describe(PAGE_NAME, () => {
.wait('@studyFixture')
.wait('@projectFixture')
.wait('@annotationFixture')
- .wait('@semanticScholarFixture')
.wait('@studysetFixture');
// ACT
@@ -56,7 +54,7 @@ describe(PAGE_NAME, () => {
cy.contains('label', 'doi').next().clear();
cy.contains('label', 'pmid').next().clear();
cy.contains('label', 'pmcid').next().clear();
- cy.contains('button', 'save').click();
+ cy.get('[data-testid="SaveIcon"]').click();
// ASSERT
cy.get('@editStudy').its('request.body').should('not.have.a.property', 'doi');
diff --git a/compose/neurosynth-frontend/cypress/e2e/pages/PublicStudiesPage.cy.tsx b/compose/neurosynth-frontend/cypress/e2e/pages/PublicStudiesPage.cy.tsx
index dc4a824d4..805078576 100644
--- a/compose/neurosynth-frontend/cypress/e2e/pages/PublicStudiesPage.cy.tsx
+++ b/compose/neurosynth-frontend/cypress/e2e/pages/PublicStudiesPage.cy.tsx
@@ -7,7 +7,7 @@ export {};
const PATH = '/base-studies';
const PAGE_NAME = 'StudiesPage';
-describe.skip(PAGE_NAME, () => {
+describe(PAGE_NAME, () => {
beforeEach(() => {
cy.clearLocalStorage();
cy.intercept('GET', 'https://api.appzi.io/**', { fixture: 'appzi' }).as('appziFixture');
@@ -16,7 +16,7 @@ describe.skip(PAGE_NAME, () => {
it('should load successfully', () => {
cy.intercept('GET', `**/api/projects*`).as('realProjectsRequest');
cy.intercept('GET', `**/api/base-studies/**`).as('realStudiesRequest');
- cy.visit(PATH).wait('@realStudiesRequest');
+ cy.visit(PATH);
});
// describe('Search', () => {
diff --git a/compose/neurosynth-frontend/cypress/e2e/workflows/Extraction/ExtractionTable.cy.tsx b/compose/neurosynth-frontend/cypress/e2e/workflows/Extraction/ExtractionTable.cy.tsx
index 24b8054fa..f1fc62bc6 100644
--- a/compose/neurosynth-frontend/cypress/e2e/workflows/Extraction/ExtractionTable.cy.tsx
+++ b/compose/neurosynth-frontend/cypress/e2e/workflows/Extraction/ExtractionTable.cy.tsx
@@ -3,6 +3,7 @@
import { INeurosynthProjectReturn } from 'hooks/projects/useGetProjects';
import { StudyReturn, StudysetReturn } from 'neurostore-typescript-sdk';
import { IExtractionTableStudy } from 'pages/Extraction/components/ExtractionTable';
+import { getAuthorShortName } from 'pages/Extraction/components/ExtractionTable.helpers';
describe('ExtractionTable', () => {
beforeEach(() => {
@@ -303,7 +304,12 @@ describe('ExtractionTable', () => {
cy.get('tbody > tr').each((tr, index) => {
cy.wrap(tr).within(() => {
- cy.get('td').eq(2).should('have.text', sortedStudies[index].authors);
+ cy.get('td')
+ .eq(2)
+ .should(
+ 'have.text',
+ getAuthorShortName(sortedStudies?.[index]?.authors || '')
+ );
});
});
});
@@ -324,7 +330,12 @@ describe('ExtractionTable', () => {
cy.get('tbody > tr').each((tr, index) => {
cy.wrap(tr).within(() => {
- cy.get('td').eq(2).should('have.text', sortedStudies[index].authors);
+ cy.get('td')
+ .eq(2)
+ .should(
+ 'have.text',
+ getAuthorShortName(sortedStudies?.[index]?.authors || '')
+ );
});
});
});
diff --git a/compose/neurosynth-frontend/cypress/e2e/workflows/MetaAnalyses/CreateSpecificationDialog.cy.tsx b/compose/neurosynth-frontend/cypress/e2e/workflows/MetaAnalyses/CreateSpecificationDialog.cy.tsx
index a2edb04ac..ac5706bc0 100644
--- a/compose/neurosynth-frontend/cypress/e2e/workflows/MetaAnalyses/CreateSpecificationDialog.cy.tsx
+++ b/compose/neurosynth-frontend/cypress/e2e/workflows/MetaAnalyses/CreateSpecificationDialog.cy.tsx
@@ -40,7 +40,7 @@ describe('CreateSpecificationDialog', () => {
cy.contains('FDRCorrector').should('exist');
});
- it.only('should step through the wizard', () => {
+ it('should step through the wizard', () => {
cy.intercept('POST', '**/api/specifications', {
id: 'mockedSpecificationId',
}).as('createSpecificationFixture');
diff --git a/compose/neurosynth-frontend/cypress/e2e/workflows/SleuthImport/DoSleuthImport.cy.tsx b/compose/neurosynth-frontend/cypress/e2e/workflows/SleuthImport/DoSleuthImport.cy.tsx
index c25014cf6..13acbfc13 100644
--- a/compose/neurosynth-frontend/cypress/e2e/workflows/SleuthImport/DoSleuthImport.cy.tsx
+++ b/compose/neurosynth-frontend/cypress/e2e/workflows/SleuthImport/DoSleuthImport.cy.tsx
@@ -433,7 +433,7 @@ describe('DoSleuthImport', () => {
});
describe('edge cases', () => {
- it.only('should apply the pubmed details to the study if a matching pubmed study is found', () => {
+ it('should apply the pubmed details to the study if a matching pubmed study is found', () => {
// this stuff exists just to make sure cypress doesnt send any real requests. They are not under test
// synth API responses
cy.intercept('POST', `${neurostoreAPIBaseURL}/analyses/**`, {
diff --git a/compose/neurosynth-frontend/src/App.spec.tsx b/compose/neurosynth-frontend/src/App.spec.tsx
deleted file mode 100644
index 4a9b4e511..000000000
--- a/compose/neurosynth-frontend/src/App.spec.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import { act } from 'react-dom/test-utils';
-import App from './App';
-
-jest.mock('./components/Navbar/Navbar');
-jest.mock('./pages/BaseNavigation/BaseNavigation');
-jest.mock('@auth0/auth0-react');
-
-test('renders main app', async () => {
- await act(async () => {
- render();
- });
- const mockNavbar = screen.getByText('mock navbar');
- const mockNavigation = screen.getByText('mock base navigation');
- expect(mockNavbar).toBeInTheDocument();
- expect(mockNavigation).toBeInTheDocument();
-});
diff --git a/compose/neurosynth-frontend/src/App.tsx b/compose/neurosynth-frontend/src/App.tsx
index 62f884cdb..f713e0394 100644
--- a/compose/neurosynth-frontend/src/App.tsx
+++ b/compose/neurosynth-frontend/src/App.tsx
@@ -5,15 +5,16 @@ import useGoogleAnalytics from 'hooks/useGoogleAnalytics';
import { SnackbarKey, SnackbarProvider } from 'notistack';
import { useEffect, useRef } from 'react';
import { QueryCache, QueryClient, QueryClientProvider } from 'react-query';
-import Navbar from './components/Navbar/Navbar';
+import Navbar from 'components/Navbar/Navbar';
import useGetToken from './hooks/useGetToken';
-import BaseNavigation from './pages/BaseNavigation/BaseNavigation';
+import BaseNavigation from 'pages/BaseNavigation/BaseNavigation';
import { useLocation } from 'react-router-dom';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: 0,
+ refetchOnWindowFocus: false,
// staleTime: 5000, // https://tkdodo.eu/blog/practical-react-query#the-defaults-explained
},
},
diff --git a/compose/neurosynth-frontend/src/__mocks__/@auth0/auth0-react.ts b/compose/neurosynth-frontend/src/__mocks__/@auth0/auth0-react.ts
index 9466c8fed..f23397b37 100644
--- a/compose/neurosynth-frontend/src/__mocks__/@auth0/auth0-react.ts
+++ b/compose/neurosynth-frontend/src/__mocks__/@auth0/auth0-react.ts
@@ -5,6 +5,7 @@ const useAuth0 = jest.fn().mockReturnValue({
loginWithPopup: jest.fn(),
logout: jest.fn(),
isAuthenticated: false,
+ isLoading: false,
user: {
sub: 'some-github-user',
},
diff --git a/compose/neurosynth-frontend/src/__mocks__/notistack.ts b/compose/neurosynth-frontend/src/__mocks__/notistack.ts
new file mode 100644
index 000000000..4d8418e63
--- /dev/null
+++ b/compose/neurosynth-frontend/src/__mocks__/notistack.ts
@@ -0,0 +1,5 @@
+const useSnackbar = jest.fn().mockReturnValue({
+ enqueueSnackbar: jest.fn(),
+});
+
+export { useSnackbar };
diff --git a/compose/neurosynth-frontend/src/__mocks__/react-query.ts b/compose/neurosynth-frontend/src/__mocks__/react-query.ts
new file mode 100644
index 000000000..46ac44638
--- /dev/null
+++ b/compose/neurosynth-frontend/src/__mocks__/react-query.ts
@@ -0,0 +1,11 @@
+const useQueryClient = jest.fn().mockReturnValue({
+ invalidateQueries: jest.fn(),
+});
+
+const useQuery = jest.fn().mockReturnValue({
+ data: null,
+ isLoading: false,
+ isError: false,
+});
+
+export { useQueryClient, useQuery };
diff --git a/compose/neurosynth-frontend/src/__mocks__/react-router-dom.ts b/compose/neurosynth-frontend/src/__mocks__/react-router-dom.ts
deleted file mode 100644
index a3a19d340..000000000
--- a/compose/neurosynth-frontend/src/__mocks__/react-router-dom.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-const useNavigate = jest.fn().mockReturnValue(jest.fn());
-
-const useLocation = jest.fn().mockReturnValue({
- location: {
- search: '',
- },
-});
-
-export { useNavigate, useLocation };
diff --git a/compose/neurosynth-frontend/src/__mocks__/react-router-dom.tsx b/compose/neurosynth-frontend/src/__mocks__/react-router-dom.tsx
new file mode 100644
index 000000000..9168b3bed
--- /dev/null
+++ b/compose/neurosynth-frontend/src/__mocks__/react-router-dom.tsx
@@ -0,0 +1,25 @@
+import { NavigateProps } from 'react-router-dom';
+
+const useParams = jest.fn().mockReturnValue({
+ projectId: 'test-project-id',
+});
+
+const useNavigate = jest.fn().mockReturnValue(jest.fn());
+
+const useLocation = jest.fn().mockReturnValue({
+ location: {
+ search: '',
+ },
+});
+
+const Navigate = ({ to, replace, state }: NavigateProps) => {
+ return (
+ <>
+
{to}
+ {replace}
+ {JSON.stringify(state)}
+ >
+ );
+};
+
+export { useNavigate, useLocation, useParams, Navigate };
diff --git a/compose/neurosynth-frontend/src/components/Dialogs/ConfirmationDialog.spec.tsx b/compose/neurosynth-frontend/src/components/Dialogs/ConfirmationDialog.spec.tsx
index 4467c7dee..aedd2e210 100644
--- a/compose/neurosynth-frontend/src/components/Dialogs/ConfirmationDialog.spec.tsx
+++ b/compose/neurosynth-frontend/src/components/Dialogs/ConfirmationDialog.spec.tsx
@@ -41,7 +41,7 @@ describe('ConfirmationDialog', () => {
const rejectButton = screen.getByRole('button', { name: 'reject' });
userEvent.click(rejectButton);
- expect(mockOnClose).toBeCalledWith(false, undefined);
+ expect(mockOnClose).toBeCalledWith(false);
});
it('should signal true when confirm is clicked', () => {
@@ -57,7 +57,7 @@ describe('ConfirmationDialog', () => {
const confirmButton = screen.getByRole('button', { name: 'confirm' });
userEvent.click(confirmButton);
- expect(mockOnClose).toBeCalledWith(true, undefined);
+ expect(mockOnClose).toBeCalledWith(true);
});
it('should signal undefined when clicked away', async () => {
@@ -77,7 +77,7 @@ describe('ConfirmationDialog', () => {
// we need to trigger a click away by clicking the backdrop. For some reason,
// the second presentation div accomplishes this
userEvent.click(screen.getAllByRole('presentation')[1]);
- expect(mockOnClose).toBeCalledWith(undefined, undefined);
+ expect(mockOnClose).toBeCalledWith(undefined);
});
it('should close when close icon button is clicked', () => {
@@ -92,7 +92,7 @@ describe('ConfirmationDialog', () => {
);
userEvent.click(screen.getByTestId('CloseIcon'));
- expect(mockOnClose).toHaveBeenCalledWith(undefined, undefined);
+ expect(mockOnClose).toHaveBeenCalledWith(undefined);
});
it('should be called with the data', () => {
@@ -103,13 +103,12 @@ describe('ConfirmationDialog', () => {
onCloseDialog={mockOnClose}
confirmText="confirm"
rejectText="reject"
- data={{ data: 'test-data' }}
/>
);
const confirmButton = screen.getByRole('button', { name: 'confirm' });
userEvent.click(confirmButton);
- expect(mockOnClose).toHaveBeenCalledWith(true, { data: 'test-data' });
+ expect(mockOnClose).toHaveBeenCalledWith(true);
});
});
diff --git a/compose/neurosynth-frontend/src/components/Dialogs/ConfirmationDialog.tsx b/compose/neurosynth-frontend/src/components/Dialogs/ConfirmationDialog.tsx
index 3fa9b23a7..a0ed28cfd 100644
--- a/compose/neurosynth-frontend/src/components/Dialogs/ConfirmationDialog.tsx
+++ b/compose/neurosynth-frontend/src/components/Dialogs/ConfirmationDialog.tsx
@@ -9,16 +9,15 @@ import {
IconButton,
} from '@mui/material';
import CloseIcon from '@mui/icons-material/Close';
-import React, { useMemo } from 'react';
+import React, { ReactNode, useMemo } from 'react';
export interface IConfirmationDialog {
isOpen: boolean;
- onCloseDialog: (confirm: boolean | undefined, data?: any) => void;
+ onCloseDialog: (confirm: boolean | undefined) => void;
dialogTitle: string;
- dialogMessage?: JSX.Element | string;
+ dialogMessage?: ReactNode | string;
confirmText?: string;
rejectText?: string;
- data?: any;
}
const ConfirmationDialog: React.FC = (props) => {
@@ -33,13 +32,13 @@ const ConfirmationDialog: React.FC = (props) => {
}, [props.dialogMessage]);
return (
-