Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • minerva/frontend
1 result
Show changes
Commits on Source (2)
Showing
with 444 additions and 261 deletions
......@@ -39,8 +39,8 @@ export const CheckboxFilter = ({
};
const handleCheckboxChange = (option: CheckboxItem): void => {
const newCheckedCheckboxes = checkedCheckboxes.includes(option)
? checkedCheckboxes.filter(item => item !== option)
const newCheckedCheckboxes = checkedCheckboxes.some(item => item.id === option.id)
? checkedCheckboxes.filter(item => item.id !== option.id)
: [...checkedCheckboxes, option];
setCheckedCheckboxes(newCheckedCheckboxes);
......
/* eslint-disable no-magic-numbers */
import { AppDispatch, RootState } from '@/redux/store';
import { InitialStoreState } from '@/utils/testing/getReduxWrapperWithStore';
import { render, screen } from '@testing-library/react';
import { CONFIGURATION_INITIAL_STORE_MOCK } from '@/redux/configuration/configuration.mock';
import { configurationFixture } from '@/models/fixtures/configurationFixture';
import { act } from 'react-dom/test-utils';
import { statisticsFixture } from '@/models/fixtures/statisticsFixture';
import { compartmentPathwaysDetailsFixture } from '@/models/fixtures/compartmentPathways';
import { MockStoreEnhanced } from 'redux-mock-store';
import { getReduxStoreWithActionsListener } from '@/utils/testing/getReduxStoreActionsListener';
import { modelsFixture } from '@/models/fixtures/modelsFixture';
import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse';
import { apiPath } from '@/redux/apiPath';
import { HttpStatusCode } from 'axios';
import { Elements } from './Elements.component';
import { ELEMENTS_COLUMNS } from '../ExportCompound/ExportCompound.constant';
const mockedAxiosClient = mockNetworkNewAPIResponse();
const renderComponent = (
initialStore?: InitialStoreState,
): { store: MockStoreEnhanced<Partial<RootState>, AppDispatch> } => {
const { Wrapper, store } = getReduxStoreWithActionsListener(initialStore);
return (
render(
<Wrapper>
<Elements />
</Wrapper>,
),
{
store,
}
);
};
describe('Elements - component', () => {
it('should render all elements sections', () => {
renderComponent({
configuration: {
...CONFIGURATION_INITIAL_STORE_MOCK,
main: {
...CONFIGURATION_INITIAL_STORE_MOCK.main,
data: {
...configurationFixture,
miriamTypes: {
compartment_label: {
commonName: 'Compartment',
homepage: '',
registryIdentifier: '',
uris: [''],
},
},
},
},
},
statistics: {
data: {
...statisticsFixture,
elementAnnotations: {
compartment_label: 1,
pathway: 0,
},
},
loading: 'succeeded',
error: {
message: '',
name: '',
},
},
compartmentPathways: {
data: compartmentPathwaysDetailsFixture,
loading: 'succeeded',
error: {
message: '',
name: '',
},
},
});
const annotations = screen.getByText('Select annotations');
const includedCompartmentPathways = screen.getByText('Select included compartment / pathways');
const excludedCompartmentPathways = screen.getByText('Select excluded compartment / pathways');
const downloadButton = screen.getByText('Download');
expect(annotations).toBeVisible();
expect(includedCompartmentPathways).toBeVisible();
expect(excludedCompartmentPathways).toBeVisible();
expect(downloadButton).toBeVisible();
});
it('should handle download button click and dispatch proper data', async () => {
mockedAxiosClient.onPost(apiPath.downloadElementsCsv()).reply(HttpStatusCode.Ok, 'test');
const FIRST_COMPARMENT_PATHWAY_NAME = compartmentPathwaysDetailsFixture[0].name;
const FIRST_COMPARMENT_PATHWAY_ID = compartmentPathwaysDetailsFixture[0].id;
const SECOND_COMPARMENT_PATHWAY_NAME = compartmentPathwaysDetailsFixture[1].name;
const SECOND_COMPARMENT_PATHWAY_ID = compartmentPathwaysDetailsFixture[1].id;
const { store } = renderComponent({
configuration: {
...CONFIGURATION_INITIAL_STORE_MOCK,
main: {
...CONFIGURATION_INITIAL_STORE_MOCK.main,
data: {
...configurationFixture,
miriamTypes: {
compartment_label: {
commonName: 'Compartment',
homepage: '',
registryIdentifier: '',
uris: [''],
},
},
},
},
},
statistics: {
data: {
...statisticsFixture,
elementAnnotations: {
compartment_label: 1,
pathway: 0,
},
},
loading: 'succeeded',
error: {
message: '',
name: '',
},
},
compartmentPathways: {
data: compartmentPathwaysDetailsFixture,
loading: 'succeeded',
error: {
message: '',
name: '',
},
},
models: {
data: modelsFixture,
loading: 'succeeded',
error: {
message: '',
name: '',
},
},
});
const annotations = screen.getByText('Select annotations');
await act(() => {
annotations.click();
});
const annotationInput = screen.getByLabelText('Compartment');
await act(() => {
annotationInput.click();
});
expect(annotationInput).toBeChecked();
const includedCompartmentPathways = screen.getByText('Select included compartment / pathways');
await act(() => {
includedCompartmentPathways.click();
});
const includedCompartmentPathwaysInput = screen.getAllByLabelText(
FIRST_COMPARMENT_PATHWAY_NAME,
)[0];
await act(() => {
includedCompartmentPathwaysInput.click();
});
expect(includedCompartmentPathwaysInput).toBeChecked();
const excludedCompartmentPathways = screen.getByText('Select excluded compartment / pathways');
await act(() => {
excludedCompartmentPathways.click();
});
const excludedCompartmentPathwaysInput = screen.getAllByLabelText(
SECOND_COMPARMENT_PATHWAY_NAME,
)[1];
await act(() => {
excludedCompartmentPathwaysInput.click();
});
expect(excludedCompartmentPathwaysInput).toBeChecked();
const downloadButton = screen.getByText('Download');
await act(() => {
downloadButton.click();
});
const actions = store.getActions();
const firstAction = actions[0];
expect(firstAction.meta.arg).toEqual({
columns: ELEMENTS_COLUMNS,
submaps: modelsFixture.map(item => item.idObject),
annotations: ['compartment_label'],
includedCompartmentIds: [FIRST_COMPARMENT_PATHWAY_ID],
excludedCompartmentIds: [SECOND_COMPARMENT_PATHWAY_ID],
});
});
});
import { Export } from '../ExportCompound';
import { ANNOTATIONS_TYPE } from '../ExportCompound/ExportCompound.constant';
export const Elements = (): React.ReactNode => {
return (
<div data-testid="elements-tab">
<Export>
<Export.Types />
<Export.Columns />
<Export.Annotations />
<Export.Annotations type={ANNOTATIONS_TYPE.ELEMENTS} />
<Export.IncludedCompartmentPathways />
<Export.ExcludedCompartmentPathways />
<Export.DownloadElements />
......
......@@ -6,7 +6,10 @@ import {
import { StoreType } from '@/redux/store';
import { statisticsFixture } from '@/models/fixtures/statisticsFixture';
import { act } from 'react-dom/test-utils';
import { CONFIGURATION_INITIAL_STORE_MOCK } from '@/redux/configuration/configuration.mock';
import { configurationFixture } from '@/models/fixtures/configurationFixture';
import { Annotations } from './Annotations.component';
import { ANNOTATIONS_TYPE } from '../ExportCompound.constant';
const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
......@@ -14,7 +17,7 @@ const renderComponent = (initialStoreState: InitialStoreState = {}): { store: St
return (
render(
<Wrapper>
<Annotations />
<Annotations type={ANNOTATIONS_TYPE.ELEMENTS} />
</Wrapper>,
),
{
......@@ -26,11 +29,28 @@ const renderComponent = (initialStoreState: InitialStoreState = {}): { store: St
describe('Annotations - component', () => {
it('should display annotations checkboxes when fetching data is successful', async () => {
renderComponent({
configuration: {
...CONFIGURATION_INITIAL_STORE_MOCK,
main: {
...CONFIGURATION_INITIAL_STORE_MOCK.main,
data: {
...configurationFixture,
miriamTypes: {
compartment_label: {
commonName: 'Compartment',
homepage: '',
registryIdentifier: '',
uris: [''],
},
},
},
},
},
statistics: {
data: {
...statisticsFixture,
elementAnnotations: {
compartment: 1,
compartment_label: 1,
pathway: 0,
},
},
......@@ -54,7 +74,7 @@ describe('Annotations - component', () => {
await waitFor(() => {
expect(screen.getByTestId('checkbox-filter')).toBeInTheDocument();
expect(screen.getByLabelText('compartment')).toBeInTheDocument();
expect(screen.getByLabelText('Compartment')).toBeInTheDocument();
expect(screen.getByLabelText('search-input')).toBeInTheDocument();
});
});
......
import { useContext } from 'react';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import {
elementAnnotationsSelector,
loadingStatisticsSelector,
statisticsDataSelector,
} from '@/redux/statistics/statistics.selectors';
import { ZERO } from '@/constants/common';
import { miramiTypesSelector } from '@/redux/configuration/configuration.selectors';
import { CheckboxFilter } from '../../CheckboxFilter';
import { CollapsibleSection } from '../../CollapsibleSection';
import { ExportContext } from '../ExportCompound.context';
import { getAnnotationsCheckboxElements } from './Annotations.utils';
import { AnnotationsType } from './Annotations.types';
export const Annotations = (): React.ReactNode => {
type AnnotationsProps = {
type: AnnotationsType;
};
export const Annotations = ({ type }: AnnotationsProps): React.ReactNode => {
const { setAnnotations } = useContext(ExportContext);
const loadingStatistics = useAppSelector(loadingStatisticsSelector);
const elementAnnotations = useAppSelector(elementAnnotationsSelector);
const statistics = useAppSelector(statisticsDataSelector);
const miramiTypes = useAppSelector(miramiTypesSelector);
const isPending = loadingStatistics === 'pending';
const mappedElementAnnotations = elementAnnotations
? Object.keys(elementAnnotations)?.map(el => ({ id: el, label: el }))
: [];
const checkboxElements = getAnnotationsCheckboxElements({ type, statistics, miramiTypes });
return (
<CollapsibleSection title="Select annotations">
{isPending && <p>Loading...</p>}
{!isPending && mappedElementAnnotations && mappedElementAnnotations.length > ZERO && (
<CheckboxFilter options={mappedElementAnnotations} onCheckedChange={setAnnotations} />
{!isPending && checkboxElements && checkboxElements.length > ZERO && (
<CheckboxFilter options={checkboxElements} onCheckedChange={setAnnotations} />
)}
</CollapsibleSection>
);
......
import { ANNOTATIONS_TYPE } from '../ExportCompound.constant';
export type AnnotationsType = (typeof ANNOTATIONS_TYPE)[keyof typeof ANNOTATIONS_TYPE];
import { getAnnotationsCheckboxElements } from './Annotations.utils';
describe('getAnnotationsCheckboxElements', () => {
const statisticsMock = {
elementAnnotations: {
chebi: 2,
mesh: 0,
reactome: 1,
},
publications: 1234,
reactionAnnotations: {
brenda: 0,
reactome: 3,
rhea: 1,
},
};
const miramiTypeMock = {
commonName: 'Name',
homepage: '',
registryIdentifier: '',
uris: [''],
};
const miramiTypesMock = {
chebi: {
...miramiTypeMock,
commonName: 'Chebi',
},
mesh: {
...miramiTypeMock,
commonName: 'MeSH',
},
reactome: {
...miramiTypeMock,
commonName: 'Reactome',
},
rhea: {
...miramiTypeMock,
commonName: 'Rhea',
},
brenda: {
...miramiTypeMock,
commonName: 'BRENDA',
},
gene_ontology: {
...miramiTypeMock,
commonName: 'Gene Ontology',
},
};
it('returns an empty array when statistics or miramiTypes are undefined', () => {
const result = getAnnotationsCheckboxElements({
type: 'Elements',
statistics: undefined,
miramiTypes: undefined,
});
expect(result).toEqual([]);
});
it('returns checkbox elements for element annotations sorted by label', () => {
const result = getAnnotationsCheckboxElements({
type: 'Elements',
statistics: statisticsMock,
miramiTypes: miramiTypesMock,
});
expect(result).toEqual([
{ id: 'chebi', label: 'Chebi' },
{ id: 'reactome', label: 'Reactome' },
]);
});
it('returns checkbox elements for reaction annotations sorted by count', () => {
const result = getAnnotationsCheckboxElements({
type: 'Network',
statistics: statisticsMock,
miramiTypes: miramiTypesMock,
});
expect(result).toEqual([
{ id: 'reactome', label: 'Reactome' },
{ id: 'rhea', label: 'Rhea' },
]);
});
it('returns an empty array when no annotations have count greater than 0', () => {
const statisticsMockEmpty = {
elementAnnotations: { annotation1: 0, annotation2: 0 },
publications: 0,
reactionAnnotations: { annotation1: 0, annotation2: 0 },
};
const result = getAnnotationsCheckboxElements({
type: 'Elements',
statistics: statisticsMockEmpty,
miramiTypes: miramiTypesMock,
});
expect(result).toEqual([]);
});
});
/* eslint-disable no-magic-numbers */
import { ConfigurationMiramiTypes, Statistics } from '@/types/models';
import { ANNOTATIONS_TYPE } from '../ExportCompound.constant';
import { AnnotationsType } from './Annotations.types';
type CheckboxElement = { id: string; label: string };
type CheckboxElements = CheckboxElement[];
type GetAnnotationsCheckboxElements = {
type: AnnotationsType;
statistics: Statistics | undefined;
miramiTypes: ConfigurationMiramiTypes | undefined;
};
const sortByCount = (countA: number, countB: number): number => {
return countA > countB ? -1 : 1;
};
const mapToCheckboxElement = (
annotation: string,
miramiTypes: ConfigurationMiramiTypes,
): CheckboxElement => ({
id: annotation,
label: miramiTypes[annotation].commonName,
});
const filterAnnotationsByCount = (annotations: Record<string, number>): string[] => {
return Object.keys(annotations).filter(annotation => annotations[annotation] > 0);
};
export const getAnnotationsCheckboxElements = ({
type,
statistics,
miramiTypes,
}: GetAnnotationsCheckboxElements): CheckboxElements => {
if (!statistics || !miramiTypes) return [];
const annotations =
type === ANNOTATIONS_TYPE.ELEMENTS
? statistics.elementAnnotations
: statistics.reactionAnnotations;
const availableAnnotations = filterAnnotationsByCount(annotations);
return availableAnnotations
.sort((firstAnnotation, secondAnnotation) =>
sortByCount(annotations[firstAnnotation], annotations[secondAnnotation]),
)
.map(annotation => mapToCheckboxElement(annotation, miramiTypes));
};
import { render, screen } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { Columns } from './Columns.component';
describe('Columns - component', () => {
it('should display select column accordion', async () => {
render(<Columns />);
expect(screen.getByText('Select column')).toBeInTheDocument();
expect(screen.queryByTestId('checkbox-filter')).not.toBeVisible();
});
it('should display columns checkboxes', async () => {
render(<Columns />);
expect(screen.getByText('Select column')).toBeInTheDocument();
expect(screen.queryByTestId('checkbox-filter')).not.toBeVisible();
const navigationButton = screen.getByTestId('accordion-item-button');
act(() => {
navigationButton.click();
});
expect(screen.queryByTestId('checkbox-filter')).toBeVisible();
expect(screen.queryByLabelText('References')).toBeVisible();
});
});
import { useContext } from 'react';
import { CheckboxFilter } from '../../CheckboxFilter';
import { CollapsibleSection } from '../../CollapsibleSection';
import { COLUMNS } from './Columns.constants';
import { ExportContext } from '../ExportCompound.context';
export const Columns = (): React.ReactNode => {
const { setColumns } = useContext(ExportContext);
return (
<CollapsibleSection title="Select column">
<CheckboxFilter options={COLUMNS} isSearchEnabled={false} onCheckedChange={setColumns} />
</CollapsibleSection>
);
};
export const COLUMNS = [
{
id: 'id',
label: 'ID',
},
{
id: 'description',
label: 'Description',
},
{
id: 'modelId',
label: 'Map id',
},
{
id: 'mapName',
label: 'Map name',
},
{
id: 'symbol',
label: 'Symbol',
},
{
id: 'abbreviation',
label: 'Abbreviation',
},
{
id: 'synonyms',
label: 'Synonyms',
},
{
id: 'references',
label: 'References',
},
{
id: 'name',
label: 'Name',
},
{
id: 'type',
label: 'Type',
},
{
id: 'complexId',
label: 'Complex id',
},
{
id: 'complexName',
label: 'Complex name',
},
{
id: 'compartmentId',
label: 'Compartment/Pathway id',
},
{
id: 'compartmentName',
label: 'Compartment/Pathway name',
},
{
id: 'charge',
label: 'Charge',
},
{
id: 'fullName',
label: 'Full name',
},
{
id: 'formula',
label: 'Formula',
},
{
id: 'formerSymbols',
label: 'Former symbols',
},
{
id: 'linkedSubmodelId',
label: 'Linked submap id',
},
{
id: 'elementId',
label: 'Element external id',
},
{
id: 'ALL',
label: 'All',
},
];
export { Columns } from './Columns.component';
......@@ -15,7 +15,7 @@ export const ExcludedCompartmentPathways = (): React.ReactNode => {
const loadingCompartmentPathways = useAppSelector(loadingCompartmentPathwaysSelector);
const isPending = loadingCompartmentPathways === 'pending';
const compartmentPathways = useAppSelector(compartmentPathwaysDataSelector);
const checkboxElements = getCompartmentPathwaysCheckboxElements(compartmentPathways);
const checkboxElements = getCompartmentPathwaysCheckboxElements('excluded', compartmentPathways);
const isCheckboxFilterVisible = !isPending && checkboxElements && checkboxElements.length > ZERO;
return (
......
import { ReactNode, useCallback, useMemo, useState } from 'react';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { modelsIdsSelector } from '@/redux/models/models.selectors';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { downloadElements } from '@/redux/export/export.thunks';
import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.component';
import { Types } from './Types';
import { Columns } from './Columns';
import { Annotations } from './Annotations';
import { ExcludedCompartmentPathways } from './ExcludedCompartmentPathways';
import { IncludedCompartmentPathways } from './IncludedCompartmentPathways ';
......@@ -11,14 +11,14 @@ import { DownloadElements } from './DownloadElements/DownloadElements';
import { ExportContext } from './ExportCompound.context';
import { getNetworkDownloadBodyRequest } from './utils/getNetworkBodyRequest';
import { getDownloadElementsBodyRequest } from './utils/getDownloadElementsBodyRequest';
import { ELEMENTS_COLUMNS } from './ExportCompound.constant';
type ExportProps = {
children: ReactNode;
};
export const Export = ({ children }: ExportProps): JSX.Element => {
const [types, setTypes] = useState<CheckboxItem[]>([]);
const [columns, setColumns] = useState<CheckboxItem[]>([]);
const dispatch = useAppDispatch();
const [annotations, setAnnotations] = useState<CheckboxItem[]>([]);
const modelIds = useAppSelector(modelsIdsSelector);
const [includedCompartmentPathways, setIncludedCompartmentPathways] = useState<CheckboxItem[]>(
......@@ -28,23 +28,17 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
[],
);
const handleDownloadElements = useCallback(() => {
getDownloadElementsBodyRequest({
types,
columns,
const handleDownloadElements = useCallback(async () => {
const body = getDownloadElementsBodyRequest({
columns: ELEMENTS_COLUMNS,
modelIds,
annotations,
includedCompartmentPathways,
excludedCompartmentPathways,
});
}, [
types,
columns,
modelIds,
annotations,
includedCompartmentPathways,
excludedCompartmentPathways,
]);
dispatch(downloadElements(body));
}, [modelIds, annotations, includedCompartmentPathways, excludedCompartmentPathways, dispatch]);
const handleDownloadNetwork = useCallback(() => {
getNetworkDownloadBodyRequest();
......@@ -52,8 +46,6 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
const globalContextValue = useMemo(
() => ({
setTypes,
setColumns,
setAnnotations,
setIncludedCompartmentPathways,
setExcludedCompartmentPathways,
......@@ -66,8 +58,6 @@ export const Export = ({ children }: ExportProps): JSX.Element => {
return <ExportContext.Provider value={globalContextValue}>{children}</ExportContext.Provider>;
};
Export.Types = Types;
Export.Columns = Columns;
Export.Annotations = Annotations;
Export.IncludedCompartmentPathways = IncludedCompartmentPathways;
Export.ExcludedCompartmentPathways = ExcludedCompartmentPathways;
......
export const ANNOTATIONS_TYPE = {
ELEMENTS: 'Elements',
NETWORK: 'Network',
} as const;
export const COLUMNS_TYPE = {
ELEMENTS: 'Elements',
NETWORK: 'Network',
} as const;
export const ELEMENTS_COLUMNS = [
'id',
'type',
'name',
'symbol',
'abbreviation',
'fullName',
'synonyms',
'formerSymbols',
'complexId',
'complexName',
'compartmentId',
'compartmentName',
'modelId',
'mapName',
'description',
'references',
'charge',
'formula',
'linkedSubmodelId',
'elementId',
];
......@@ -2,8 +2,6 @@ import { createContext } from 'react';
import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.component';
export type ExportContextType = {
setTypes: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
setColumns: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
setAnnotations: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
setIncludedCompartmentPathways: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
setExcludedCompartmentPathways: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
......@@ -12,8 +10,6 @@ export type ExportContextType = {
};
export const ExportContext = createContext<ExportContextType>({
setTypes: () => {},
setColumns: () => {},
setAnnotations: () => {},
setIncludedCompartmentPathways: () => {},
setExcludedCompartmentPathways: () => {},
......
......@@ -15,7 +15,7 @@ export const IncludedCompartmentPathways = (): React.ReactNode => {
const loadingCompartmentPathways = useAppSelector(loadingCompartmentPathwaysSelector);
const isPending = loadingCompartmentPathways === 'pending';
const compartmentPathways = useAppSelector(compartmentPathwaysDataSelector);
const checkboxElements = getCompartmentPathwaysCheckboxElements(compartmentPathways);
const checkboxElements = getCompartmentPathwaysCheckboxElements('included', compartmentPathways);
return (
<CollapsibleSection title="Select included compartment / pathways">
......
import { render, screen } from '@testing-library/react';
import {
InitialStoreState,
getReduxWrapperWithStore,
} from '@/utils/testing/getReduxWrapperWithStore';
import { StoreType } from '@/redux/store';
import { Types } from './Types.component';
const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
return (
render(
<Wrapper>
<Types />
</Wrapper>,
),
{
store,
}
);
};
describe('Types Component', () => {
test('renders without crashing', () => {
renderComponent();
expect(screen.getByText('Select types')).toBeInTheDocument();
});
});
import { useContext } from 'react';
import { elementTypesSelector } from '@/redux/configuration/configuration.selectors';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { getCheckboxElements } from './Types.utils';
import { CheckboxFilter } from '../../CheckboxFilter';
import { CollapsibleSection } from '../../CollapsibleSection';
import { ExportContext } from '../ExportCompound.context';
export const Types = (): React.ReactNode => {
const { setTypes } = useContext(ExportContext);
const elementTypes = useAppSelector(elementTypesSelector);
const checkboxElements = getCheckboxElements(elementTypes);
return (
<CollapsibleSection title="Select types">
{checkboxElements && (
<CheckboxFilter
options={checkboxElements}
isSearchEnabled={false}
onCheckedChange={setTypes}
/>
)}
</CollapsibleSection>
);
};
import { getCheckboxElements } from './Types.utils';
describe('getCheckboxElements', () => {
it('should return an empty array when elementTypes is undefined', () => {
const result = getCheckboxElements(undefined);
expect(result).toEqual([]);
});
it('should map elementTypes to MappedElementTypes and exclude duplicates based on name and parentClass', () => {
const elementTypes = [
{ className: 'class1', name: 'type1', parentClass: 'parent1' },
{ className: 'class2', name: 'type2', parentClass: 'parent2' },
{ className: 'class1', name: 'type1', parentClass: 'parent1' },
{ className: 'class3', name: 'type3', parentClass: 'parent3' },
{ className: 'class2', name: 'type2', parentClass: 'parent2' },
];
const result = getCheckboxElements(elementTypes);
expect(result).toEqual([
{ id: 'type1', label: 'type1' },
{ id: 'type2', label: 'type2' },
{ id: 'type3', label: 'type3' },
]);
});
it('should handle an empty array of elementTypes', () => {
const result = getCheckboxElements([]);
expect(result).toEqual([]);
});
it('should return an empty array when elementTypes is undefined', () => {
const result = getCheckboxElements(undefined);
expect(result).toEqual([]);
});
});