Skip to content

Commit

Permalink
Convert SimpleFilter class component to functional (#522)
Browse files Browse the repository at this point in the history
* rewrote SimpleFilter to be functional component; eliminated old unit tests and snapshot

* Added new SimpleFilter functional component with unit tests, along with updated snapshots

* took out basic render test, as well as test id. updated snapshots to not include test id

* added render test back, without check for class

* update test setup

* updated unit tests with checks for company response values

---------

Co-authored-by: cdhenley219 <chanel.henley@cfpb.gov>
Co-authored-by: Richard Dinh <richard.dinh@cfpb.gov>
  • Loading branch information
3 people authored Aug 2, 2024
1 parent c47b059 commit 955be8c
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 164 deletions.
2 changes: 1 addition & 1 deletion src/components/Filters/FilterPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import getIcon from '../iconMap';
import { Issue } from './Issue';
import { Product } from './Product';
import React from 'react';
import SimpleFilter from './SimpleFilter';
import SimpleFilter from './SimpleFilter/SimpleFilter';
import { ZipCode } from './ZipCode';
import {
selectViewHasFilters,
Expand Down
53 changes: 0 additions & 53 deletions src/components/Filters/SimpleFilter.js

This file was deleted.

41 changes: 41 additions & 0 deletions src/components/Filters/SimpleFilter/SimpleFilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { selectAggsState } from '../../../reducers/aggs/selectors';
import { selectQueryState } from '../../../reducers/query/selectors';
import { coalesce } from '../../../utils';
import CollapsibleFilter from '../CollapsibleFilter';
import MoreOrLess from '../MoreOrLess';
import AggregationItem from '../AggregationItem/AggregationItem';

const SimpleFilter = ({ fieldName, title, desc }) => {
const aggs = useSelector(selectAggsState);
const query = useSelector(selectQueryState);
const activeChildren = coalesce(query, fieldName, []);
const options = coalesce(aggs, fieldName, []);
const hasChildren = activeChildren.length > 0;

const listComponentProps = { fieldName };

return (
<CollapsibleFilter
title={title}
desc={desc}
hasChildren={hasChildren}
className={'aggregation simple ' + fieldName}
>
<MoreOrLess
listComponent={AggregationItem}
listComponentProps={listComponentProps}
options={options}
/>
</CollapsibleFilter>
);
};

SimpleFilter.propTypes = {
fieldName: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
desc: PropTypes.string,
};

export default SimpleFilter;
86 changes: 86 additions & 0 deletions src/components/Filters/SimpleFilter/SimpleFilter.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { testRender as render, screen } from '../../../testUtils/test-utils';
import SimpleFilter from './SimpleFilter';
import { merge } from '../../../testUtils/functionHelpers';
import { defaultAggs } from '../../../reducers/aggs/aggs';
import { defaultQuery } from '../../../reducers/query/query';

const renderComponent = (props, newAggsState, newQueryState) => {
merge(newAggsState, defaultAggs);
merge(newQueryState, defaultQuery);

const data = {
aggs: newAggsState,
query: newQueryState,
};

return render(<SimpleFilter {...props} />, {
preloadedState: data,
});
};

describe('component:SimpleFilter', () => {
let props, aggs, query;

beforeEach(() => {
props = {
fieldName: 'company_response',
desc: 'This is a description',
title: 'Title',
};

aggs = {
company_response: [
{ key: 'Closed with non-monetary relief', doc_count: 412732 },
{ key: 'Closed with explanation', doc_count: 345066 },
{ key: 'In progress', doc_count: 86400 },
{ key: 'Closed with monetary relief', doc_count: 244 },
{ key: 'Untimely response', doc_count: 178 },
],
};

query = {};
});

describe('initial state', () => {
props = { title: 'nana', fieldName: 'company_response' };

test('renders without crashing', () => {
renderComponent(props, {}, {});
expect(screen.getByRole('button')).toHaveAttribute(
'aria-label',
`Hide ${props.title} filter`,
);
expect(screen.getByText(props.title)).toBeInTheDocument();
});

test('shows if there are any active children', () => {
query = {
company_response: ['Closed with non-monetary relief'],
};

renderComponent(props, aggs, query);

expect(screen.getByRole('button')).toHaveAttribute(
'aria-expanded',
'true',
);

aggs.company_response.forEach((response) => {
expect(screen.getByText(response.key)).toBeInTheDocument();
});
});

test('hides if there are no active children', () => {
renderComponent(props, aggs, query);

expect(screen.getByRole('button')).toHaveAttribute(
'aria-expanded',
'false',
);

aggs.company_response.forEach((response) => {
expect(screen.queryByText(response.key)).not.toBeInTheDocument();
});
});
});
});
76 changes: 0 additions & 76 deletions src/components/Filters/__tests__/SimpleFilter.spec.js

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export const clampDate = (val, min, max) => {
* @param {object} object - the object being tested
* @param {string} field - the field to check
* @param {string | object} alternateValue - the value to use in absence
* @returns {string} the value to use
* @returns {string | Array | object} the value to use
*/
export const coalesce = (object, field, alternateValue) => {
if (typeof object !== 'object') {
Expand Down

0 comments on commit 955be8c

Please sign in to comment.