Skip to content

Commit

Permalink
[DUOS-2675][risk=no] Manually validate study name in dataset submissi…
Browse files Browse the repository at this point in the history
…ons (#2347)

* validate uniqueness for study names
  • Loading branch information
rushtong authored Oct 10, 2023
1 parent 961a2d8 commit dec217f
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-undef */
import React from 'react';
import { DAC, User, Institution, Schema } from '../../../src/libs/ajax';
import { DAC, User, Institution, Schema, Study } from '../../../src/libs/ajax';
import DataSubmissionForm from '../../../src/pages/DataSubmissionForm';
import { mount } from 'cypress/react';

Expand All @@ -22,6 +22,7 @@ beforeEach(() => {
cy.stub(User, 'getMe').returns(user);
cy.stub(Institution, 'list').returns([{name: 'Test Institution'}]);
cy.stub(Schema, 'datasetRegistrationV1').returns({});
cy.stub(Study, 'getStudyNames').returns([]);
});

describe('Data Access Governance', function () {
Expand Down
8 changes: 7 additions & 1 deletion src/components/forms/formValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ export const dateValidator = {
msg: 'Please enter a date (YYYY-MM-DD), e.g. 2018-11-13',
};

const validators = [requiredValidator, urlValidator, emailValidator, dateValidator];
export const uniqueValidator = {
id: 'unique',
isValid: (val, list) => !list.includes(val),
msg: 'Please enter a unique value that doesn\'t exist in the system'
};

const validators = [requiredValidator, urlValidator, emailValidator, dateValidator, uniqueValidator];

/**
* Validates the form value
Expand Down
10 changes: 10 additions & 0 deletions src/libs/ajax.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,16 @@ export const DataSet = {
},
};

export const Study = {

getStudyNames: async () => {
const url = `${await getApiUrl()}/api/dataset/studyNames`;
const res = await fetchOk(url, Config.authOpts());
return await res.json();
}

};

export const DatasetAssociation = {

createDatasetAssociations: async (objectId, usersIdList) => {
Expand Down
24 changes: 20 additions & 4 deletions src/pages/DataSubmissionForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { validateForm } from '../utils/JsonSchemaUtils';

import { cloneDeep, isNil } from 'lodash/fp';
import { useState, useEffect } from 'react';
import { Institution, DataSet } from '../libs/ajax';
import { Institution, DataSet, Study } from '../libs/ajax';
import { Notifications } from '../libs/utils';

import lockIcon from '../images/lock-icon.png';
Expand All @@ -14,9 +14,11 @@ import DataSubmissionStudyInformation from '../components/data_submission/ds_stu
import NIHAdministrativeInformation from '../components/data_submission/NIHAdministrativeInformation';
import NIHDataManagement from '../components/data_submission/NIHDataManagement';
import NihAnvilUse from '../components/data_submission/NihAnvilUse';
// schema validation is auto-generated from pre-compiled code - if the backend
// schama changes, then run `npm run genschemas` to regenerate this code
// Schema validation was previously auto-generated from pre-compiled code
// If any validation changes, it needs to be manually updated in both DataRegistrationV1Validation
// and JsonSchemaUtils
import validateSchema from '../assets/schemas/DataRegistrationV1Validation';
import {uniqueValidator} from '../components/forms/formValidation';
import { set } from 'lodash';
import UsgOmbText from '../components/UsgOmbText';

Expand All @@ -26,6 +28,7 @@ export const DataSubmissionForm = (props) => {
} = props;

const [institutions, setInstitutions] = useState([]);
const [studyNames, setStudyNames] = useState([]);
const [failedInit, setFailedInit] = useState(false);

const [allConsentGroupsSaved, setAllConsentGroupsSaved] = useState(false);
Expand All @@ -37,9 +40,15 @@ export const DataSubmissionForm = (props) => {
setInstitutions(institutions);
};

const getAllStudies = async() => {
const studyNames = await Study.getStudyNames();
setStudyNames(studyNames);
};

const init = async () => {
try {
getAllInstitutions();
await getAllInstitutions();
await getAllStudies();
} catch (error) {
setFailedInit(true);
Notifications.showError({
Expand Down Expand Up @@ -100,6 +109,13 @@ export const DataSubmissionForm = (props) => {

// check against json schema to see if there are uncaught validation issues
let [valid, validation] = validateForm(validateSchema, registration);
if (!uniqueValidator.isValid(registration.studyName, studyNames)) {
validation.studyName = {
failed: ['unique'],
valid: false
};
}

if (formData.alternativeDataSharingPlan === true) {
if (isNil(formFiles.alternativeDataSharingPlanFile)) {
validation.alternativeDataSharingPlanFile = {
Expand Down

0 comments on commit dec217f

Please sign in to comment.