Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
s-rubenstein committed Dec 11, 2024
1 parent b9c97e7 commit 1816c1f
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 34 deletions.
50 changes: 48 additions & 2 deletions cypress/component/DataSearch/dataset_search_filters.spec.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,44 @@
/* eslint-disable no-undef */

import { mount } from 'cypress/react';
import { makeDatasetTerm, makeStudyTerm } from '../test-utils';
import { mount } from 'cypress/react18';
import React from 'react';
import { defaultFilters } from '../../../src/components/data_search/DatasetFilterConstants';
import DatasetFilterList from '../../../src/components/data_search/DatasetFilterList';

const datasets = [
makeDatasetTerm({
datasetId: 123456,
datasetIdentifier: `DUOS-123456`,
datasetName: 'Some Dataset 1',
participantCount: 100,
study: makeStudyTerm({
studyName: 'Some Study 1',
studyId: 1,
dataCustodianEmail: ['Some Data Custodian Email 1'],
})
}),
makeDatasetTerm({
datasetId: 123457,
datasetIdentifier: `DUOS-123457`,
datasetName: 'Some Dataset 2',
participantCount: 2,
study: makeStudyTerm({
studyName: 'Some Study 1',
studyId: 1,
dataCustodianEmail: ['Some Data Custodian Email 1'],
})
})
];

