Skip to content

Commit

Permalink
feat: fixed stylistic issues, added deleteproject button, fixed cypre…
Browse files Browse the repository at this point in the history
…ss tests (#610)
  • Loading branch information
nicoalee authored Nov 9, 2023
1 parent 007a84c commit 29f1b07
Show file tree
Hide file tree
Showing 29 changed files with 404 additions and 377 deletions.

This file was deleted.

16 changes: 15 additions & 1 deletion compose/neurosynth-frontend/cypress/e2e/pages/LandingPage.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@ const PAGE_NAME = 'LandingPage';
describe(PAGE_NAME, () => {
beforeEach(() => {
cy.intercept('GET', 'https://api.appzi.io/**', { fixture: 'appzi' }).as('appziFixture');
cy.intercept('GET', `**/api/base-studies/**`, { fixture: 'baseStudies' }).as(
'baseStudiesFixture'
);
cy.intercept('GET', `**/api/points/**`, { fixture: 'points' }).as('pointsFixture');
});

it('should load successfully', () => {
cy.visit('/');
cy.visit('/').wait('@baseStudiesFixture').wait('@pointsFixture');
});

it('should authenticate for real and redirect to projects page', () => {
cy.login('real').visit('/');
cy.contains('Projects');
});

it('should authenticate and redirect to the projects page', () => {
cy.login('mocked').visit('/');
cy.contains('Projects');
});

it('should change the viewport property', () => {
Expand Down
34 changes: 0 additions & 34 deletions compose/neurosynth-frontend/cypress/e2e/pages/NotFound.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,4 @@ describe('NotFoundPage', () => {
cy.visit('/page-that-doesnt-exist');
cy.contains('Requested resource not found');
});

// it('should route the non existent studyset resource to the not found page', () => {
// cy.intercept('GET', '**/api/studysets/*', { statusCode: 404 }).as('studysetsRequestError');
// cy.intercept('GET', '**/api/annotations/*', { statusCode: 404 }).as(
// 'annotationsRequestError'
// );

// cy.visit('/studysets/studyset-that-doesnt-exist')
// .wait(['@studysetsRequestError', '@annotationsRequestError'])
// .get('body')
// .contains('Requested resource not found');
// });

// it('should route the non existent meta-analysis resource to the not found page', () => {
// cy.intercept('GET', '**/api/meta-analyses/**', { statusCode: 404 }).as(
// 'metaAnalysisRequestError'
// );

// cy.visit('/meta-analyses/meta-analysis-that-doesnt-exist')
// .wait(['@metaAnalysisRequestError'])
// .get('body')
// .contains('Requested resource not found');
// });

// it('should route the non existent annotation resource to the not found page', () => {
// cy.intercept('GET', '**/api/annotations/*', {
// statusCode: 404,
// }).as('annotationRequestError');

// cy.visit('/annotations/annotation-doesnt-exist')
// .wait(['@annotationRequestError'])
// .get('body')
// .contains('Requested resource not found');
// });
});
5 changes: 5 additions & 0 deletions compose/neurosynth-frontend/cypress/fixtures/baseStudies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"metadata": {
"total_count": 100
}
}
5 changes: 5 additions & 0 deletions compose/neurosynth-frontend/cypress/fixtures/points.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"metadata": {
"total_count": 100
}
}
47 changes: 9 additions & 38 deletions compose/neurosynth-frontend/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,6 @@ import * as jose from 'jose';
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }

