Skip to content

Commit 50791ac

Browse files
Feature/prevent duplicate search fields in search api (#510)
* Prevent duplicate search fields in search API
1 parent 79827a8 commit 50791ac

File tree

3 files changed

+85
-7
lines changed

3 files changed

+85
-7
lines changed

lib-es5/v2/search.js

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,27 @@ var Search = function () {
4242
}, {
4343
key: 'aggregate',
4444
value: function aggregate(value) {
45-
this.query_hash.aggregate.push(value);
45+
var found = this.query_hash.aggregate.find(function (v) {
46+
return v === value;
47+
});
48+
49+
if (!found) {
50+
this.query_hash.aggregate.push(value);
51+
}
52+
4653
return this;
4754
}
4855
}, {
4956
key: 'with_field',
5057
value: function with_field(value) {
51-
this.query_hash.with_field.push(value);
58+
var found = this.query_hash.with_field.find(function (v) {
59+
return v === value;
60+
});
61+
62+
if (!found) {
63+
this.query_hash.with_field.push(value);
64+
}
65+
5266
return this;
5367
}
5468
}, {
@@ -59,7 +73,20 @@ var Search = function () {
5973
var sort_bucket = void 0;
6074
sort_bucket = {};
6175
sort_bucket[field_name] = dir;
62-
this.query_hash.sort_by.push(sort_bucket);
76+
77+
// Check if this field name is already stored in the hash
78+
var previously_sorted_obj = this.query_hash.sort_by.find(function (sort_by) {
79+
return sort_by[field_name];
80+
});
81+
82+
// Since objects are references in Javascript, we can update the reference we found
83+
// For example,
84+
if (previously_sorted_obj) {
85+
previously_sorted_obj[field_name] = dir;
86+
} else {
87+
this.query_hash.sort_by.push(sort_bucket);
88+
}
89+
6390
return this;
6491
}
6592
}, {

lib/v2/search.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const api = require('./api');
2-
const { isEmpty, isNumber } = require('../utils');
2+
const {isEmpty, isNumber} = require('../utils');
33

44
const Search = class Search {
55
constructor() {
@@ -54,20 +54,41 @@ const Search = class Search {
5454
}
5555

5656
aggregate(value) {
57-
this.query_hash.aggregate.push(value);
57+
const found = this.query_hash.aggregate.find(v => v === value);
58+
59+
if (!found) {
60+
this.query_hash.aggregate.push(value);
61+
}
62+
5863
return this;
5964
}
6065

6166
with_field(value) {
62-
this.query_hash.with_field.push(value);
67+
const found = this.query_hash.with_field.find(v => v === value);
68+
69+
if (!found) {
70+
this.query_hash.with_field.push(value);
71+
}
72+
6373
return this;
6474
}
6575

6676
sort_by(field_name, dir = "desc") {
6777
let sort_bucket;
6878
sort_bucket = {};
6979
sort_bucket[field_name] = dir;
70-
this.query_hash.sort_by.push(sort_bucket);
80+
81+
// Check if this field name is already stored in the hash
82+
const previously_sorted_obj = this.query_hash.sort_by.find((sort_by) => sort_by[field_name]);
83+
84+
// Since objects are references in Javascript, we can update the reference we found
85+
// For example,
86+
if (previously_sorted_obj) {
87+
previously_sorted_obj[field_name] = dir;
88+
} else {
89+
this.query_hash.sort_by.push(sort_bucket);
90+
}
91+
7192
return this;
7293
}
7394

test/integration/api/search/search_spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,36 @@ describe("search_api", function () {
155155
expect(results).not.to.have.key('next_cursor');
156156
});
157157
});
158+
159+
it('Should eliminate duplicate fields when using sort_by, aggregate or with_fields', function () {
160+
// This test ensures we can't push duplicate values into sort_by, aggregate or with_fields
161+
const search_query = cloudinary.v2.search.max_results(10).expression(`tags:${SEARCH_TAG}`)
162+
.sort_by('public_id', 'asc')
163+
.sort_by('public_id', 'asc')
164+
.sort_by('public_id', 'asc')
165+
.sort_by('public_id', 'asc')
166+
.sort_by('public_id', 'desc')
167+
.sort_by('public_id', 'desc')
168+
.aggregate('foo')
169+
.aggregate('foo')
170+
.aggregate('foo2')
171+
.with_field('foo')
172+
.with_field('foo')
173+
.with_field('foo2')
174+
.to_query();
175+
176+
expect(search_query.aggregate.length).to.be(2);
177+
expect(search_query.with_field.length).to.be(2);
178+
expect(search_query.sort_by.length).to.be(1);
179+
180+
expect(search_query.aggregate[0]).to.be('foo');
181+
expect(search_query.aggregate[1]).to.be('foo2');
182+
expect(search_query.with_field[0]).to.be('foo');
183+
expect(search_query.with_field[1]).to.be('foo2');
184+
185+
expect(search_query.sort_by[0].public_id).to.be('desc');
186+
});
187+
158188
it('should include context', function () {
159189
return cloudinary.v2.search.expression(`tags:${SEARCH_TAG}`).with_field('context')
160190
.execute()

0 commit comments

Comments
 (0)