diff --git a/src/encoded/static/libs/__tests__/query_string-test.js b/src/encoded/static/libs/__tests__/query_string-test.js index e7520877c60..db7e4bd8b30 100644 --- a/src/encoded/static/libs/__tests__/query_string-test.js +++ b/src/encoded/static/libs/__tests__/query_string-test.js @@ -3,10 +3,10 @@ import QueryString from '../query_string'; describe('QueryString Class', () => { it('Returns given query string unmodified', () => { - let query = new QueryString('type=Experiment&assay_term_id=OBI:0000716&type=ReferenceEpigenome&assay_title=Histone+ChIP-seq'); - expect(query.format()).toEqual('type=Experiment&assay_term_id=OBI:0000716&type=ReferenceEpigenome&assay_title=Histone+ChIP-seq'); - query = new QueryString('type=Experiment&assay_term_id=OBI:0000716&type!=ReferenceEpigenome&assay_title=Histone+ChIP-seq'); - expect(query.format()).toEqual('type=Experiment&assay_term_id=OBI:0000716&type!=ReferenceEpigenome&assay_title=Histone+ChIP-seq'); + let query = new QueryString('type=Experiment&type=ReferenceEpigenome&assay_term_id=OBI:0000716&assay_title=Histone+ChIP-seq'); + expect(query.format()).toEqual('type=Experiment&type=ReferenceEpigenome&assay_term_id=OBI:0000716&assay_title=Histone+ChIP-seq'); + query = new QueryString('type=Experiment&type!=ReferenceEpigenome&assay_term_id=OBI:0000716&assay_title=Histone+ChIP-seq'); + expect(query.format()).toEqual('type=Experiment&type!=ReferenceEpigenome&assay_term_id=OBI:0000716&assay_title=Histone+ChIP-seq'); }); it('Finds all values matching a key', () => { @@ -26,7 +26,7 @@ describe('QueryString Class', () => { query.addKeyValue('assay_term_id', 'OBI:0000716'); expect(query.format()).toEqual('type=Experiment&assay_term_id=OBI:0000716'); query.addKeyValue('type', 'Annotation', true); - expect(query.format()).toEqual('type=Experiment&assay_term_id=OBI:0000716&type!=Annotation'); + expect(query.format()).toEqual('type=Experiment&type!=Annotation&assay_term_id=OBI:0000716'); }); it('Deletes all keys of a value', () => { @@ -36,7 +36,7 @@ describe('QueryString Class', () => { query = new QueryString('type=Experiment&assay_term_id=OBI:0000716&type=Annotation'); query.deleteKeyValue('type', 'Experiment'); - expect(query.format()).toEqual('assay_term_id=OBI:0000716&type=Annotation'); + expect(query.format()).toEqual('type=Annotation&assay_term_id=OBI:0000716'); query = new QueryString('type=Experiment&assay_term_id=OBI:0000716&type!=Annotation'); query.deleteKeyValue('type'); @@ -50,7 +50,7 @@ describe('QueryString Class', () => { it('Replaces all keys with a new value', () => { let query = new QueryString('type=Experiment&assay_term_id=OBI:0000716&type=Annotation'); query.replaceKeyValue('type', 'Biosample'); - expect(query.format()).toEqual('assay_term_id=OBI:0000716&type=Biosample'); + expect(query.format()).toEqual('type=Biosample&assay_term_id=OBI:0000716'); query = new QueryString('type=Experiment&assay_term_id=OBI:0000716&type=Annotation'); query.replaceKeyValue('assay_term_id', 'OBI:0001919'); @@ -58,19 +58,19 @@ describe('QueryString Class', () => { query = new QueryString('type=Experiment&assay_term_id=OBI:0000716&type!=Annotation'); query.replaceKeyValue('type', 'Biosample'); - expect(query.format()).toEqual('assay_term_id=OBI:0000716&type=Biosample'); + expect(query.format()).toEqual('type=Biosample&assay_term_id=OBI:0000716'); query = new QueryString('type=Experiment&assay_term_id=OBI:0000716&type!=Annotation'); query.replaceKeyValue('type', 'Biosample', true); - expect(query.format()).toEqual('assay_term_id=OBI:0000716&type!=Biosample'); + expect(query.format()).toEqual('type!=Biosample&assay_term_id=OBI:0000716'); }); it('Creates an independent clone', () => { const query = new QueryString('type=Experiment&assay_term_id=OBI:0000716&type!=Annotation'); const queryCopy = query.clone(); queryCopy.addKeyValue('assay_title', 'Histone ChIP-seq', true); - expect(query.format()).toEqual('type=Experiment&assay_term_id=OBI:0000716&type!=Annotation'); - expect(queryCopy.format()).toEqual('type=Experiment&assay_term_id=OBI:0000716&type!=Annotation&assay_title!=Histone+ChIP-seq'); + expect(query.format()).toEqual('type=Experiment&type!=Annotation&assay_term_id=OBI:0000716'); + expect(queryCopy.format()).toEqual('type=Experiment&type!=Annotation&assay_term_id=OBI:0000716&assay_title!=Histone+ChIP-seq'); }); it('Counts the number of query keys', () => { diff --git a/src/encoded/static/libs/query_string.js b/src/encoded/static/libs/query_string.js index a4576bd6f45..98ffb2f68de 100644 --- a/src/encoded/static/libs/query_string.js +++ b/src/encoded/static/libs/query_string.js @@ -210,13 +210,25 @@ class QueryString { /** * Get the query string corresponding to the query this object holds. If you have made no * modifications to the query this object holds, you get back the same query string that - * initialized this object. + * initialized this object. `type=` elements get sorted to the front to avoid requests getting + * blocked. * * @return {string} Equivalent query string. */ format() { - return this._parsedQuery.map((queryElement) => { - const key = Object.keys(queryElement)[0]; + // If any of the query strings has a key of `type` move all those to the front of the query + // string. The `reduce()` accumulator is a two-element array. The first element is an array + // of `type=` elements, and the second element is an array of all other query elements. + const [typeQueries, otherQueries] = this._parsedQuery.reduce( + ([types, others], queryElement) => + queryElement.type ? [types.concat(queryElement), others] : [types, others.concat(queryElement)], + [[], []] + ); + const sortedQueries = [...typeQueries, ...otherQueries]; + + // Convert sorted queries to the formatted query string. + return sortedQueries.map((queryElement) => { + const key = QueryString._getQueryElementKey(queryElement); return `${key}${queryElement.negative ? '!=' : '='}${queryEncoding.encodedURIComponent(queryElement[key])}`; }).join('&'); }