From 7cc675f51567c3e6e5836bf7a0cdb168bff53b0e Mon Sep 17 00:00:00 2001 From: rushtong Date: Thu, 7 Nov 2024 12:17:14 -0500 Subject: [PATCH 1/6] feat: add conditionals around applying for access. --- src/pages/DatasetStatistics.jsx | 119 +++++++++++++++++++------------- 1 file changed, 72 insertions(+), 47 deletions(-) diff --git a/src/pages/DatasetStatistics.jsx b/src/pages/DatasetStatistics.jsx index 7b256b3da..c1e46617f 100644 --- a/src/pages/DatasetStatistics.jsx +++ b/src/pages/DatasetStatistics.jsx @@ -1,19 +1,19 @@ import React from 'react'; -import { useCallback, useState, useEffect } from 'react'; -import { DatasetMetrics } from '../libs/ajax/DatasetMetrics'; -import { DataSet } from '../libs/ajax/DataSet'; -import { DAR } from '../libs/ajax/DAR'; -import { Notifications } from '../libs/utils'; -import { Styles, Theme } from '../libs/theme'; -import { find } from 'lodash/fp'; -import { ReadMore } from '../components/ReadMore'; -import { formatDate } from '../libs/utils'; -import { Button } from '@mui/material'; +import {useCallback, useState, useEffect} from 'react'; +import {DatasetMetrics} from '../libs/ajax/DatasetMetrics'; +import {DataSet} from '../libs/ajax/DataSet'; +import {DAR} from '../libs/ajax/DAR'; +import {Notifications} from '../libs/utils'; +import {Styles, Theme} from '../libs/theme'; +import {find} from 'lodash/fp'; +import {ReadMore} from '../components/ReadMore'; +import {formatDate} from '../libs/utils'; +import {Button} from '@mui/material'; -const LINE =
; +const LINE =
; export default function DatasetStatistics(props) { - const { history, match: { params: { datasetIdentifier }} } = props; + const {history, match: {params: {datasetIdentifier}}} = props; const [datasetId, setDatasetId] = useState(); const [dataset, setDataset] = useState(); const [dars, setDars] = useState(); @@ -21,16 +21,16 @@ export default function DatasetStatistics(props) { const applyForAccess = async () => { try { - const draftResponse = await DAR.postDarDraft({ datasetId: [datasetId] }); + const draftResponse = await DAR.postDarDraft({datasetId: [datasetId]}); if (draftResponse.referenceId) { history.push(`/dar_application/${draftResponse.referenceId}`); } else if (draftResponse.message) { - Notifications.showError({ text: draftResponse.message + ' Please contact customer support for help.' }); + Notifications.showError({text: draftResponse.message + ' Please contact customer support for help.'}); } else { - Notifications.showError({ text: 'Error: Unable to create a Draft Data Access Request' }); + Notifications.showError({text: 'Error: Unable to create a Draft Data Access Request'}); } } catch (error) { - Notifications.showError({ text: 'Error: Unable to create a Draft Data Access Request' }); + Notifications.showError({text: 'Error: Unable to create a Draft Data Access Request'}); } }; @@ -38,12 +38,12 @@ export default function DatasetStatistics(props) { DataSet.getDatasetByDatasetIdentifier(datasetIdentifier).then((dataset) => { setData(dataset.datasetId); }).catch(() => { - Notifications.showError({ text: 'Error: Unable to retrieve dataset from server' }); + Notifications.showError({text: 'Error: Unable to retrieve dataset from server'}); }); }, [datasetIdentifier]); const extract = useCallback((propertyName) => { - const property = find({ propertyName })(dataset.properties); + const property = find({propertyName})(dataset.properties); return property?.propertyValue; }, [dataset]); @@ -57,57 +57,82 @@ export default function DatasetStatistics(props) { setDars(metrics.dars); setIsLoading(false); } catch (error) { - Notifications.showError({ text: 'Error: Unable to retrieve dataset statistics from server' }); + Notifications.showError({text: 'Error: Unable to retrieve dataset statistics from server'}); setIsLoading(false); } }; + const accessButton = () => { + const accessManagement = extract('Access Management').toLowerCase(); + if (accessManagement === 'controlled') { + return ; + } + const locationUrl = extract('URL'); + if (accessManagement === 'open') { + return + This dataset is open access, does not require an access request + {locationUrl && + , and can be accessed directly through this link. + } + ; + } + if (accessManagement === 'external') { + return + This dataset is externally managed. Requests cannot be made via DUOS + {locationUrl && + , but must be made directly through the dataset's host repository. + } + ; + } + return
; + }; + if (!isLoading) { return ( -
-
-
+
+
+
Dataset Statistics
-
Dataset ID:
+
Dataset ID:
{dataset?.alias}
-
Dataset Name:
+
Dataset Name:
{extract('Dataset Name') || dataset?.name}
-
- +
+ {accessButton()}
Dataset Information
-
+
-
Dataset Description:
+
Dataset Description:
{LINE} -
- {extract('Dataset Description') || dataset?.description || dataset?.study?.description || 'N/A' } +
+ {extract('Dataset Description') || dataset?.description || dataset?.study?.description || 'N/A'}
-
-
Number of Participants:
+
+
Number of Participants:
{extract('# of participants')}
- {(extract('Principal Investigator(PI)') || dataset?.study?.piName) &&
-
Principal Investigator:
+ {(extract('Principal Investigator(PI)') || dataset?.study?.piName) &&
+
Principal Investigator:
{extract('Principal Investigator(PI)') || dataset?.study?.piName}
} - {(extract('Data Depositor') || dataset?.createUser?.displayName) &&
-
Data Custodian:
+ {(extract('Data Depositor') || dataset?.createUser?.displayName) &&
+
Data Custodian:
{extract('Data Depositor') || dataset?.createUser?.displayName}
@@ -121,24 +146,24 @@ export default function DatasetStatistics(props) { props={props} readLessText='Show less' readMoreText='Show More' - readStyle={{ fontWeight: 500, margin: '20px', height: 0 }} + readStyle={{fontWeight: 500, margin: '20px', height: 0}} content={[ -
-
{dar.darCode}
-
{dar.projectTitle}
+
+
{dar.darCode}
+
{dar.projectTitle}
, LINE ]} moreContent={[ -
-
-
Last Updated:
+
+
+
Last Updated:
{formatDate(dar.updateDate)}
, -
+
NonTechnical Summary:
-
+
{dar.nonTechRus}
, From 32cf3358f868cd075c754c5df0314f76b25f261d Mon Sep 17 00:00:00 2001 From: rushtong Date: Thu, 7 Nov 2024 12:23:53 -0500 Subject: [PATCH 2/6] fix: show the identifier, not the alias --- src/pages/DatasetStatistics.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/DatasetStatistics.jsx b/src/pages/DatasetStatistics.jsx index c1e46617f..19daf0148 100644 --- a/src/pages/DatasetStatistics.jsx +++ b/src/pages/DatasetStatistics.jsx @@ -97,7 +97,7 @@ export default function DatasetStatistics(props) {
Dataset Statistics
Dataset ID:
-
{dataset?.alias}
+
{dataset?.datasetIdentifier}
Dataset Name:
From 2269c6762b57da3bb99da5cde7d79d93489c5a43 Mon Sep 17 00:00:00 2001 From: rushtong Date: Thu, 7 Nov 2024 15:50:16 -0500 Subject: [PATCH 3/6] feat: add test cases --- cypress/component/Dataset/dataset.json | 138 +++++++++++++++ .../Dataset/datasetStatistics.spec.js | 167 ++++++++++++++++++ 2 files changed, 305 insertions(+) create mode 100644 cypress/component/Dataset/dataset.json create mode 100644 cypress/component/Dataset/datasetStatistics.spec.js diff --git a/cypress/component/Dataset/dataset.json b/cypress/component/Dataset/dataset.json new file mode 100644 index 000000000..cc2a8252f --- /dev/null +++ b/cypress/component/Dataset/dataset.json @@ -0,0 +1,138 @@ +{ + "datasetId": 1975, + "name": "ExteranlAccessTestJL1", + "datasetName": "ExteranlAccessTestJL1", + "createDate": "Nov 2, 2023", + "createUserId": 3396, + "updateDate": 1730999135936, + "updateUserId": 3351, + "alias": 682, + "datasetIdentifier": "DUOS-000682", + "dataUse": { + "generalUse": true, + "hmbResearch": false, + "diseaseRestrictions": [], + "populationOriginsAncestry": false, + "ethicsApprovalRequired": false, + "collaboratorRequired": true, + "geneticStudiesOnly": true, + "publicationResults": true, + "controls": false, + "population": false + }, + "deletable": false, + "properties": [ + { + "propertyId": 9311, + "datasetId": 1975, + "propertyName": "Data Location", + "propertyValue": "Not Determined", + "schemaProperty": "dataLocation", + "propertyType": "String" + }, + { + "propertyId": 9312, + "datasetId": 1975, + "propertyName": "# of participants", + "propertyValue": 1, + "schemaProperty": "numberOfParticipants", + "propertyType": "Number" + }, + { + "propertyId": 9313, + "datasetId": 1975, + "propertyName": "File Types", + "propertyValue": [ + {} + ], + "schemaProperty": "fileTypes", + "propertyType": "Json" + } + ], + "createUser": { + "userId": 3396, + "email": "jlawson@broadinstitute.org", + "displayName": "Jonathan Lawson (Admin \u0026 DAC Member)", + "createDate": 1526056488000, + "emailPreference": false, + "institutionId": 150, + "eraCommonsId": "a" + }, + "study": { + "studyId": 5854, + "name": "ExternalAccessTestJL1", + "description": "ExternalAccessTestJL1", + "publicVisibility": true, + "piName": "Dr. Make", + "dataTypes": [ + "Hybrid Capture" + ], + "datasetIds": [ + 1975, + 1976, + 1977 + ], + "properties": [ + { + "studyPropertyId": 5860, + "studyId": 5854, + "key": "collaboratingSites", + "type": "Json", + "value": [] + }, + { + "studyPropertyId": 5855, + "studyId": 5854, + "key": "species", + "type": "String", + "value": "ExternalAccessTestJL1" + }, + { + "studyPropertyId": 5857, + "studyId": 5854, + "key": "dataCustodianEmail", + "type": "Json", + "value": [ + "geraldg@spurs.bb" + ] + }, + { + "studyPropertyId": 5858, + "studyId": 5854, + "key": "nihAnvilUse", + "type": "String", + "value": "I am not NHGRI funded and do not plan to store data in AnVIL" + }, + { + "studyPropertyId": 5854, + "studyId": 5854, + "key": "phenotypeIndication", + "type": "String", + "value": "ExternalAccessTestJL1" + }, + { + "studyPropertyId": 5859, + "studyId": 5854, + "key": "nihICsSupportingStudy", + "type": "Json", + "value": [] + }, + { + "studyPropertyId": 5853, + "studyId": 5854, + "key": "studyType", + "type": "String", + "value": "Observational" + }, + { + "studyPropertyId": 5861, + "studyId": 5854, + "key": "alternativeDataSharingPlanReasons", + "type": "Json", + "value": [] + } + ], + "createDate": 1698897809861, + "createUserId": 3396 + } +} diff --git a/cypress/component/Dataset/datasetStatistics.spec.js b/cypress/component/Dataset/datasetStatistics.spec.js new file mode 100644 index 000000000..d08f177bd --- /dev/null +++ b/cypress/component/Dataset/datasetStatistics.spec.js @@ -0,0 +1,167 @@ +/* eslint-disable no-undef,no-console */ + +import React from 'react'; +import {mount} from 'cypress/react'; +import DatasetStatistics from '../../../src/pages/DatasetStatistics'; +import dataset from './dataset.json'; +import {DataSet} from '../../../src/libs/ajax/DataSet'; +import {DatasetMetrics} from '../../../src/libs/ajax/DatasetMetrics'; + +const externalProp = { + 'propertyId': 9314, + 'datasetId': 1975, + 'propertyName': 'Access Management', + 'propertyValue': 'external', + 'schemaProperty': 'accessManagement', + 'propertyType': 'String' +}; + +const openProp = { + 'propertyId': 9314, + 'datasetId': 1975, + 'propertyName': 'Access Management', + 'propertyValue': 'open', + 'schemaProperty': 'accessManagement', + 'propertyType': 'String' +}; + +const controlledProp = { + 'propertyId': 9314, + 'datasetId': 1975, + 'propertyName': 'Access Management', + 'propertyValue': 'controlled', + 'schemaProperty': 'accessManagement', + 'propertyType': 'String' +}; + +const location = { + 'propertyId': 12657, + 'datasetId': 1975, + 'propertyName': 'URL', + 'propertyValue': 'https://duos.org', + 'schemaProperty': 'url', + 'propertyType': 'String' +}; + +describe('Dataset Statistics Tests', () => { + + it('Displays Controlled Access Dataset Apply Button', () => { + const controlled = Object.assign(dataset, {properties: [controlledProp]}); + cy.viewport(600, 800); + cy.stub(DataSet, 'getDatasetByDatasetIdentifier').returns(Promise.resolve(controlled)); + cy.stub(DataSet, 'getDataSetsByDatasetId').returns(Promise.resolve(controlled)); + cy.stub(DatasetMetrics, 'getDatasetStats').returns(Promise.resolve({})); + + const props = { + match: { + params: { + datasetIdentifier: controlled.datasetIdentifier + } + }, + history: { + push() { + } + } + }; + mount(); + cy.contains(controlled.datasetIdentifier).should('exist'); + cy.contains('Apply for Access').should('exist'); + }); + + it('Displays External Access Language With Location', () => { + const external = Object.assign(dataset, {properties: [externalProp, location]}); + cy.viewport(600, 800); + cy.stub(DataSet, 'getDatasetByDatasetIdentifier').returns(Promise.resolve(external)); + cy.stub(DataSet, 'getDataSetsByDatasetId').returns(Promise.resolve(external)); + cy.stub(DatasetMetrics, 'getDatasetStats').returns(Promise.resolve({})); + + const props = { + match: { + params: { + datasetIdentifier: external.datasetIdentifier + } + }, + history: { + push() { + } + } + }; + mount(); + cy.contains(external.datasetIdentifier).should('exist'); + cy.contains('This dataset is externally managed').should('exist'); + cy.contains('Requests cannot be made via DUOS, but must be made directly').should('exist'); + }); + + it('Displays External Access Language Without Location', () => { + const external = Object.assign(dataset, {properties: [externalProp]}); + cy.viewport(600, 800); + cy.stub(DataSet, 'getDatasetByDatasetIdentifier').returns(Promise.resolve(external)); + cy.stub(DataSet, 'getDataSetsByDatasetId').returns(Promise.resolve(external)); + cy.stub(DatasetMetrics, 'getDatasetStats').returns(Promise.resolve({})); + + const props = { + match: { + params: { + datasetIdentifier: external.datasetIdentifier + } + }, + history: { + push() { + } + } + }; + mount(); + cy.contains(external.datasetIdentifier).should('exist'); + cy.contains('This dataset is externally managed').should('exist'); + cy.contains('Requests cannot be made via DUOS, but must be made directly').should('not.exist'); + }); + + it('Displays Open Access Language With Location', () => { + const open = Object.assign(dataset, {properties: [openProp, location]}); + cy.viewport(600, 800); + cy.stub(DataSet, 'getDatasetByDatasetIdentifier').returns(Promise.resolve(open)); + cy.stub(DataSet, 'getDataSetsByDatasetId').returns(Promise.resolve(open)); + cy.stub(DatasetMetrics, 'getDatasetStats').returns(Promise.resolve({})); + + const props = { + match: { + params: { + datasetIdentifier: open.datasetIdentifier + } + }, + history: { + push() { + } + } + }; + mount(); + cy.contains(open.datasetIdentifier).should('exist'); + cy.contains('This dataset is open access, does not require an access request').should('exist'); + cy.contains('and can be accessed directly').should('exist'); + }); + + it('Displays Open Access Language Without Location', () => { + const open = Object.assign(dataset, {properties: [openProp]}); + cy.viewport(600, 800); + cy.stub(DataSet, 'getDatasetByDatasetIdentifier').returns(Promise.resolve(open)); + cy.stub(DataSet, 'getDataSetsByDatasetId').returns(Promise.resolve(open)); + cy.stub(DatasetMetrics, 'getDatasetStats').returns(Promise.resolve({})); + + const props = { + match: { + params: { + datasetIdentifier: open.datasetIdentifier + } + }, + history: { + push() { + } + } + }; + mount(); + cy.contains(open.datasetIdentifier).should('exist'); + cy.contains('This dataset is open access, does not require an access request').should('exist'); + cy.contains('and can be accessed directly').should('not.exist'); + }); + +}); From 122a507413e1c81702a5e8458531daa2f457fd6e Mon Sep 17 00:00:00 2001 From: rushtong Date: Thu, 7 Nov 2024 15:52:17 -0500 Subject: [PATCH 4/6] feat: formatting --- cypress/component/Dataset/datasetStatistics.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/component/Dataset/datasetStatistics.spec.js b/cypress/component/Dataset/datasetStatistics.spec.js index d08f177bd..465943e64 100644 --- a/cypress/component/Dataset/datasetStatistics.spec.js +++ b/cypress/component/Dataset/datasetStatistics.spec.js @@ -34,7 +34,7 @@ const controlledProp = { 'propertyType': 'String' }; -const location = { +const location = { 'propertyId': 12657, 'datasetId': 1975, 'propertyName': 'URL', From 679e2702691b640d4daeb6978b61cd51130be9e9 Mon Sep 17 00:00:00 2001 From: rushtong Date: Fri, 8 Nov 2024 13:31:49 -0500 Subject: [PATCH 5/6] feat: use switch and enum --- src/libs/Models.ts | 6 +++++ src/pages/DatasetStatistics.jsx | 45 +++++++++++++++++---------------- 2 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 src/libs/Models.ts diff --git a/src/libs/Models.ts b/src/libs/Models.ts new file mode 100644 index 000000000..e0532b422 --- /dev/null +++ b/src/libs/Models.ts @@ -0,0 +1,6 @@ + +export enum AccessManagement { + OPEN = 'open', + CONTROLLED = 'controlled', + EXTERNAL = 'external' +} diff --git a/src/pages/DatasetStatistics.jsx b/src/pages/DatasetStatistics.jsx index 19daf0148..987f1ff86 100644 --- a/src/pages/DatasetStatistics.jsx +++ b/src/pages/DatasetStatistics.jsx @@ -9,6 +9,7 @@ import {find} from 'lodash/fp'; import {ReadMore} from '../components/ReadMore'; import {formatDate} from '../libs/utils'; import {Button} from '@mui/material'; +import {AccessManagement} from '../libs/Models.ts'; const LINE =
; @@ -62,31 +63,31 @@ export default function DatasetStatistics(props) { } }; - const accessButton = () => { + const accessInstructions = () => { const accessManagement = extract('Access Management').toLowerCase(); - if (accessManagement === 'controlled') { - return ; - } const locationUrl = extract('URL'); - if (accessManagement === 'open') { - return - This dataset is open access, does not require an access request - {locationUrl && - , and can be accessed directly through this link. - } - ; - } - if (accessManagement === 'external') { - return + switch (accessManagement) { + case AccessManagement.CONTROLLED: + return ; + case AccessManagement.OPEN: + return dataset is open access, does not require an access request + {locationUrl && + , and can be accessed directly through this link. + } + ; + case AccessManagement.EXTERNAL: + return This dataset is externally managed. Requests cannot be made via DUOS - {locationUrl && - , but must be made directly through the dataset's host repository. - } - ; + {locationUrl && + , but must be made directly through the dataset's host repository. + } + ; + default: + return
; } - return
; }; if (!isLoading) { @@ -106,7 +107,7 @@ export default function DatasetStatistics(props) {
- {accessButton()} + {accessInstructions()}
Dataset Information
From 015a22dc7b191af516f6f1aa3603479881f31a56 Mon Sep 17 00:00:00 2001 From: rushtong Date: Fri, 8 Nov 2024 13:40:47 -0500 Subject: [PATCH 6/6] fix: replace missing text --- src/pages/DatasetStatistics.jsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/DatasetStatistics.jsx b/src/pages/DatasetStatistics.jsx index 987f1ff86..174431f70 100644 --- a/src/pages/DatasetStatistics.jsx +++ b/src/pages/DatasetStatistics.jsx @@ -72,14 +72,13 @@ export default function DatasetStatistics(props) { Apply for Access ; case AccessManagement.OPEN: - return dataset is open access, does not require an access request + return This dataset is open access, does not require an access request {locationUrl && , and can be accessed directly through this link. } ; case AccessManagement.EXTERNAL: - return - This dataset is externally managed. Requests cannot be made via DUOS + return This dataset is externally managed. Requests cannot be made via DUOS {locationUrl && , but must be made directly through the dataset's host repository.