diff --git a/package.json b/package.json
index a8e2a2391..31fb71f1f 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,7 @@
"prepare": "husky",
"release": "yarn run build && release-it --npm.skipChecks",
"start": "NODE_ENV=development craco start",
- "test": "craco test --coverage --watchAll=false"
+ "test": "TZ=UTC craco test --coverage --watchAll=false"
},
"browserslist": "> 0.2% in @cfpb/browserslist-config stats",
"devDependencies": {
diff --git a/src/components/Filters/AggregationBranch.js b/src/components/Filters/AggregationBranch.js
index 99f8aaa1e..49048684f 100644
--- a/src/components/Filters/AggregationBranch.js
+++ b/src/components/Filters/AggregationBranch.js
@@ -7,7 +7,7 @@ import {
slugify,
} from '../../utils';
import { removeMultipleFilters, replaceFilters } from '../../actions/filter';
-import AggregationItem from './AggregationItem';
+import AggregationItem from './AggregationItem/AggregationItem';
import { connect } from 'react-redux';
import { FormattedNumber } from 'react-intl';
import getIcon from '../iconMap';
diff --git a/src/components/Filters/AggregationItem.js b/src/components/Filters/AggregationItem.js
deleted file mode 100644
index 52e5c432b..000000000
--- a/src/components/Filters/AggregationItem.js
+++ /dev/null
@@ -1,143 +0,0 @@
-import { coalesce, sanitizeHtmlId } from '../../utils';
-import { filterPatch, SLUG_SEPARATOR } from '../../constants';
-import { replaceFilters, toggleFilter } from '../../actions/filter';
-import { arrayEquals } from '../../utils/compare';
-import { connect } from 'react-redux';
-import { FormattedNumber } from 'react-intl';
-import { getUpdatedFilters } from '../../utils/filters';
-import PropTypes from 'prop-types';
-import React from 'react';
-
-export class AggregationItem extends React.Component {
- _onChange() {
- if (this.props.isActive) {
- this.props.removeFilter(this.props);
- } else {
- this.props.addFilter(this.props);
- }
- }
-
- render() {
- const { isActive, item, fieldName } = this.props;
- const value = item.value || item.key;
- const liStyle = 'layout-row m-form-field m-form-field--checkbox';
- const id = sanitizeHtmlId(fieldName + '-' + item.key);
- return (
-
- this._onChange()}
- />
-
-
-
-
-
- );
- }
-}
-
-export const mapStateToProps = (state, ownProps) => {
- const aggs = coalesce(state.aggs, ownProps.fieldName, []);
- const filters = coalesce(state.query, ownProps.fieldName, []);
- const value = ownProps.item.key;
- const parentKey = value.split(SLUG_SEPARATOR)[0];
- const isActive = filters.includes(value) || filters.includes(parentKey);
- return {
- isActive,
- aggs,
- filters,
- };
-};
-
-// remove parent and apply current filter
-export const mapDispatchToProps = (dispatch, ownProps) => ({
- addFilter: (props) => {
- const { aggs, filters } = props;
- const { fieldName, item } = ownProps;
- const value = item.key;
- const isChildItem = value.indexOf(SLUG_SEPARATOR) > -1;
- // cases where its issue / product
- if (isChildItem && filterPatch.includes(fieldName)) {
- // We should find the parent
- // determine if the other siblings are already checked
- // check the parent only, and uncheck the rest so that the fake check
- // will take affect
- const parentFilter = value.split(SLUG_SEPARATOR)[0];
- const childFilter = value.split(SLUG_SEPARATOR)[1];
- /* eslint-disable no-unexpected-multiline */
- // TODO: reformat to not need the unexpected multiline.
- const subItems = aggs
- .find((agg) => agg.key === parentFilter)
- ['sub_' + fieldName + '.raw'].buckets.map((agg) => agg.key)
- .sort();
- /* eslint-enable no-unexpected-multiline */
-
- const parentKey = parentFilter + SLUG_SEPARATOR;
- const selectedFilters = filters
- .filter((filter) => filter.indexOf(parentKey) > -1)
- .map((filter) => filter.replace(parentKey, ''));
- selectedFilters.push(childFilter);
-
- selectedFilters.sort();
-
- let appliedFilters;
- if (arrayEquals(selectedFilters, subItems)) {
- // remove subitems, add parent filter
- appliedFilters = filters
- .filter((filter) => filter.indexOf(parentKey) === -1)
- .concat(parentFilter);
- } else {
- // just add the single filter and apply filters
- appliedFilters = filters.concat(value);
- }
- dispatch(replaceFilters(fieldName, appliedFilters));
- } else {
- dispatch(toggleFilter(fieldName, item));
- }
- },
- removeFilter: (props) => {
- const { aggs, filters } = props;
- const { fieldName, item } = ownProps;
- if (filterPatch.includes(fieldName)) {
- const filterName = item.key;
- const updatedFilters = getUpdatedFilters(
- filterName,
- filters,
- aggs,
- fieldName,
- );
- dispatch(replaceFilters(fieldName, updatedFilters));
- } else {
- dispatch(toggleFilter(fieldName, item));
- }
- },
-});
-
-// eslint-disable-next-line react-redux/prefer-separate-component-file
-export default connect(mapStateToProps, mapDispatchToProps)(AggregationItem);
-
-AggregationItem.propTypes = {
- isActive: PropTypes.bool,
- fieldName: PropTypes.string.isRequired,
- item: PropTypes.shape({
- // eslint-disable-next-line camelcase
- doc_count: PropTypes.number.isRequired,
- key: PropTypes.string.isRequired,
- value: PropTypes.string,
- isDisabled: PropTypes.bool,
- }).isRequired,
- removeFilter: PropTypes.func.isRequired,
- addFilter: PropTypes.func.isRequired,
-};
-
-AggregationItem.defaultProps = {
- isActive: false,
-};
diff --git a/src/components/Filters/AggregationItem/AggregationItem.js b/src/components/Filters/AggregationItem/AggregationItem.js
new file mode 100644
index 000000000..d7382b9ef
--- /dev/null
+++ b/src/components/Filters/AggregationItem/AggregationItem.js
@@ -0,0 +1,126 @@
+import PropTypes from 'prop-types';
+import { useSelector, useDispatch } from 'react-redux';
+import { FormattedNumber } from 'react-intl';
+import { filterPatch, SLUG_SEPARATOR } from '../../../constants';
+import { coalesce, sanitizeHtmlId } from '../../../utils';
+import { arrayEquals } from '../../../utils/compare';
+import { replaceFilters, toggleFilter } from '../../../actions/filter';
+import { getUpdatedFilters } from '../../../utils/filters';
+import { selectAggsState } from '../../../reducers/aggs/selectors';
+import { selectQueryState } from '../../../reducers/query/selectors';
+
+const appliedFilters = ({ fieldName, item, aggs, filters }) => {
+ // We should find the parent
+ // determine if the other siblings are already checked
+ // check the parent only, and uncheck the rest so that the fake check
+ // will take affect
+ const [parentFilter, childFilter] = item.key.split(SLUG_SEPARATOR);
+ /* eslint-disable no-unexpected-multiline */
+ // TODO: reformat to not need the unexpected multiline.
+ const subItems = aggs
+ .find((agg) => agg.key === parentFilter)
+ ['sub_' + fieldName + '.raw'].buckets.map((agg) => agg.key)
+ .sort();
+ /* eslint-enable no-unexpected-multiline */
+
+ const parentKey = parentFilter + SLUG_SEPARATOR;
+ const selectedFilters = filters
+ .filter((filter) => filter.indexOf(parentKey) > -1)
+ .map((filter) => filter.replace(parentKey, ''));
+ selectedFilters.push(childFilter);
+
+ selectedFilters.sort();
+
+ if (arrayEquals(selectedFilters, subItems)) {
+ // remove subitems, add parent filter
+ return filters
+ .filter((filter) => filter.indexOf(parentKey) === -1)
+ .concat(parentFilter);
+ } else {
+ // just add the single filter and apply filters
+ return filters.concat(item.key);
+ }
+};
+
+const AggregationItem = ({ fieldName, item }) => {
+ const aggsState = useSelector(selectAggsState);
+ const queryState = useSelector(selectQueryState);
+ const dispatch = useDispatch();
+
+ const aggs = coalesce(aggsState, fieldName, []);
+ const filters = coalesce(queryState, fieldName, []);
+ const isActive =
+ filters.includes(item.key) ||
+ filters.includes(item.key.split(SLUG_SEPARATOR)[0]);
+
+ const value = item.value || item.key;
+ const liStyle = 'layout-row m-form-field m-form-field--checkbox';
+ const id = sanitizeHtmlId(fieldName + '-' + item.key);
+
+ const addFilter = () => {
+ const isChildItem = item.key.indexOf(SLUG_SEPARATOR) > -1;
+ // cases where its issue / product
+ if (isChildItem && filterPatch.includes(fieldName)) {
+ const filtersToApply = appliedFilters({ fieldName, item, aggs, filters });
+ dispatch(replaceFilters(fieldName, filtersToApply));
+ } else {
+ dispatch(toggleFilter(fieldName, item));
+ }
+ };
+
+ const removeFilter = () => {
+ if (filterPatch.includes(fieldName)) {
+ const filterName = item.key;
+ const updatedFilters = getUpdatedFilters(
+ filterName,
+ filters,
+ aggs,
+ fieldName,
+ );
+ dispatch(replaceFilters(fieldName, updatedFilters));
+ } else {
+ dispatch(toggleFilter(fieldName, item));
+ }
+ };
+
+ const onChange = () => {
+ if (isActive) {
+ removeFilter();
+ } else {
+ addFilter();
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+AggregationItem.propTypes = {
+ fieldName: PropTypes.string.isRequired,
+ item: PropTypes.shape({
+ // eslint-disable-next-line camelcase
+ doc_count: PropTypes.number.isRequired,
+ key: PropTypes.string.isRequired,
+ value: PropTypes.string,
+ isDisabled: PropTypes.bool,
+ }).isRequired,
+};
+
+export default AggregationItem;
diff --git a/src/components/Filters/AggregationItem/AggregationItem.spec.js b/src/components/Filters/AggregationItem/AggregationItem.spec.js
new file mode 100644
index 000000000..9afc2e0fc
--- /dev/null
+++ b/src/components/Filters/AggregationItem/AggregationItem.spec.js
@@ -0,0 +1,323 @@
+import { testRender as render, screen } from '../../../testUtils/test-utils';
+import { merge } from '../../../testUtils/functionHelpers';
+import userEvent from '@testing-library/user-event';
+import * as filter from '../../../actions/filter';
+import * as utils from '../../../utils';
+import { slugify } from '../../../utils';
+import { defaultAggs } from '../../../reducers/aggs/aggs';
+import { defaultQuery } from '../../../reducers/query/query';
+import AggregationItem from './AggregationItem';
+
+const defaultTestProps = {
+ fieldName: 'foo',
+ item: {
+ key: 'hole',
+ value: 'som',
+ doc_count: 100,
+ isDisabled: false,
+ },
+};
+
+const renderComponent = (props, newAggsState, newQueryState) => {
+ merge(newAggsState, defaultAggs);
+ merge(newQueryState, defaultQuery);
+
+ const data = {
+ aggs: newAggsState,
+ query: newQueryState,
+ };
+
+ render(, {
+ preloadedState: data,
+ });
+};
+
+describe('component::AggregationItem', () => {
+ const user = userEvent.setup({ delay: null });
+
+ describe('initial state', () => {
+ let aggs, query;
+
+ beforeEach(() => {
+ aggs = {
+ issue: [1, 2, 3],
+ product: ['foo', 'bar'],
+ };
+
+ query = {
+ issue: [1],
+ timely: ['Yes'],
+ };
+ });
+
+ test('renders properly with given item key and value', () => {
+ renderComponent(defaultTestProps, aggs, query);
+
+ expect(
+ screen.getByLabelText(defaultTestProps.item.value),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByText(defaultTestProps.item.doc_count),
+ ).toBeInTheDocument();
+ expect(screen.getByRole('checkbox')).toBeEnabled();
+ });
+
+ test('renders properly with given item key, but no item value', () => {
+ const noItemValueProps = {
+ ...defaultTestProps,
+ item: { ...defaultTestProps.item, value: null },
+ };
+
+ renderComponent(noItemValueProps, aggs, query);
+
+ expect(
+ screen.getByLabelText(defaultTestProps.item.key),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByText(defaultTestProps.item.doc_count),
+ ).toBeInTheDocument();
+ expect(screen.getByRole('checkbox')).toBeEnabled();
+ });
+
+ test('renders properly in its disabled state', () => {
+ const disabledItemProps = {
+ ...defaultTestProps,
+ item: { ...defaultTestProps.item, isDisabled: true },
+ };
+
+ renderComponent(disabledItemProps, aggs, query);
+
+ expect(screen.getByRole('checkbox')).toBeDisabled();
+ });
+
+ test('leaves checkbox unchecked when no filter present', () => {
+ const ownProps = {
+ fieldName: 'foobar',
+ item: { key: 'Yes', doc_count: 1 },
+ };
+
+ renderComponent(ownProps, aggs, query);
+
+ expect(screen.getByRole('checkbox')).not.toBeChecked();
+ });
+
+ test('checks checkbox when fieldName key matches query', () => {
+ const ownProps = {
+ fieldName: 'timely',
+ item: { key: 'Yes', doc_count: 1 },
+ };
+
+ renderComponent(ownProps, aggs, query);
+
+ expect(screen.getByRole('checkbox')).toBeChecked();
+ });
+
+ test('leaves checkbox unchecked when same fieldName passed with different value', () => {
+ const ownProps = {
+ fieldName: 'timely',
+ item: { key: 'No', doc_count: 1 },
+ };
+
+ renderComponent(ownProps, aggs, query);
+
+ expect(screen.getByRole('checkbox')).not.toBeChecked();
+ });
+
+ test('maps aggs & filters with fieldName', () => {
+ const ownProps = {
+ fieldName: 'issue',
+ item: { key: 'No Money', doc_count: 1 },
+ };
+
+ renderComponent(ownProps, aggs, query);
+
+ expect(screen.getByRole('checkbox')).not.toBeChecked();
+ });
+ });
+
+ describe('onChange functionality', () => {
+ let replaceFiltersFn, toggleFilterFn, coalesceFn;
+
+ beforeEach(() => {
+ replaceFiltersFn = jest.spyOn(filter, 'replaceFilters');
+ toggleFilterFn = jest.spyOn(filter, 'toggleFilter');
+ coalesceFn = jest.spyOn(utils, 'coalesce');
+ });
+
+ afterEach(() => {
+ jest.restoreAllMocks();
+ });
+
+ describe('addFilter', () => {
+ test('appends subIssue filter when not all selected', async () => {
+ const ownProps = {
+ fieldName: 'issue',
+ item: {
+ key: slugify('a', 'b'),
+ doc_count: 1000,
+ },
+ };
+
+ const aggs = [
+ {
+ key: 'a',
+ doc_count: 1,
+ 'sub_issue.raw': {
+ buckets: [{ key: 'b' }, { key: 'c' }, { key: 'd' }],
+ },
+ },
+ ];
+
+ const filters = ['f', 'g', 'h', slugify('a', 'd')];
+
+ coalesceFn.mockReturnValueOnce(aggs).mockReturnValueOnce(filters);
+
+ renderComponent(ownProps, {}, {});
+
+ await user.click(screen.getByRole('checkbox'));
+
+ expect(replaceFiltersFn).toHaveBeenCalled();
+ expect(replaceFiltersFn).toHaveReturnedWith({
+ filterName: 'issue',
+ requery: 'REQUERY_ALWAYS',
+ type: 'FILTER_REPLACED',
+ values: ['f', 'g', 'h', slugify('a', 'd'), slugify('a', 'b')],
+ });
+
+ expect(toggleFilterFn).not.toHaveBeenCalled();
+ });
+
+ test('replaces subItems with parent when children are selected', async () => {
+ const ownProps = {
+ fieldName: 'issue',
+ item: {
+ key: slugify('a', 'b'),
+ doc_count: 1000,
+ },
+ };
+
+ const aggs = [
+ {
+ key: 'a',
+ doc_count: 1,
+ 'sub_issue.raw': {
+ buckets: [{ key: 'b' }, { key: 'c' }, { key: 'd' }],
+ },
+ },
+ ];
+
+ const filters = ['f', 'g', 'h', slugify('a', 'c'), slugify('a', 'd')];
+
+ coalesceFn.mockReturnValueOnce(aggs).mockReturnValueOnce(filters);
+
+ renderComponent(ownProps, {}, {});
+
+ await user.click(screen.getByRole('checkbox'));
+
+ expect(replaceFiltersFn).toHaveBeenCalled();
+ expect(replaceFiltersFn).toHaveReturnedWith({
+ filterName: 'issue',
+ requery: 'REQUERY_ALWAYS',
+ type: 'FILTER_REPLACED',
+ values: ['f', 'g', 'h', 'a'],
+ });
+
+ expect(toggleFilterFn).not.toHaveBeenCalled();
+ });
+
+ test('handles non product & issue filters', async () => {
+ const ownProps = {
+ fieldName: 'fieldName',
+ item: { key: 'foo', doc_count: 1000 },
+ };
+
+ const aggs = {};
+ const filters = [];
+
+ coalesceFn.mockReturnValueOnce(aggs).mockReturnValueOnce(filters);
+
+ renderComponent(ownProps, {}, {});
+
+ await user.click(screen.getByRole('checkbox'));
+
+ expect(toggleFilterFn).toHaveBeenCalled();
+ expect(toggleFilterFn).toHaveReturnedWith({
+ filterName: 'fieldName',
+ filterValue: {
+ doc_count: 1000,
+ key: 'foo',
+ },
+ requery: 'REQUERY_ALWAYS',
+ type: 'FILTER_CHANGED',
+ });
+
+ expect(replaceFiltersFn).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('removeFilter', () => {
+ test('handles product/issue filters', async () => {
+ const ownProps = {
+ fieldName: 'issue',
+ item: { key: 'foo', doc_count: 1000 },
+ };
+
+ const aggs = [
+ {
+ key: 'foo',
+ doc_count: 1,
+ 'sub_issue.raw': {
+ buckets: [],
+ },
+ },
+ ];
+ const filters = ['foo'];
+
+ coalesceFn.mockReturnValueOnce(aggs).mockReturnValueOnce(filters);
+
+ renderComponent(ownProps, {}, {});
+
+ await user.click(screen.getByRole('checkbox'));
+
+ expect(replaceFiltersFn).toHaveBeenCalled();
+ expect(replaceFiltersFn).toHaveReturnedWith({
+ filterName: 'issue',
+ requery: 'REQUERY_ALWAYS',
+ type: 'FILTER_REPLACED',
+ values: [],
+ });
+
+ expect(toggleFilterFn).not.toHaveBeenCalled();
+ });
+
+ test('handles non product & issue filters', async () => {
+ const ownProps = {
+ fieldName: 'fieldName',
+ item: { key: 'foo', doc_count: 1000 },
+ };
+
+ const aggs = {};
+ const filters = ['foo'];
+
+ coalesceFn.mockReturnValueOnce(aggs).mockReturnValueOnce(filters);
+
+ renderComponent(ownProps, {}, {});
+
+ await user.click(screen.getByRole('checkbox'));
+
+ expect(toggleFilterFn).toHaveBeenCalled();
+ expect(toggleFilterFn).toHaveReturnedWith({
+ filterName: 'fieldName',
+ filterValue: {
+ doc_count: 1000,
+ key: 'foo',
+ },
+ requery: 'REQUERY_ALWAYS',
+ type: 'FILTER_CHANGED',
+ });
+
+ expect(replaceFiltersFn).not.toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/src/components/Filters/SimpleFilter.js b/src/components/Filters/SimpleFilter.js
index 471888cdb..733a00fe0 100644
--- a/src/components/Filters/SimpleFilter.js
+++ b/src/components/Filters/SimpleFilter.js
@@ -1,5 +1,5 @@
import './Aggregation.less';
-import AggregationItem from './AggregationItem';
+import AggregationItem from './AggregationItem/AggregationItem';
import { coalesce } from '../../utils';
import CollapsibleFilter from './CollapsibleFilter';
import { connect } from 'react-redux';
diff --git a/src/components/Filters/StickyOptions.js b/src/components/Filters/StickyOptions.js
index 5bf0096e0..66667d865 100644
--- a/src/components/Filters/StickyOptions.js
+++ b/src/components/Filters/StickyOptions.js
@@ -1,4 +1,4 @@
-import AggregationItem from './AggregationItem';
+import AggregationItem from './AggregationItem/AggregationItem';
import PropTypes from 'prop-types';
import React from 'react';
diff --git a/src/components/Filters/__tests__/AggregationItem.spec.js b/src/components/Filters/__tests__/AggregationItem.spec.js
deleted file mode 100644
index bfbfad2cc..000000000
--- a/src/components/Filters/__tests__/AggregationItem.spec.js
+++ /dev/null
@@ -1,284 +0,0 @@
-import ReduxAggregationItem, {
- AggregationItem,
- mapDispatchToProps,
- mapStateToProps,
-} from '../AggregationItem';
-import configureMockStore from 'redux-mock-store';
-import { IntlProvider } from 'react-intl';
-import { Provider } from 'react-redux';
-import React from 'react';
-import renderer from 'react-test-renderer';
-import { shallow } from 'enzyme';
-import { slugify } from '../../../utils';
-import thunk from 'redux-thunk';
-
-/**
- *
- * @param {Function} rmCb - Remove filter function
- * @param {Function} addCb - Add filter function
- * @param {boolean} isActive - Is the filter active?
- * @returns {Function} - Rendering function
- */
-function setupEnzyme(rmCb, addCb, isActive) {
- return shallow(
- ,
- );
-}
-
-/**
- * @returns {Function} - Rendering function
- */
-function setupSnapshot() {
- const middlewares = [thunk];
- const mockStore = configureMockStore(middlewares);
-
- const active = false;
- const onClick = jest.fn();
-
- const store = mockStore({
- query: {
- fieldName: [213],
- },
- });
-
- return renderer.create(
-
-
-
-
- ,
- );
-}
-
-describe('component:AggregationItem', () => {
- let fieldName, item;
- beforeEach(() => {
- item = { key: 'foo', doc_count: 1000 };
- fieldName = 'fieldName';
- });
- it('renders without crashing', () => {
- const target = setupSnapshot();
- const tree = target.toJSON();
- expect(tree).toMatchSnapshot();
- });
-
- describe('_onChange', () => {
- let rmCb, addCb, target;
- beforeEach(() => {
- rmCb = jest.fn();
- addCb = jest.fn();
- });
-
- it('ticks box - remove', () => {
- target = setupEnzyme(rmCb, addCb, true);
- const button = target.find('#foo-hole');
- button.simulate('change', { target: { checked: true } });
- expect(addCb).not.toHaveBeenCalled();
- expect(rmCb).toHaveBeenCalled();
- });
-
- it('ticks box - add', () => {
- target = setupEnzyme(rmCb, addCb, false);
- const button = target.find('#foo-hole');
- button.simulate('change', { target: { checked: false } });
- expect(addCb).toHaveBeenCalled();
- expect(rmCb).not.toHaveBeenCalled();
- });
- });
-
- describe('mapDispatchToProps', () => {
- let dispatch, ownProps;
- describe('addFilter', () => {
- it('appends subIssue filter when not all selected', () => {
- dispatch = jest.fn();
- ownProps = {
- fieldName: 'issue',
- item: {
- key: slugify('a', 'b'),
- doc_count: 1000,
- },
- };
- mapDispatchToProps(dispatch, ownProps).addFilter({
- aggs: [
- {
- key: 'a',
- doc_count: 1,
- 'sub_issue.raw': {
- buckets: [{ key: 'b' }, { key: 'c' }, { key: 'd' }],
- },
- },
- ],
- filters: ['f', 'g', 'h', slugify('a', 'd')],
- });
- expect(dispatch.mock.calls).toEqual([
- [
- {
- filterName: 'issue',
- requery: 'REQUERY_ALWAYS',
- type: 'FILTER_REPLACED',
- values: ['f', 'g', 'h', slugify('a', 'd'), slugify('a', 'b')],
- },
- ],
- ]);
- });
-
- it('replaces subItems with parent when children are selected', () => {
- dispatch = jest.fn();
- ownProps = {
- fieldName: 'issue',
- item: {
- key: slugify('a', 'b'),
- doc_count: 1000,
- },
- };
- mapDispatchToProps(dispatch, ownProps).addFilter({
- aggs: [
- {
- key: 'a',
- doc_count: 1,
- 'sub_issue.raw': {
- buckets: [{ key: 'b' }, { key: 'c' }, { key: 'd' }],
- },
- },
- ],
- filters: ['f', 'g', 'h', slugify('a', 'c'), slugify('a', 'd')],
- });
- expect(dispatch.mock.calls).toEqual([
- [
- {
- filterName: 'issue',
- requery: 'REQUERY_ALWAYS',
- type: 'FILTER_REPLACED',
- values: ['f', 'g', 'h', 'a'],
- },
- ],
- ]);
- });
-
- it('handles non product & issue filters', () => {
- dispatch = jest.fn();
- ownProps = { fieldName: fieldName, item: item };
- mapDispatchToProps(dispatch, ownProps).addFilter({
- aggs: {},
- fieldName: 'foo',
- filters: [],
- });
- expect(dispatch.mock.calls).toEqual([
- [
- {
- filterName: 'fieldName',
- filterValue: {
- doc_count: 1000,
- key: 'foo',
- },
- requery: 'REQUERY_ALWAYS',
- type: 'FILTER_CHANGED',
- },
- ],
- ]);
- });
- });
-
- describe('removeFilter', () => {
- it('handles product/issue filters', () => {
- dispatch = jest.fn();
- ownProps = { fieldName: 'issue', item: item };
- mapDispatchToProps(dispatch, ownProps).removeFilter({
- aggs: {},
- fieldName: 'foo',
- filters: [],
- });
- expect(dispatch.mock.calls).toEqual([
- [
- {
- filterName: 'issue',
- requery: 'REQUERY_ALWAYS',
- type: 'FILTER_REPLACED',
- values: [],
- },
- ],
- ]);
- });
- it('handles non product & issue filters', () => {
- dispatch = jest.fn();
- ownProps = { fieldName: fieldName, item: item };
- mapDispatchToProps(dispatch, ownProps).removeFilter({
- aggs: {},
- fieldName: 'foo',
- filters: [],
- });
- expect(dispatch.mock.calls).toEqual([
- [
- {
- filterName: 'fieldName',
- filterValue: {
- doc_count: 1000,
- key: 'foo',
- },
- requery: 'REQUERY_ALWAYS',
- type: 'FILTER_CHANGED',
- },
- ],
- ]);
- });
- });
- });
-
- describe('mapStateToProps', () => {
- let state, ownProps, propsReturn;
- beforeEach(() => {
- state = {
- aggs: {
- issue: [1, 2, 3],
- product: ['foo', 'bar'],
- },
- query: {
- issue: [1],
- timely: ['Yes'],
- },
- };
- });
- it('returns correct active value when no filter present', () => {
- ownProps = { fieldName: 'foobar', item: { key: 'Yes' } };
- propsReturn = mapStateToProps(state, ownProps);
- expect(propsReturn.isActive).toEqual(false);
- });
-
- it('returns correct active value fieldName key matches query', () => {
- ownProps = { fieldName: 'timely', item: { key: 'Yes' } };
- propsReturn = mapStateToProps(state, ownProps);
- expect(propsReturn.isActive).toEqual(true);
- });
-
- it('returns correct value when same fieldName passed with different value', () => {
- ownProps = { fieldName: 'timely', item: { key: 'No' } };
- propsReturn = mapStateToProps(state, ownProps);
- expect(propsReturn.isActive).toEqual(false);
- });
-
- it('maps aggs & filters with fieldName', () => {
- ownProps = { fieldName: 'issue', item: { key: 'No Money' } };
- propsReturn = mapStateToProps(state, ownProps);
- expect(propsReturn).toEqual({
- isActive: false,
- aggs: [1, 2, 3],
- filters: [1],
- });
- });
- });
-});
diff --git a/src/components/Filters/__tests__/MoreOrLess.spec.js b/src/components/Filters/__tests__/MoreOrLess.spec.js
index e04358b4b..0a31ae4a2 100644
--- a/src/components/Filters/__tests__/MoreOrLess.spec.js
+++ b/src/components/Filters/__tests__/MoreOrLess.spec.js
@@ -1,4 +1,4 @@
-import AggregationItem from '../AggregationItem';
+import AggregationItem from '../AggregationItem/AggregationItem';
import configureMockStore from 'redux-mock-store';
import { IntlProvider } from 'react-intl';
import MoreOrLess from '../MoreOrLess';
diff --git a/src/components/Filters/__tests__/__snapshots__/AggregationItem.spec.js.snap b/src/components/Filters/__tests__/__snapshots__/AggregationItem.spec.js.snap
deleted file mode 100644
index 0d5351a09..000000000
--- a/src/components/Filters/__tests__/__snapshots__/AggregationItem.spec.js.snap
+++ /dev/null
@@ -1,27 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`component:AggregationItem renders without crashing 1`] = `
-
-
-
-
- 1,000
-
-
-`;