diff --git a/cypress/e2e/APIRequests.cy.ts b/cypress/e2e/APIRequests.cy.ts index d8aeef74..3aa446e9 100644 --- a/cypress/e2e/APIRequests.cy.ts +++ b/cypress/e2e/APIRequests.cy.ts @@ -1,15 +1,26 @@ -import { mixedResponse, nodeOptions, emptyDiagnosisOptions, emptyAssessmentToolOptions } from '../fixtures/mocked-responses'; +import { + mixedResponse, + nodeOptions, + emptyDiagnosisOptions, + emptyAssessmentToolOptions, +} from '../fixtures/mocked-responses'; describe('API request', () => { it('Intercepts the request sent to the API and asserts over the request url', () => { - cy.intercept({ - method: 'GET', - url: 'query/?*', - }, mixedResponse).as('call'); - cy.intercept({ - method: 'GET', - url: '/nodes/', - }, nodeOptions).as('getNodes'); + cy.intercept( + { + method: 'GET', + url: 'query/?*', + }, + mixedResponse + ).as('call'); + cy.intercept( + { + method: 'GET', + url: '/nodes/', + }, + nodeOptions + ).as('getNodes'); cy.visit('/?node=OpenNeuro'); // We need to wait for the fetch to complete and populate the // dropdown with nodes and selecting OpenNeuro before making the request @@ -20,32 +31,53 @@ describe('API request', () => { cy.wait('@call').its('request.url').should('contains', '&min_age=10&max_age=30'); }); it('Empty responses for diagnosis and Assessment make a toast appear', () => { - cy.intercept({ - method: 'GET', - url: '/attributes/nb:Diagnosis', - }, emptyDiagnosisOptions).as('getDiagnosisOptions'); - cy.intercept({ - method: 'GET', - url: '/attributes/nb:Assessment', - }, emptyAssessmentToolOptions).as('getAssessmentToolOptions'); + cy.intercept( + { + method: 'GET', + url: '/attributes/nb:Diagnosis', + }, + emptyDiagnosisOptions + ).as('getDiagnosisOptions'); + cy.intercept( + { + method: 'GET', + url: '/attributes/nb:Assessment', + }, + emptyAssessmentToolOptions + ).as('getAssessmentToolOptions'); cy.visit('/'); cy.wait('@getDiagnosisOptions'); cy.get('.notistack-SnackbarContainer').should('contain', 'No Diagnosis options were available'); - cy.get('.notistack-SnackbarContainer').should('contain', 'No Assessment tool options were available'); + cy.get('.notistack-SnackbarContainer').should( + 'contain', + 'No Assessment tool options were available' + ); }); it('Failed responses for diagnosis and assessment make an error toast appear', () => { - cy.intercept({ - method: 'GET', - url: '/attributes/nb:Diagnosis', - }, { statusCode: 500 }).as('getDiagnosisOptions'); - cy.intercept({ - method: 'GET', - url: '/attributes/nb:Assessment', - }, { statusCode: 500 }).as('getAssessmentToolOptions'); + cy.intercept( + { + method: 'GET', + url: '/attributes/nb:Diagnosis', + }, + { statusCode: 500 } + ).as('getDiagnosisOptions'); + cy.intercept( + { + method: 'GET', + url: '/attributes/nb:Assessment', + }, + { statusCode: 500 } + ).as('getAssessmentToolOptions'); cy.visit('/'); cy.wait('@getDiagnosisOptions'); - cy.get('.notistack-SnackbarContainer').should('contain', 'Failed to retrieve Diagnosis options'); + cy.get('.notistack-SnackbarContainer').should( + 'contain', + 'Failed to retrieve Diagnosis options' + ); cy.wait('@getAssessmentToolOptions'); - cy.get('.notistack-SnackbarContainer').should('contain', 'Failed to retrieve Assessment tool options'); + cy.get('.notistack-SnackbarContainer').should( + 'contain', + 'Failed to retrieve Assessment tool options' + ); }); }); diff --git a/cypress/e2e/Alert.cy.ts b/cypress/e2e/Alert.cy.ts index b06ba78b..72dd0e86 100644 --- a/cypress/e2e/Alert.cy.ts +++ b/cypress/e2e/Alert.cy.ts @@ -1,27 +1,32 @@ describe('Alert', () => { - it('Correctly displays and dismisses the alert', () => { - cy.intercept({ - method: 'GET', - url: '/nodes/', - }).as('getNodes'); - cy.visit('/?node=All'); - // We need to wait for the fetch to complete and populate the - // dropdown with nodes before searching for OpenNeuro - cy.wait('@getNodes'); - cy.get('[data-cy="openneuro-alert"]').should('be.visible').should('contain', 'The OpenNeuro node is being actively annotated at the participant'); + it('Correctly displays and dismisses the alert', () => { + cy.intercept({ + method: 'GET', + url: '/nodes/', + }).as('getNodes'); + cy.visit('/?node=All'); + // We need to wait for the fetch to complete and populate the + // dropdown with nodes before searching for OpenNeuro + cy.wait('@getNodes'); + cy.get('[data-cy="openneuro-alert"]') + .should('be.visible') + .should('contain', 'The OpenNeuro node is being actively annotated at the participant'); - cy.get('[data-cy="Neurobagel graph-categorical-field"]').type('Quebec Parkinson Network{downarrow}{enter}'); - cy.get('[data-cy="openneuro-alert"]').should('not.exist'); - - cy.get('[data-cy="Neurobagel graph-categorical-field"]').should('not.contain', 'All'); - cy.get('[data-cy="Neurobagel graph-categorical-field"]').find('[data-testid="CloseIcon"]').click(); - cy.get('[data-cy="Neurobagel graph-categorical-field"]').should('contain', 'All'); + cy.get('[data-cy="Neurobagel graph-categorical-field"]').type( + 'Quebec Parkinson Network{downarrow}{enter}' + ); + cy.get('[data-cy="openneuro-alert"]').should('not.exist'); - cy.get('[data-cy="Neurobagel graph-categorical-field"]').type('OpenNeuro{downarrow}{enter}'); - cy.get('[data-cy="openneuro-alert"]').should('be.visible'); + cy.get('[data-cy="Neurobagel graph-categorical-field"]').should('not.contain', 'All'); + cy.get('[data-cy="Neurobagel graph-categorical-field"]') + .find('[data-testid="CloseIcon"]') + .click(); + cy.get('[data-cy="Neurobagel graph-categorical-field"]').should('contain', 'All'); - cy.get('[data-cy="openneuro-alert"]').find('[data-testid="CloseIcon"]').click(); - cy.get('[data-cy="openneuro-alert"]').should('not.exist'); - }); + cy.get('[data-cy="Neurobagel graph-categorical-field"]').type('OpenNeuro{downarrow}{enter}'); + cy.get('[data-cy="openneuro-alert"]').should('be.visible'); + + cy.get('[data-cy="openneuro-alert"]').find('[data-testid="CloseIcon"]').click(); + cy.get('[data-cy="openneuro-alert"]').should('not.exist'); }); - \ No newline at end of file +}); diff --git a/cypress/e2e/Checkbox.cy.ts b/cypress/e2e/Checkbox.cy.ts index b71ff11a..ba605c97 100644 --- a/cypress/e2e/Checkbox.cy.ts +++ b/cypress/e2e/Checkbox.cy.ts @@ -16,9 +16,13 @@ describe('Dataset result checkbox', () => { cy.visit('/'); cy.get('[data-cy="submit-query"]').click(); cy.wait('@call'); - cy.get('[data-cy="card-http://neurobagel.org/vocab/cool-dataset-checkbox"]').find('input').check(); + cy.get('[data-cy="card-http://neurobagel.org/vocab/cool-dataset-checkbox"]') + .find('input') + .check(); cy.get('[data-cy="submit-query"]').click(); cy.wait('@call'); - cy.get('[data-cy="card-http://neurobagel.org/vocab/cool-dataset-checkbox"]').should('not.be.checked'); + cy.get('[data-cy="card-http://neurobagel.org/vocab/cool-dataset-checkbox"]').should( + 'not.be.checked' + ); }); }); diff --git a/src/App.tsx b/src/App.tsx index 5748729b..cf1b239f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -51,13 +51,12 @@ function App() { `${attributesURL}${dataElementURI}` ); return response.data[dataElementURI]; - } - catch (err) { + } catch (err) { return null; } } - getAttributes('nb:Diagnosis').then(diagnosisResponse => { + getAttributes('nb:Diagnosis').then((diagnosisResponse) => { if (diagnosisResponse === null) { enqueueSnackbar('Failed to retrieve Diagnosis options', { variant: 'error' }); } else if (diagnosisResponse.length === 0) { @@ -67,7 +66,7 @@ function App() { } }); - getAttributes('nb:Assessment').then(assessmentResponse => { + getAttributes('nb:Assessment').then((assessmentResponse) => { if (assessmentResponse === null) { enqueueSnackbar('Failed to retrieve Assessment tool options', { variant: 'error' }); } else if (assessmentResponse.length === 0) { @@ -81,14 +80,13 @@ function App() { try { const response: AxiosResponse = await axios.get(fetchURL); return response.data; - } - catch (err) { + } catch (err) { return null; } } if (isFederationAPI) { - getNodeOptions(nodesURL).then(nodeResponse => { + getNodeOptions(nodesURL).then((nodeResponse) => { if (nodeResponse === null) { enqueueSnackbar('Failed to retrieve Node options', { variant: 'error' }); } else if (nodeResponse.length === 0) { @@ -98,7 +96,6 @@ function App() { } }); } - }, []); useEffect(() => { @@ -106,22 +103,20 @@ function App() { const searchParamNodes: string[] = searchParams.getAll('node'); if (searchParamNodes) { - const matchedNodeNames: string[] = searchParamNodes - .filter((nodeName) => availableNodes.some((option) => option.NodeName === nodeName)); + const matchedNodeNames: string[] = searchParamNodes.filter((nodeName) => + availableNodes.some((option) => option.NodeName === nodeName) + ); // If there is no node in the search params, set it to All if (matchedNodeNames.length === 0) { setSearchParams({ node: ['All'] }); } // If there is any node besides All selected, remove All from the list - else if ( - matchedNodeNames.length > 1 && - matchedNodeNames.includes('All') - ) { + else if (matchedNodeNames.length > 1 && matchedNodeNames.includes('All')) { const filteredNodeNames = matchedNodeNames.filter((nodeName) => nodeName !== 'All'); setSearchParams({ node: filteredNodeNames }); } - } + } } }, [searchParams, setSearchParams, availableNodes]); @@ -257,7 +252,11 @@ function App() { return ( <> - + {showAlert() && ( <> diff --git a/src/components/CategoricalField.tsx b/src/components/CategoricalField.tsx index acc54f90..5c3005f0 100644 --- a/src/components/CategoricalField.tsx +++ b/src/components/CategoricalField.tsx @@ -9,23 +9,23 @@ function CategoricalField({ inputValue, }: CategoricalFieldProps) { return ( - a.label.localeCompare(b.label))} - isOptionEqualToValue={(option, value) => option.id === value.id} - value={inputValue} - renderInput={(params) => ( - - )} - multiple={multiple} - onChange={(_, value) => onFieldChange(label, value)} - /> + a.label.localeCompare(b.label))} + isOptionEqualToValue={(option, value) => option.id === value.id} + value={inputValue} + renderInput={(params) => ( + + )} + multiple={multiple} + onChange={(_, value) => onFieldChange(label, value)} + /> ); } diff --git a/src/components/DownloadResultButton.tsx b/src/components/DownloadResultButton.tsx index 0f6de54b..0a7524a7 100644 --- a/src/components/DownloadResultButton.tsx +++ b/src/components/DownloadResultButton.tsx @@ -30,7 +30,7 @@ function DownloadResultButton({ {button} ) : ( - button + button ); } diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 69d1e89f..6cfa11c0 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -7,13 +7,15 @@ function Navbar() { const [latestReleaseTag, setLatestReleaseTag] = useState(''); useEffect(() => { - // TODO: replace with react-query-tool once there is a release - const GHApiURL = 'https://api.github.com/repos/neurobagel/query-tool/releases/latest'; - axios.get(GHApiURL) + // TODO: replace with react-query-tool once there is a release + const GHApiURL = 'https://api.github.com/repos/neurobagel/query-tool/releases/latest'; + axios + .get(GHApiURL) .then((response) => { - const {data} = response; + const { data } = response; setLatestReleaseTag(data.tag_name); - }).catch(() => { + }) + .catch(() => { setLatestReleaseTag('beta'); }); }, []); diff --git a/src/components/QueryForm.tsx b/src/components/QueryForm.tsx index bc70e158..ab4e6fd6 100644 --- a/src/components/QueryForm.tsx +++ b/src/components/QueryForm.tsx @@ -48,8 +48,7 @@ function QueryForm({ loading: boolean; onSubmitQuery: () => void; }) { - - function validateContinuousValue (value: number | null) { + function validateContinuousValue(value: number | null) { if (value === null) { // Value is default, user has not entered anything yet return ''; @@ -69,7 +68,10 @@ function QueryForm({ const minAgeExceedsMaxAge: boolean = minAge && maxAge ? minAge > maxAge : false; const disableSubmit: boolean = - minAgeExceedsMaxAge || minAgeHelperText !== '' || maxAgeHelperText !== '' || minNumSessionsHelperText !== ''; + minAgeExceedsMaxAge || + minAgeHelperText !== '' || + maxAgeHelperText !== '' || + minNumSessionsHelperText !== ''; return (
- onCheckboxChange(datasetUUID)} /> + onCheckboxChange(datasetUUID)} + />
{datasetName} diff --git a/src/components/ResultContainer.tsx b/src/components/ResultContainer.tsx index 85161407..5c72df89 100644 --- a/src/components/ResultContainer.tsx +++ b/src/components/ResultContainer.tsx @@ -12,15 +12,15 @@ function ResultContainer({ result }: { result: Result[] | null }) { ? result.length === download.length && result.every((r) => download.includes(r.dataset_uuid)) : false; - let numOfMatchedDatasets = 0; - let numOfMatchedSubjects = 0; - if (result) { - result.forEach((item) => { - numOfMatchedDatasets += 1; - numOfMatchedSubjects += item.num_matching_subjects; - }); - } - const summaryStats = `Summary stats: ${numOfMatchedDatasets} datasets, ${numOfMatchedSubjects} subjects`; + let numOfMatchedDatasets = 0; + let numOfMatchedSubjects = 0; + if (result) { + result.forEach((item) => { + numOfMatchedDatasets += 1; + numOfMatchedSubjects += item.num_matching_subjects; + }); + } + const summaryStats = `Summary stats: ${numOfMatchedDatasets} datasets, ${numOfMatchedSubjects} subjects`; /** * Updates the download array. diff --git a/src/main.tsx b/src/main.tsx index 2b094744..8716b75b 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -16,7 +16,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render( {/* CSS injection order for MUI and tailwind: https://mui.com/material-ui/guides/interoperability/#tailwind-css */} - + );