diff --git a/src/lib/state/selectors/query.js b/src/lib/state/selectors/query.js index fcf8ac61..cd7b42da 100644 --- a/src/lib/state/selectors/query.js +++ b/src/lib/state/selectors/query.js @@ -7,8 +7,12 @@ */ import Qs from 'qs'; +import _forEach from 'lodash/forEach'; +import _head from 'lodash/head'; +import _isArray from 'lodash/isArray'; import _isEmpty from 'lodash/isEmpty'; import _pick from 'lodash/pick'; + /** * Return true if the first string starts and contains the second. * @param {string} first a string @@ -39,8 +43,7 @@ function removeLastChild(arr) { return []; } -export const updateQueryFilters = (queryFilter, stateFilters) => { - if (_isEmpty(queryFilter)) return; +function updateFilter(queryFilter, stateFilters) { /** * convert query and state to strings so they can be compared */ @@ -101,6 +104,25 @@ export const updateQueryFilters = (queryFilter, stateFilters) => { * convert back to lists */ return filteredStrStates.map(strState => parse(strState)); +} + +export const updateQueryFilters = (queryFilter, stateFilters) => { + if (_isEmpty(queryFilter)) return; + + /** If we have one filter as query = ['file_type', 'pdf'] */ + if (!_isArray(_head(queryFilter))) { + return updateFilter(queryFilter, stateFilters); + } + + /** If we have an array of filters as query we apply the filters one by one. + * e.g. query = [['file_type', 'pdf'], ['file_type', 'txt']] + */ + let tempStateFilters = stateFilters; + _forEach( + queryFilter, + filter => (tempStateFilters = updateFilter(filter, tempStateFilters)) + ); + return tempStateFilters; }; export const updateQueryState = (oldState, newState, storeKeys) => { diff --git a/src/lib/state/selectors/query.test.js b/src/lib/state/selectors/query.test.js index 7492bde1..a50bf914 100644 --- a/src/lib/state/selectors/query.test.js +++ b/src/lib/state/selectors/query.test.js @@ -35,11 +35,17 @@ describe('queries with first level filters.', () => { const newState = updateQueryFilters(query, state); - expect(newState).toEqual([['file_type', 'pdf'], ['type', 'Publication']]); + expect(newState).toEqual([ + ['file_type', 'pdf'], + ['type', 'Publication'], + ]); }); test('query with `type: Publication` should be added when another `type` is already in the state.', () => { - const state = [['file_type', 'pdf'], ['type', 'Image']]; + const state = [ + ['file_type', 'pdf'], + ['type', 'Image'], + ]; const query = ['type', 'Publication']; const newState = updateQueryFilters(query, state); @@ -61,13 +67,19 @@ describe('queries with first level filters.', () => { const newState = updateQueryFilters(query, state); - expect(newState).toEqual([['file_type', 'pdf'], ['type', 'Publication']]); + expect(newState).toEqual([ + ['file_type', 'pdf'], + ['type', 'Publication'], + ]); }); }); describe('queries with second level filters.', () => { test('query with `subtype: Other` should be added when not in the state.', () => { - const state = [['file_type', 'pdf'], ['type', 'Image']]; + const state = [ + ['file_type', 'pdf'], + ['type', 'Image'], + ]; const query = ['type', 'Publication', ['subtype', 'Other']]; const newState = updateQueryFilters(query, state); @@ -91,7 +103,10 @@ describe('queries with second level filters.', () => { const newState = updateQueryFilters(query, state); - expect(newState).toEqual([['file_type', 'pdf'], ['type', 'Image']]); + expect(newState).toEqual([ + ['file_type', 'pdf'], + ['type', 'Image'], + ]); }); test('query with `subtype: Other` should remove any query with the parent `type: Publication`.', () => { @@ -233,3 +248,53 @@ describe('user clears previous selections', () => { expect(newState).toEqual([['file_type', 'pdf']]); }); }); + +describe('user submits multiple filters as input', () => { + test('query with `file_type: txt` should be added when not in the state.', () => { + const state = []; + const query = [['file_type', 'txt']]; + const newState = updateQueryFilters(query, state); + expect(newState).toEqual([['file_type', 'txt']]); + }); + + test('query removes existing `file_type: pdf` and adds `file_type: txt`.', () => { + const state = [['file_type', 'pdf']]; + const query = [ + ['file_type', 'pdf'], + ['file_type', 'txt'], + ]; + const newState = updateQueryFilters(query, state); + expect(newState).toEqual([['file_type', 'txt']]); + }); + + test('query removes existing `file_type: pdf` from state.', () => { + const state = [['file_type', 'pdf']]; + const query = [['file_type', 'pdf']]; + const newState = updateQueryFilters(query, state); + expect(newState).toEqual([]); + }); + + test('query with `subtype: Report` should remove from the state any child query with `subsubtype`', () => { + const state = [ + ['file_type', 'png'], + ['file_type', 'pdf'], + ['type', 'Image'], + [ + 'type', + 'Publication', + ['subtype', 'Report', ['subsubtype', 'Restricted']], + ], + ['type', 'Publication', ['subtype', 'Report', ['subsubtype', 'Public']]], + ]; + const query = [['type', 'Publication', ['subtype', 'Report']]]; + + const newState = updateQueryFilters(query, state); + + expect(newState).toEqual([ + ['file_type', 'png'], + ['file_type', 'pdf'], + ['type', 'Image'], + ['type', 'Publication'], + ]); + }); +});