const constructMockAuthJWT = async (jwtPayload = {}): Promise<string> => {
const jwt = await new jose.SignJWT({ ...jwtPayload })
.setProtectedHeader({ alg: 'HS256' })
Expand All @@ -51,6 +23,7 @@ const createMockRequest = async (
audience: string,
client_id: string,
domain: string,
scope: string,
extraClaims = {}
) => {
const access_token = await constructMockAuthJWT({
Expand All @@ -60,7 +33,7 @@ const createMockRequest = async (
iat: 1659719697,
exp: 1659806097,
azp: 'EmcOFhu0XAINM4EyslaKpZ3u09QlBvef',
scope: 'openid profile email',
scope: scope,
});

const id_token = await constructMockAuthJWT({
Expand All @@ -85,7 +58,7 @@ const createMockRequest = async (
access_token: access_token,
expires_in: 86400,
id_token: id_token,
scope: 'openid profile email read:current_user update:current_user_metadata delete:current_user_metadata create:current_user_metadata create:current_user_device_credentials delete:current_user_device_credentials update:current_user_identities',
scope: scope,
token_type: 'Bearer',
},
};
Expand All @@ -99,12 +72,14 @@ Cypress.Commands.add('login', (loginMode = 'mocked', extraClaims = {}) => {
const password = Cypress.env('auth0Password');
const domain = Cypress.env('auth0Domain');

const scope = 'openid profile email offline_access';

/**
* To prevent rate limiting errors form auth0, we stub our own request func and return a mocked response
*/
if (loginMode === 'mocked') {
cy.stub(cy, 'request').callsFake(() =>
cy.wrap(createMockRequest(audience, client_id, domain, extraClaims))
cy.wrap(createMockRequest(audience, client_id, domain, scope, extraClaims))
);
}

Expand All @@ -121,7 +96,7 @@ Cypress.Commands.add('login', (loginMode = 'mocked', extraClaims = {}) => {
username,
password,
audience,
scope: 'openid profile email',
scope,
client_id,
client_secret,
},
Expand Down Expand Up @@ -153,7 +128,7 @@ Cypress.Commands.add('login', (loginMode = 'mocked', extraClaims = {}) => {
},
expires_in,
id_token,
scope: 'openid profile email read:current_user update:current_user_metadata delete:current_user_metadata create:current_user_metadata create:current_user_device_credentials delete:current_user_device_credentials update:current_user_identities',
scope,
token_type: 'Bearer',
},
expiresAt: Math.floor(Date.now() / 1000) + expires_in,
Expand All @@ -165,13 +140,10 @@ Cypress.Commands.add('login', (loginMode = 'mocked', extraClaims = {}) => {
* the isAuthenticated state. This code is in tandem with setting the auth0 provider cacheLocation=localstorage.
*/
cy.addToLocalStorage(
`@@auth0spajs@@::${client_id}::${audience}::openid profile email`,
`@@auth0spajs@@::${client_id}::${audience}::${scope}`,
JSON.stringify(session)
);
});

// this will always run after the previous commands are complete
cy.visit('/');
});

Cypress.Commands.add('clearSessionStorage', () => {
Expand All @@ -192,7 +164,6 @@ declare global {
namespace Cypress {
interface Chainable {
login(loginMode: 'real' | 'mocked', extraClaims?: any): Chainable<void>;
mockLogin(extraClaims?: any): Chainable<void>;
clearSessionStorage(): Chainable<void>;
addToLocalStorage(key: string, value: string): Chainable<void>;
}
Expand Down
2 changes: 1 addition & 1 deletion compose/neurosynth-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"test-with-coverage": "npm run test -- --coverage --watchAll=false",
"cy:e2e-headless": "cypress run",
"cy:e2e-headless-local": "env-cmd -f .env.dev cypress run",
"cy:e2e-browser": "env-cmd -f .env.dev cypress open -b chrome --e2e",
"cy:e2e-browser": "env-cmd -f .env.staging cypress open -b chrome --e2e",
"cy:install": "cypress install",
"cy:ci": "start-server-and-test start-ci:dev 3000 cy:e2e-headless",
"eject": "react-scripts eject"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const ConfirmationDialog: React.FC<IConfirmationDialog> = (props) => {
</DialogTitle>
<DialogContent>
{props.dialogMessage && dialogContent}
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', marginTop: '1rem' }}>
<Button
sx={{ width: '250px', marginRight: '15px' }}
onClick={() => props.onCloseDialog(false, props.data)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@ const FullTextChip: React.FC<{ name?: string | null }> = (props) => {
isError: getFullTextIsError,
} = useGetFullText(debouncedName);

console.log({
debouncedName,
getFullTextIsError,
getFullTextIsLoading,
fullTextURL,
});

if (getFullTextIsLoading || !debouncedName) {
return (
<Box sx={{ display: 'inline-block', textAlign: 'center', width: '200px' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,42 +83,57 @@ const EditStudySaveButton: React.FC = React.memo((props) => {
const [isCloning, setIsCloning] = useState(false);

const handleUpdateBothInDB = async () => {
const updatedStudy = await updateStudyInDB(annotationId as string);
const updatedNotes = [...(notes || [])];
updatedNotes.forEach((note, index) => {
if (note.isNew) {
const foundAnalysis = ((updatedStudy.analyses || []) as AnalysisReturn[]).find(
(analysis) => analysis.name === note.analysis_name
);
if (!foundAnalysis) return;
try {
const updatedStudy = await updateStudyInDB(annotationId as string);
const updatedNotes = [...(notes || [])];
updatedNotes.forEach((note, index) => {
if (note.isNew) {
const foundAnalysis = ((updatedStudy.analyses || []) as AnalysisReturn[]).find(
(analysis) => analysis.name === note.analysis_name
);
if (!foundAnalysis) return;

updatedNotes[index] = {
...updatedNotes[index],
analysis: foundAnalysis.id,
};
}
});
updateAnnotationNotes(updatedNotes);
await updateAnnotationInDB();
updatedNotes[index] = {
...updatedNotes[index],
analysis: foundAnalysis.id,
};
}
});
updateAnnotationNotes(updatedNotes);
await updateAnnotationInDB();

queryClient.invalidateQueries('studies');
queryClient.invalidateQueries('annotations');
queryClient.invalidateQueries('studies');
queryClient.invalidateQueries('annotations');

enqueueSnackbar('Study and annotation saved', { variant: 'success' });
enqueueSnackbar('Study and annotation saved', { variant: 'success' });
} catch (e) {
console.error(e);
enqueueSnackbar('There was an error', { variant: 'error' });
}
};

const handleUpdateStudyInDB = async () => {
await updateStudyInDB(annotationId as string);
queryClient.invalidateQueries('studies');
queryClient.invalidateQueries('annotations');
try {
await updateStudyInDB(annotationId as string);
queryClient.invalidateQueries('studies');
queryClient.invalidateQueries('annotations');

enqueueSnackbar('Study saved', { variant: 'success' });
enqueueSnackbar('Study saved', { variant: 'success' });
} catch (e) {
console.error(e);
enqueueSnackbar('There was an error saving the study', { variant: 'error' });
}
};

const handleUpdateAnnotationInDB = async () => {
await updateAnnotationInDB();
queryClient.invalidateQueries('annotations');
enqueueSnackbar('Annotation saved', { variant: 'success' });
try {
await updateAnnotationInDB();
queryClient.invalidateQueries('annotations');
enqueueSnackbar('Annotation saved', { variant: 'success' });
} catch (e) {
console.error(e);
enqueueSnackbar('There was an issue saving the annotation', { variant: 'error' });
}
};

const handleUpdateDB = () => {
Expand Down
Loading

0 comments on commit 29f1b07

Please sign in to comment.