Skip to content

Commit 76bdec5

Browse files
author
Gilles Ballini
authored
Merge pull request #209 from kuzzleio/25-document-exists
Add Collection:documentExists & Document:exists methods
2 parents 44845db + 7851021 commit 76bdec5

File tree

6 files changed

+196
-0
lines changed

6 files changed

+196
-0
lines changed

src/Collection.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,30 @@ Collection.prototype.deleteDocument = function (arg, options, cb) {
249249
return this;
250250
};
251251

252+
/**
253+
* Returns a boolean indicating whether or not a document with provided ID exists.
254+
*
255+
* @param {string} documentId - Unique document identifier
256+
* @param {object} options [options] - Optional parameters
257+
* @param {responseCallback} cb - Handles the query response
258+
*/
259+
Collection.prototype.documentExists = function (documentId, options, cb) {
260+
var
261+
data = {_id: documentId},
262+
self = this;
263+
264+
if (!cb && typeof options === 'function') {
265+
cb = options;
266+
options = null;
267+
}
268+
269+
self.kuzzle.callbackRequired('Collection.documentExists', cb);
270+
271+
self.kuzzle.query(this.buildQueryArgs('document', 'exists'), data, options, function (err, res) {
272+
cb(err, err ? undefined : res.result);
273+
});
274+
};
275+
252276
/**
253277
* Retrieve a single stored document using its unique document ID.
254278
*

src/Document.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,30 @@ Document.prototype.delete = function (options, cb) {
161161
});
162162
};
163163

164+
/**
165+
* Checks if this document exists in Kuzzle.
166+
*
167+
* @param {object} [options] - Optional parameters
168+
* @param {responseCallback} [cb] - Handles the query response
169+
* @returns {*} this
170+
*/
171+
Document.prototype.exists = function (options, cb) {
172+
var self = this;
173+
174+
if (!cb && typeof options === 'function') {
175+
cb = options;
176+
options = null;
177+
}
178+
179+
if (!self.id) {
180+
throw new Error('Document.exists: cannot check if the document exists if no id has been provided');
181+
}
182+
183+
this.kuzzle.query(this.dataCollection.buildQueryArgs('document', 'exists'), this.serialize(), options, cb && function (err, res) {
184+
cb(err, err ? undefined : res.result);
185+
});
186+
};
187+
164188
/**
165189
* Replaces the current content with the last version of this document stored in Kuzzle.
166190
*

test/Collection/constructor.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ describe('Collection constructor', function () {
4343
should.exist(collection.createPromise);
4444
should.exist(collection.createDocumentPromise);
4545
should.exist(collection.deleteDocumentPromise);
46+
should.exist(collection.documentExistsPromise);
4647
should.exist(collection.fetchDocumentPromise);
4748
should.exist(collection.fetchAllDocumentsPromise);
4849
should.exist(collection.getMappingPromise);

test/Collection/methods.test.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,67 @@ describe('Collection methods', function () {
470470
});
471471
});
472472

473+
describe('#documentExists', function () {
474+
beforeEach(function () {
475+
result = { result: true };
476+
expectedQuery = {
477+
index: 'bar',
478+
collection: 'foo',
479+
action: 'exists',
480+
controller: 'document'
481+
};
482+
});
483+
484+
it('should send the right documentExists query to Kuzzle', function(done) {
485+
var options = { queuable: false };
486+
487+
this.timeout(50);
488+
489+
collection.documentExists('foo', options, function (err, res) {
490+
should(err).be.null();
491+
should(res).be.true();
492+
done();
493+
});
494+
495+
should(kuzzle.query).be.calledOnce();
496+
should(kuzzle.query).calledWith(expectedQuery, {_id: 'foo'}, options, sinon.match.func);
497+
498+
kuzzle.query.yield(null, result);
499+
});
500+
501+
it('should raise an error if no callback is provided', function () {
502+
should(function () { collection.documentExists(); }).throw(Error);
503+
should(function () { collection.documentExists({}); }).throw(Error);
504+
should(function () { collection.documentExists({}, {}); }).throw(Error);
505+
should(kuzzle.query).not.be.called();
506+
});
507+
508+
it('should handle the callback argument correctly', function () {
509+
var
510+
cb1 = sinon.stub(),
511+
cb2 = sinon.stub();
512+
513+
collection.documentExists({}, cb1);
514+
collection.documentExists({}, {}, cb2);
515+
should(kuzzle.query).be.calledTwice();
516+
517+
kuzzle.query.yield(null, result);
518+
should(cb1).be.calledOnce();
519+
should(cb2).be.calledOnce();
520+
});
521+
522+
it('should call the callback with an error if one occurs', function (done) {
523+
this.timeout(50);
524+
525+
collection.documentExists({}, function (err, res) {
526+
should(err).be.exactly('foobar');
527+
should(res).be.undefined();
528+
done();
529+
});
530+
kuzzle.query.yield('foobar');
531+
});
532+
});
533+
473534
describe('#fetchDocument', function () {
474535
beforeEach(function () {
475536
result = { result: {_id: 'foobar', _source: {foo: 'bar'} }};

test/Document/constructor.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ describe('Document constructor', function () {
7070
var document = new Document(collection);
7171

7272
should.exist(document.deletePromise);
73+
should.not.exist(document.existsPromise);
7374
should.not.exist(document.publishPromise);
7475
should.exist(document.refreshPromise);
7576
should.exist(document.savePromise);

test/Document/methods.test.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,91 @@ describe('Document methods', function () {
134134
});
135135
});
136136

137+
describe('#exists', function () {
138+
beforeEach(function () {
139+
result = { result: true };
140+
expectedQuery = {
141+
index: 'bar',
142+
collection: 'foo',
143+
action: 'exists',
144+
controller: 'document'
145+
};
146+
});
147+
148+
it('should send the right query to Kuzzle', function () {
149+
var
150+
options = { queuable: false },
151+
document = new Document(collection);
152+
153+
document.id = 'foo';
154+
document.exists(options);
155+
should(kuzzle.query).be.calledOnce();
156+
should(kuzzle.query).calledWith(expectedQuery, {_id: 'foo', body: {}, meta: {}}, options);
157+
});
158+
159+
it('should handle arguments correctly', function () {
160+
var
161+
document = new Document(collection),
162+
cb1 = sinon.stub(),
163+
cb2 = sinon.stub();
164+
165+
document.id = 'foo';
166+
167+
document.exists(cb1);
168+
document.exists({}, cb2);
169+
170+
should(kuzzle.query).be.calledTwice();
171+
172+
kuzzle.query.yield(null, result);
173+
should(cb1).be.calledOnce();
174+
should(cb2).be.calledOnce();
175+
176+
kuzzle.query.reset();
177+
document.exists();
178+
document.exists({});
179+
180+
should(kuzzle.query).be.calledTwice();
181+
});
182+
183+
it('should throw an error if no ID has been set', function () {
184+
should(function () { document.exists(); }).throw(Error);
185+
should(function () { document.exists({}); }).throw(Error);
186+
should(function () { document.exists(sinon.stub()); }).throw(Error);
187+
should(function () { document.exists({}, sinon.stub()); }).throw(Error);
188+
should(kuzzle.query).not.be.called();
189+
});
190+
191+
it('should resolve the callback with true as the result', function (done) {
192+
var document = new Document(collection);
193+
194+
this.timeout(50);
195+
document.id = 'foo';
196+
197+
document.exists(function (err, res) {
198+
should(err).be.null();
199+
should(res).be.true();
200+
done();
201+
});
202+
203+
should(kuzzle.query).be.calledOnce();
204+
kuzzle.query.yield(null, result);
205+
});
206+
207+
it('should revolve the callback with an error if one occurs', function (done) {
208+
var document = new Document(collection);
209+
210+
this.timeout(50);
211+
document.id = 'foo';
212+
213+
document.exists(function (err, res) {
214+
should(err).be.exactly('foobar');
215+
should(res).be.undefined();
216+
done();
217+
});
218+
kuzzle.query.yield('foobar');
219+
});
220+
});
221+
137222
describe('#refresh', function () {
138223
beforeEach(function () {
139224
result = { result: {_id: 'foo', _version: 42, _source: {some: 'content'}}};

0 commit comments

Comments
 (0)