describe('Data Library Filters', () => {
// Intercept configuration calls
beforeEach(() => {
cy.initApplicationConfig();
});

it('Renders the data library filters', () => {
const props = { datasets: [], filterHandler: () => {}, isFiltered: () => {}};
const props = { datasets, filters: defaultFilters(datasets), filterHandler: () => {}, isFiltered: () => {}};
mount(<DatasetFilterList {...props} />);
cy.get('div').should('contain', 'Filters');
cy.get('div').should('contain', 'Access Type');
Expand All @@ -20,4 +47,23 @@ describe('Data Library Filters', () => {
cy.get('div').should('contain', 'Data Type');
cy.get('div').should('contain', 'Participant Count');
});

it('initially defaults to minimum and maximum participant counts in datasets', () => {
const props = { datasets, filters: defaultFilters(datasets), filterHandler: () => {}, isFiltered: () => {}};
mount(<DatasetFilterList {...props} />);
cy.get('#participantCountMax-range-input').should('have.value',
datasets[0].participantCount);
cy.get('#participantCountMin-range-input').should('have.value',
datasets[1].participantCount);
});

it('calls the filter handler on range changes', () => {
const filterHandlerStub = cy.stub();
const props = { datasets, filters: { ...defaultFilters(datasets), participantCountMin: 2, participantCountMax: 5 }, filterHandler: filterHandlerStub, isFiltered: () => {}};
mount(<DatasetFilterList {...props} />);
cy.get('#participantCountMax-range-input').type('3').trigger('change');
filterHandlerStub.calledWith('participantCountMax', 53);
cy.get('#participantCountMin-range-input').type('3').trigger('change');
filterHandlerStub.calledWith('participantCountMin', 23);
});
});
56 changes: 56 additions & 0 deletions cypress/component/test-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {DatasetTerm, StudyTerm, UserTerm} from '../../src/types/model';

export const makeUserTerm = (overrides: Partial<UserTerm> = {}): UserTerm => ({
userId: 0,
displayName: 'some name',
institution: {
id: 0,
name: 'some name',
},
...overrides,
});

export const makeStudyTerm = (overrides: Partial<StudyTerm> = {}): StudyTerm => ({
description: 'description',
studyName: 'name',
studyId: 0,
phsId: 'phsid',
phenotype: 'phenotype',
species: 'species',
piName: 'pi name',
dataSubmitterEmail: 'data submitter email',
dataSubmitterId: 0,
dataCustodianEmail: ['data custodian email'],
publicVisibility: false,
dataTypes: ['data type'],
...overrides
});

export const makeDatasetTerm = (overrides: Partial<DatasetTerm> = {}): DatasetTerm => ({
datasetId: 0,
createUserId: 0,
createUserDisplayName: 'user',
datasetIdentifier: 'DUOS-123456',
deletable: true,
datasetName: 'dataset',
participantCount: 1,
dataUse: {
primary: [{code: 'foo', description: 'bar'}],
secondary: [{code: 'foo', description: 'bar'}]
},
dataLocation: 'somewhere',
url: 'some url',
dacId: 0,
dacApproval: true,
accessManagement: 'access',
approvedUserIds: [0],
study: makeStudyTerm(),
submitter: makeUserTerm(),
updateUser: makeUserTerm(),
dac: {
dacId: 0,
dacName: 'some name',
dacEmail: 'some email',
},
...overrides
});
28 changes: 28 additions & 0 deletions src/components/data_search/DatasetFilterConstants.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {DatasetTerm} from '../../types/model';

export interface FiltersTypes {
accessManagement: string[],
dataUse: string[],
dataType: string[],
dac: string[],
participantCountMin?: number,
participantCountMax?: number,
}

export const defaultFilters = (datasets: DatasetTerm[]): FiltersTypes => {
const defaultParticipantCountValues = generateDefaultParticipantCountValues(datasets);
return {
accessManagement: [],
dataUse: [],
dataType: [],
dac: [],
participantCountMin: defaultParticipantCountValues.min,
participantCountMax: defaultParticipantCountValues.max,
};
};

export const generateDefaultParticipantCountValues = (datasets: DatasetTerm[]) => datasets.reduce((acc, dataset) => {
return {
max: Math.max(acc.max, dataset.participantCount ? dataset.participantCount : 0),
min: Math.min(acc.min, dataset.participantCount ? dataset.participantCount : Infinity) };
}, {max: 0, min: Infinity});
41 changes: 23 additions & 18 deletions src/components/data_search/DatasetFilterList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Divider from '@mui/material/Divider';
import { Button, Checkbox, TextField, Typography } from '@mui/material';
import { flatten, uniq, compact, orderBy } from 'lodash';
import {DatasetTerm, getAccessManagementSummary} from '../../types/model';
import {FiltersTypes, generateDefaultParticipantCountValues} from './DatasetFilterConstants';

interface FilterItemHeaderProps {
title: React.ReactNode;
Expand Down Expand Up @@ -57,28 +58,33 @@ export const FilterItemList = (props: FilterItemListProps) => {
};

interface FilterItemRangeProps {
min: number;
max: number;
allowableMin: number;
allowableMax: number;
min?: number;
max?: number;
minCategory: string;
maxCategory: string;
filterHandler: (category: string, filter: string) => void;
}

export const FilterItemRange = (props: FilterItemRangeProps) => {
const { min, max, minCategory, maxCategory, filterHandler } = props;
const getValue = (val: any, defaultVal: any) => isNaN(Number(val)) ? defaultVal : Number(val);
const { allowableMin, allowableMax, min, max, minCategory, maxCategory, filterHandler } = props;
const inputProps = { max: allowableMax, min: allowableMin };
return (
<Box key={minCategory + '-' + maxCategory} sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
<TextField id={minCategory + '-range-input'} size='small' margin='dense' variant='outlined' defaultValue={min}
<TextField type={'number'} value={min} id={minCategory + '-range-input'}
size='small' margin='dense' variant='outlined'
helperText={'minimum'}
FormHelperTextProps={{style: { transform: 'scale(1.5)' }}}
onChange={(event) => filterHandler(minCategory, getValue(event.target.value, min))}/>
inputProps={inputProps}
onChange={(event) => filterHandler(minCategory, event.target.value)}/>
<Box padding={'0rem 1rem 1rem'}> - </Box>
<TextField id={maxCategory + '-range-input'} size='small' margin='dense' variant='outlined' defaultValue={max}
<TextField type={'number'} value={max} id={maxCategory + '-range-input'}
size='small' margin='dense' variant='outlined'
helperText={'maximum'}
FormHelperTextProps={{style: {transform: 'scale(1.5)'}}}
onChange={(event) => filterHandler(maxCategory, getValue(event.target.value, max))}
/>
FormHelperTextProps={{style: { transform: 'scale(1.5)' }}}
inputProps={inputProps}
onChange={(event) => filterHandler(maxCategory, event.target.value)}/>
</Box>
);
};
Expand All @@ -87,20 +93,17 @@ interface DatasetFilterListProps {
datasets: DatasetTerm[];
filterHandler: (category: string, filter: string) => void;
isFiltered: (filter: string, category: string) => boolean;
filters: FiltersTypes
onClear: () => void;
}
export const DatasetFilterList = (props: DatasetFilterListProps) => {
const { datasets, filterHandler, isFiltered, onClear } = props;
const { datasets, filterHandler, filters, isFiltered, onClear } = props;

const accessManagementFilters = uniq(compact(datasets.map((dataset) => dataset.accessManagement)));
const dataUseFilters = uniq(compact(flatten(datasets.map((dataset) => dataset.dataUse?.primary))).map((dataUse) => dataUse.code));
const dataTypeFilters = uniq(flatten(datasets.map((dataset) => dataset.study.dataTypes)));
const dacFilters = orderBy(uniq(compact(datasets.map((dataset) => dataset.dac?.dacName))), (dac) => dac.toLowerCase(), 'asc');
const defaultValues = datasets.reduce((acc, dataset) => {
return {
max: Math.max(acc.max, dataset.participantCount ? dataset.participantCount : 0),
min: Math.min(acc.min, dataset.participantCount ? dataset.participantCount : Infinity) };
}, {max: 0, min: Infinity});
const defaultValues = generateDefaultParticipantCountValues(datasets);
return (
<Box sx={{ bgcolor: 'background.paper' }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
Expand Down Expand Up @@ -156,8 +159,10 @@ export const DatasetFilterList = (props: DatasetFilterListProps) => {
/>
<FilterItemHeader title='Participant Count' />
<FilterItemRange
min={defaultValues.min}
max={defaultValues.max}
allowableMin={defaultValues.min}
allowableMax={defaultValues.max}
min={filters.participantCountMin}
max={filters.participantCountMax}
minCategory='participantCountMin'
maxCategory='participantCountMax'
filterHandler={filterHandler}
Expand Down
16 changes: 3 additions & 13 deletions src/components/data_search/DatasetSearchTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as React from 'react';
import { Box, Button } from '@mui/material';
import {useEffect, useRef, useState} from 'react';
import { isArray, isEmpty } from 'lodash';
import { defaultFilters } from './DatasetFilterConstants';
import { TerraDataRepo } from '../../libs/ajax/TerraDataRepo';
import { DatasetSearchTableDisplay } from './DatasetSearchTableDisplay';
import { datasetSearchTableTabs } from './DatasetSearchTableConstants';
Expand Down Expand Up @@ -46,21 +47,10 @@ export const applyForAccess = async (selected, history) => {
}
};



const defaultFilters = {
accessManagement: [],
dataUse: [],
dataType: [],
dac: [],
participantCountMin: null,
participantCountMax: null,
};

export const DatasetSearchTable = (props) => {
const { datasets, history, icon, title } = props;
const [exportableDatasets, setExportableDatasets] = useState({});
const [filters, setFilters] = useState(_.clone(defaultFilters));
const [filters, setFilters] = useState(defaultFilters(datasets));
const [filtered, setFiltered] = useState(datasets);
const [selected, setSelected] = useState([]);
const [selectedTable, setSelectedTable] = useState(datasetSearchTableTabs.study);
Expand Down Expand Up @@ -303,7 +293,7 @@ export const DatasetSearchTable = (props) => {
</Box>
<Box sx={{display: 'flex', flexDirection: 'row', paddingTop: '2em'}}>
<Box sx={{width: '14%', padding: '0 1em'}}>
<DatasetFilterList datasets={datasets} filterHandler={filterHandler} isFiltered={isFilteredArray} onClear={() => setFilters(defaultFilters)}/>
<DatasetFilterList datasets={datasets} filterHandler={filterHandler} filters={filters} isFiltered={isFilteredArray} onClear={() => setFilters(defaultFilters(datasets))}/>
</Box>
<Box sx={{width: '85%', padding: '0 1em'}}>
{(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/types/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ interface InstitutionTerm {
name: string;
}

interface UserTerm {
export interface UserTerm {
userId: number;
displayName: string;
institution: InstitutionTerm;
Expand Down

0 comments on commit 1816c1f

Please sign in to comment.