From 55d19c6320958f23c7318b240bf9681c8ab18ea1 Mon Sep 17 00:00:00 2001 From: linusbrolin Date: Thu, 25 Aug 2016 23:17:30 +0200 Subject: [PATCH 1/9] Added support for 'findOneAndUpdate' and 'update' with upsert This will make the sequence plugin work with upsert operations. --- lib/sequence.js | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/sequence.js b/lib/sequence.js index dbad9b7..f4fdd8b 100644 --- a/lib/sequence.js +++ b/lib/sequence.js @@ -64,7 +64,7 @@ Sequence = function(schema, options) { Sequence.getInstance = function(schema, options) { var sequence = new Sequence(schema, options), id = sequence.getId(); - + if(sequenceArchive.existsSequence(id)){ throw new Error('Counter already defined for field "'+id+'"'); } @@ -180,6 +180,7 @@ Sequence.prototype._createCounterModel = function() { * @method _setHooks */ Sequence.prototype._setHooks = function() { + this._schema.pre('save', true, (function(sequence){ return function(next, done) { var doc = this; @@ -194,6 +195,41 @@ Sequence.prototype._setHooks = function() { }.bind(doc)); }; })(this)); + + this._schema.pre('findOneAndUpdate', function(next) { + // jscs:disable + var _thisquery = this, + referenceValue; + + // jscs:enable + + this._update['$setOnInsert'] = this._update['$setOnInsert'] || {}; + + referenceValue = _this._getCounterReferenceField(this._update['$setOnInsert']); + _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { + if (err) return next(); + _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; + next(); + }.bind(this._update['$setOnInsert'])); + }); + + this._schema.pre('update', function(next, done) { + // jscs:disable + var _thisquery = this, + referenceValue; + + // jscs:enable + + this._update['$setOnInsert'] = this._update['$setOnInsert'] || {}; + + referenceValue = _this._getCounterReferenceField(this._update['$setOnInsert']); + _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { + if (err) return next(); + _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; + next(); + }.bind(this._update['$setOnInsert'])); + }); +>>>>>>> Added support for 'findOneAndUpdate' and 'update' with upsert }; /** @@ -235,7 +271,7 @@ Sequence.prototype._setMethods = function() { */ Sequence.prototype._setNextCounter = function(doc, callback) { var id = this.getId(); - var referenceValue = this._getCounterReferenceField(doc); + var referenceValue = this._getCounterReferenceField(doc); this._counterModel.findOneAndUpdate( { id: id, reference_value: referenceValue }, { $inc: { seq: 1 } }, From d0a33c8f00de9ea4990b09059d6ab2f21a74e319 Mon Sep 17 00:00:00 2001 From: linusbrolin Date: Fri, 26 Aug 2016 11:47:28 +0200 Subject: [PATCH 2/9] Fixed so the nextCounter doesn't increase for existing documents Unfortunately it seems there is no way to know in the query if an upsert will result in an insert or update, according to this mongoose issue: https://github.com/Automattic/mongoose/issues/2118 So the only way to know is to make another query to find out. --- lib/sequence.js | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/lib/sequence.js b/lib/sequence.js index f4fdd8b..440b4b4 100644 --- a/lib/sequence.js +++ b/lib/sequence.js @@ -205,12 +205,18 @@ Sequence.prototype._setHooks = function() { this._update['$setOnInsert'] = this._update['$setOnInsert'] || {}; - referenceValue = _this._getCounterReferenceField(this._update['$setOnInsert']); - _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { + this.model.findOne({_id: _thisquery._update._id}, function(err, obj) { if (err) return next(); - _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; - next(); - }.bind(this._update['$setOnInsert'])); + if (obj) return next(); + else { + referenceValue = _this._getCounterReferenceField(_thisquery._update['$setOnInsert']); + _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { + if (err) return next(); + _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; + next(); + }); + } + }); }); this._schema.pre('update', function(next, done) { @@ -222,12 +228,18 @@ Sequence.prototype._setHooks = function() { this._update['$setOnInsert'] = this._update['$setOnInsert'] || {}; - referenceValue = _this._getCounterReferenceField(this._update['$setOnInsert']); - _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { + this.model.findOne({_id: _thisquery._update._id}, function(err, obj) { if (err) return next(); - _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; - next(); - }.bind(this._update['$setOnInsert'])); + if (obj) return next(); + else { + referenceValue = _this._getCounterReferenceField(_thisquery._update['$setOnInsert']); + _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { + if (err) return next(); + _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; + next(); + }); + } + }); }); >>>>>>> Added support for 'findOneAndUpdate' and 'update' with upsert }; From ea72b30c7caf26160205e10304411dd73fa7f176 Mon Sep 17 00:00:00 2001 From: linusbrolin Date: Fri, 26 Aug 2016 13:35:32 +0200 Subject: [PATCH 3/9] Fixed the findOne query, so it uses the same conditions as the original update query This should prevent any possible error due to undefined _id in the _update object --- lib/sequence.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/sequence.js b/lib/sequence.js index 440b4b4..090b3b7 100644 --- a/lib/sequence.js +++ b/lib/sequence.js @@ -205,7 +205,7 @@ Sequence.prototype._setHooks = function() { this._update['$setOnInsert'] = this._update['$setOnInsert'] || {}; - this.model.findOne({_id: _thisquery._update._id}, function(err, obj) { + this.model.findOne(_thisquery._conditions, function(err, obj) { if (err) return next(); if (obj) return next(); else { @@ -219,6 +219,10 @@ Sequence.prototype._setHooks = function() { }); }); + this._schema.post('findOneAndUpdate', function(next) { + // console.dir(this); + }); + this._schema.pre('update', function(next, done) { // jscs:disable var _thisquery = this, @@ -228,7 +232,7 @@ Sequence.prototype._setHooks = function() { this._update['$setOnInsert'] = this._update['$setOnInsert'] || {}; - this.model.findOne({_id: _thisquery._update._id}, function(err, obj) { + this.model.findOne(_thisquery._conditions, function(err, obj) { if (err) return next(); if (obj) return next(); else { From 667f826c74d61fca352f0699061f31a40d3b6b05 Mon Sep 17 00:00:00 2001 From: linusbrolin Date: Fri, 26 Aug 2016 13:40:32 +0200 Subject: [PATCH 4/9] cleanup --- lib/sequence.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/sequence.js b/lib/sequence.js index 090b3b7..33be74d 100644 --- a/lib/sequence.js +++ b/lib/sequence.js @@ -219,10 +219,6 @@ Sequence.prototype._setHooks = function() { }); }); - this._schema.post('findOneAndUpdate', function(next) { - // console.dir(this); - }); - this._schema.pre('update', function(next, done) { // jscs:disable var _thisquery = this, From 0589d52877b7e0e817bf2d391dafbde18e8db3ad Mon Sep 17 00:00:00 2001 From: Fabrizio Ruggeri Date: Fri, 26 Aug 2016 13:37:18 +0200 Subject: [PATCH 5/9] Adds test for update and findone --- lib/sequence.js | 7 ++--- test/base.js | 74 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/lib/sequence.js b/lib/sequence.js index 33be74d..3b8b676 100644 --- a/lib/sequence.js +++ b/lib/sequence.js @@ -203,8 +203,6 @@ Sequence.prototype._setHooks = function() { // jscs:enable - this._update['$setOnInsert'] = this._update['$setOnInsert'] || {}; - this.model.findOne(_thisquery._conditions, function(err, obj) { if (err) return next(); if (obj) return next(); @@ -212,6 +210,7 @@ Sequence.prototype._setHooks = function() { referenceValue = _this._getCounterReferenceField(_thisquery._update['$setOnInsert']); _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { if (err) return next(); + _thisquery._update['$setOnInsert'] = _thisquery._update['$setOnInsert'] || {}; _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; next(); }); @@ -219,6 +218,7 @@ Sequence.prototype._setHooks = function() { }); }); + this._schema.pre('update', function(next, done) { // jscs:disable var _thisquery = this, @@ -226,7 +226,6 @@ Sequence.prototype._setHooks = function() { // jscs:enable - this._update['$setOnInsert'] = this._update['$setOnInsert'] || {}; this.model.findOne(_thisquery._conditions, function(err, obj) { if (err) return next(); @@ -235,13 +234,13 @@ Sequence.prototype._setHooks = function() { referenceValue = _this._getCounterReferenceField(_thisquery._update['$setOnInsert']); _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { if (err) return next(); + _thisquery._update['$setOnInsert'] = _thisquery._update['$setOnInsert'] || {}; _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; next(); }); } }); }); ->>>>>>> Added support for 'findOneAndUpdate' and 'update' with upsert }; /** diff --git a/test/base.js b/test/base.js index 962c845..34e7d51 100644 --- a/test/base.js +++ b/test/base.js @@ -228,6 +228,76 @@ describe('Basic => ', function() { }); + describe('hook', function(){ + before(function(done) { + var SimpleFieldSchema = new Schema({ + id: Number, + val: String, + tag: String + }); + var wrapper = function(schema, options) { + var instance = AutoIncrement(schema, options); + this.setNextCounterSpy = sinon.spy(instance, '_setNextCounter'); + return instance; + }.bind(this); + SimpleFieldSchema.plugin(wrapper, {id: 'id_hook_test', inc_field: 'id'}); + this.SimpleField = mongoose.model('SimpleFieldHookTest', SimpleFieldSchema); + this.SimpleField.create({val: 'existing'}, function(err){ + this.setNextCounterSpy.reset(); + done(err); + }.bind(this)); + }); + + afterEach(function(){ + this.setNextCounterSpy.reset(); + }); + + it('is called when saving a new document', function(done){ + var t = new this.SimpleField({val: 'a'}); + t.save(function(err){ + sinon.assert.calledOnce(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); + + it('is not called when saving an existing document', function(done){ + var t = new this.SimpleField({val: 'a'}); + t.isNew = false; + t.save(function(err){ + sinon.assert.notCalled(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); + + it('is called when upserting in an update and result in an insert', function(done){ + this.SimpleField.update({val: '1234'}, {tag: 'nothing'}, {upsert: true}, function(err, doc){ + sinon.assert.calledOnce(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); + + it('is not called when upserting in an update and not result in an insert', function(done){ + this.SimpleField.update({val: 'existing'}, {tag: 'update'}, {upsert: true}, function(err, doc){ + sinon.assert.notCalled(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); + + it('is called when upserting in an findOneAndUpdate and result in an insert', function(done){ + this.SimpleField.findOneAndUpdate({val: '4567'}, {tag: 'nothing'}, {upsert: true}, function(err, doc){ + sinon.assert.calledOnce(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); + + it('is not called when upserting in an findOneAndUpdate and not result in an insert', function(done){ + this.SimpleField.findOneAndUpdate({val: '1234'}, {tag: 'findOneAndUpdate'}, {upsert: true}, function(err, doc){ + sinon.assert.notCalled(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); + }); + describe('a manual increment field => ', function() { before(function(done) { @@ -342,7 +412,7 @@ describe('Basic => ', function() { assert.throws(function(){ UnusedSchema.plugin(AutoIncrement, {inc_field: 'inhabitant', reference_fields: ['country', 'city'], disable_hooks: true}); }, Error); - + }); }); @@ -427,7 +497,7 @@ describe('Basic => ', function() { }); }); }); - }); + }); }); }); From d70a9f805b351e003466be55eef76726973cedd1 Mon Sep 17 00:00:00 2001 From: linusbrolin Date: Fri, 26 Aug 2016 14:14:16 +0200 Subject: [PATCH 6/9] Fixed bug where the reference value(s) would not be found --- lib/sequence.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sequence.js b/lib/sequence.js index 3b8b676..0133870 100644 --- a/lib/sequence.js +++ b/lib/sequence.js @@ -207,7 +207,7 @@ Sequence.prototype._setHooks = function() { if (err) return next(); if (obj) return next(); else { - referenceValue = _this._getCounterReferenceField(_thisquery._update['$setOnInsert']); + referenceValue = _this._getCounterReferenceField(_thisquery._update); _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { if (err) return next(); _thisquery._update['$setOnInsert'] = _thisquery._update['$setOnInsert'] || {}; @@ -231,7 +231,7 @@ Sequence.prototype._setHooks = function() { if (err) return next(); if (obj) return next(); else { - referenceValue = _this._getCounterReferenceField(_thisquery._update['$setOnInsert']); + referenceValue = _this._getCounterReferenceField(_thisquery._update); _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { if (err) return next(); _thisquery._update['$setOnInsert'] = _thisquery._update['$setOnInsert'] || {}; From 96d6639c28fb8f8b7c53ef32c87d793a8fadaada Mon Sep 17 00:00:00 2001 From: Fabrizio Ruggeri Date: Fri, 26 Aug 2016 17:13:34 +0200 Subject: [PATCH 7/9] Fix after rebase --- lib/sequence.js | 9 +++++++-- test/base.js | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/sequence.js b/lib/sequence.js index 0133870..05e5ce6 100644 --- a/lib/sequence.js +++ b/lib/sequence.js @@ -180,6 +180,7 @@ Sequence.prototype._createCounterModel = function() { * @method _setHooks */ Sequence.prototype._setHooks = function() { + var _this = this; this._schema.pre('save', true, (function(sequence){ return function(next, done) { @@ -208,7 +209,7 @@ Sequence.prototype._setHooks = function() { if (obj) return next(); else { referenceValue = _this._getCounterReferenceField(_thisquery._update); - _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { + _this._setNextCounterByReference(_this._options.reference_fields, referenceValue, function(err, seq) { if (err) return next(); _thisquery._update['$setOnInsert'] = _thisquery._update['$setOnInsert'] || {}; _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; @@ -232,7 +233,7 @@ Sequence.prototype._setHooks = function() { if (obj) return next(); else { referenceValue = _this._getCounterReferenceField(_thisquery._update); - _this._setNextCounter(_this._options.reference_fields, referenceValue, function(err, seq) { + _this._setNextCounterByReference(_this._options.reference_fields, referenceValue, function(err, seq) { if (err) return next(); _thisquery._update['$setOnInsert'] = _thisquery._update['$setOnInsert'] || {}; _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; @@ -283,6 +284,10 @@ Sequence.prototype._setMethods = function() { Sequence.prototype._setNextCounter = function(doc, callback) { var id = this.getId(); var referenceValue = this._getCounterReferenceField(doc); + this._setNextCounterByReference(id, referenceValue, callback); +}; + +Sequence.prototype._setNextCounterByReference = function(id, referenceValue, callback) { this._counterModel.findOneAndUpdate( { id: id, reference_value: referenceValue }, { $inc: { seq: 1 } }, diff --git a/test/base.js b/test/base.js index 34e7d51..fd73c3d 100644 --- a/test/base.js +++ b/test/base.js @@ -237,7 +237,7 @@ describe('Basic => ', function() { }); var wrapper = function(schema, options) { var instance = AutoIncrement(schema, options); - this.setNextCounterSpy = sinon.spy(instance, '_setNextCounter'); + this.setNextCounterSpy = sinon.spy(instance, '_setNextCounterByReference'); return instance; }.bind(this); SimpleFieldSchema.plugin(wrapper, {id: 'id_hook_test', inc_field: 'id'}); From fe61282c98e661a5afae4f01dee46364afdbb524 Mon Sep 17 00:00:00 2001 From: Fabrizio Ruggeri Date: Fri, 26 Aug 2016 19:42:40 +0200 Subject: [PATCH 8/9] Tests for reference field hooks behavior Adds tests which demonstrate that reference fileds are not upated correctly --- lib/sequence.js | 2 - test/base.js | 194 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 137 insertions(+), 59 deletions(-) diff --git a/lib/sequence.js b/lib/sequence.js index 05e5ce6..9863e69 100644 --- a/lib/sequence.js +++ b/lib/sequence.js @@ -119,7 +119,6 @@ Sequence.prototype._getCounterReferenceField = function(doc) { reference.push(JSON.stringify(doc[this._options.reference_fields[i]])); } } - return reference; }; @@ -263,7 +262,6 @@ Sequence.prototype._setMethods = function() { if (_.isNull(sequence)) { return callback(new Error('Trying to increment a wrong sequence using the id ' + id)); } - // sequence = sequence.sequence; sequence._setNextCounter(this, function(err, seq) { if (err) return callback(err); diff --git a/test/base.js b/test/base.js index fd73c3d..7a318a8 100644 --- a/test/base.js +++ b/test/base.js @@ -229,72 +229,152 @@ describe('Basic => ', function() { }); describe('hook', function(){ - before(function(done) { - var SimpleFieldSchema = new Schema({ - id: Number, - val: String, - tag: String - }); - var wrapper = function(schema, options) { - var instance = AutoIncrement(schema, options); - this.setNextCounterSpy = sinon.spy(instance, '_setNextCounterByReference'); - return instance; - }.bind(this); - SimpleFieldSchema.plugin(wrapper, {id: 'id_hook_test', inc_field: 'id'}); - this.SimpleField = mongoose.model('SimpleFieldHookTest', SimpleFieldSchema); - this.SimpleField.create({val: 'existing'}, function(err){ + describe('simple counters', function(){ + before(function(done) { + var SimpleFieldSchema = new Schema({ + id: Number, + val: String, + tag: String + }); + var wrapper = function(schema, options) { + var instance = AutoIncrement(schema, options); + this.setNextCounterSpy = sinon.spy(instance, '_setNextCounterByReference'); + return instance; + }.bind(this); + SimpleFieldSchema.plugin(wrapper, {id: 'id_hook_test', inc_field: 'id'}); + this.SimpleField = mongoose.model('SimpleFieldHookTest', SimpleFieldSchema); + this.SimpleField.create({val: 'existing'}, function(err){ + this.setNextCounterSpy.reset(); + done(err); + }.bind(this)); + }); + + afterEach(function(){ this.setNextCounterSpy.reset(); - done(err); - }.bind(this)); - }); + }); - afterEach(function(){ - this.setNextCounterSpy.reset(); - }); + it('is called when saving a new document', function(done){ + var t = new this.SimpleField({val: 'a'}); + t.save(function(err){ + sinon.assert.calledOnce(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); - it('is called when saving a new document', function(done){ - var t = new this.SimpleField({val: 'a'}); - t.save(function(err){ - sinon.assert.calledOnce(this.setNextCounterSpy); - done(err); - }.bind(this)); - }); + it('is not called when saving an existing document', function(done){ + var t = new this.SimpleField({val: 'a'}); + t.isNew = false; + t.save(function(err){ + sinon.assert.notCalled(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); - it('is not called when saving an existing document', function(done){ - var t = new this.SimpleField({val: 'a'}); - t.isNew = false; - t.save(function(err){ - sinon.assert.notCalled(this.setNextCounterSpy); - done(err); - }.bind(this)); - }); + it('is called when upserting in an update and result in an insert', function(done){ + this.SimpleField.update({val: '1234'}, {tag: 'nothing'}, {upsert: true}, function(err, doc){ + sinon.assert.calledOnce(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); - it('is called when upserting in an update and result in an insert', function(done){ - this.SimpleField.update({val: '1234'}, {tag: 'nothing'}, {upsert: true}, function(err, doc){ - sinon.assert.calledOnce(this.setNextCounterSpy); - done(err); - }.bind(this)); - }); + it('is not called when upserting in an update and not result in an insert', function(done){ + this.SimpleField.update({val: 'existing'}, {tag: 'update'}, {upsert: true}, function(err, doc){ + sinon.assert.notCalled(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); - it('is not called when upserting in an update and not result in an insert', function(done){ - this.SimpleField.update({val: 'existing'}, {tag: 'update'}, {upsert: true}, function(err, doc){ - sinon.assert.notCalled(this.setNextCounterSpy); - done(err); - }.bind(this)); - }); + it('is called when upserting in an findOneAndUpdate and result in an insert', function(done){ + this.SimpleField.findOneAndUpdate({val: '4567'}, {tag: 'nothing'}, {upsert: true}, function(err, doc){ + sinon.assert.calledOnce(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); - it('is called when upserting in an findOneAndUpdate and result in an insert', function(done){ - this.SimpleField.findOneAndUpdate({val: '4567'}, {tag: 'nothing'}, {upsert: true}, function(err, doc){ - sinon.assert.calledOnce(this.setNextCounterSpy); - done(err); - }.bind(this)); + it('is not called when upserting in an findOneAndUpdate and not result in an insert', function(done){ + this.SimpleField.findOneAndUpdate({val: '1234'}, {tag: 'findOneAndUpdate'}, {upsert: true}, function(err, doc){ + sinon.assert.notCalled(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); }); - it('is not called when upserting in an findOneAndUpdate and not result in an insert', function(done){ - this.SimpleField.findOneAndUpdate({val: '1234'}, {tag: 'findOneAndUpdate'}, {upsert: true}, function(err, doc){ - sinon.assert.notCalled(this.setNextCounterSpy); - done(err); - }.bind(this)); + describe('referenced counters', function() { + before(function(done) { + var SimpleFieldSchema = new Schema({ + same_tag_members: Number, + val: String, + tag: String + }); + var wrapper = function(schema, options) { + var instance = AutoIncrement(schema, options); + this.instance = instance; + this.setNextCounterSpy = sinon.spy(instance, '_setNextCounterByReference'); + return instance; + }.bind(this); + SimpleFieldSchema.plugin(wrapper, { + id: 'id_hook_test_referenced', + inc_field: 'same_tag_members', + reference_fields: ['tag']} + ); + this.SimpleField = mongoose.model('SimpleFieldHookTestReferenced', SimpleFieldSchema); + this.SimpleField.create({val: 'existing'}, function(err){ + this.setNextCounterSpy.reset(); + done(err); + }.bind(this)); + }); + + afterEach(function(){ + this.setNextCounterSpy.reset(); + }); + + it('are called when saving a new document', function(done){ + var t = new this.SimpleField({val: 'a', tag: 'red'}); + t.save(function(err){ + sinon.assert.calledWith( + this.setNextCounterSpy, + 'id_hook_test_referenced', + this.instance._getCounterReferenceField(t) + ); + done(err); + }.bind(this)); + }); + + it('are called when upserting in an update and result in an insert', function(done){ + this.SimpleField.update({val: '1234'}, {tag: 'blue'}, {upsert: true}, function(err, doc){ + sinon.assert.calledWith( + this.setNextCounterSpy, + 'id_hook_test_referenced', + this.instance._getCounterReferenceField({tag:'blue'}) + ); + done(err); + }.bind(this)); + }); + + it('are not called when upserting in an update and not result in an insert', function(done){ + this.SimpleField.update({val: 'existing'}, {tag: 'green'}, {upsert: true}, function(err, doc){ + sinon.assert.notCalled(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); + + it('is called when upserting in an findOneAndUpdate and result in an insert', function(done){ + this.SimpleField.findOneAndUpdate({val: '4567'}, {tag: 'pink'}, {upsert: true}, function(err, doc){ + sinon.assert.calledWith( + this.setNextCounterSpy, + 'id_hook_test_referenced', + this.instance._getCounterReferenceField({tag:'blue'}) + ); + done(err); + }.bind(this)); + }); + + it('is not called when upserting in an findOneAndUpdate and not result in an insert', function(done){ + this.SimpleField.findOneAndUpdate({val: '1234'}, {tag: 'yellow'}, {upsert: true}, function(err, doc){ + sinon.assert.notCalled(this.setNextCounterSpy); + done(err); + }.bind(this)); + }); }); }); From 98b11b87547f0d267259f6e40aceb1e9b97f54ac Mon Sep 17 00:00:00 2001 From: Fabrizio Ruggeri Date: Fri, 26 Aug 2016 19:52:08 +0200 Subject: [PATCH 9/9] Fix non-passing tests Looks like those hooks are complex to manage --- lib/sequence.js | 6 +++--- test/base.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/sequence.js b/lib/sequence.js index 9863e69..549e0c0 100644 --- a/lib/sequence.js +++ b/lib/sequence.js @@ -208,7 +208,7 @@ Sequence.prototype._setHooks = function() { if (obj) return next(); else { referenceValue = _this._getCounterReferenceField(_thisquery._update); - _this._setNextCounterByReference(_this._options.reference_fields, referenceValue, function(err, seq) { + _this._setNextCounterByReference(_this.getId(), referenceValue, function(err, seq) { if (err) return next(); _thisquery._update['$setOnInsert'] = _thisquery._update['$setOnInsert'] || {}; _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; @@ -231,8 +231,8 @@ Sequence.prototype._setHooks = function() { if (err) return next(); if (obj) return next(); else { - referenceValue = _this._getCounterReferenceField(_thisquery._update); - _this._setNextCounterByReference(_this._options.reference_fields, referenceValue, function(err, seq) { + referenceValue = _this._getCounterReferenceField(_thisquery._update.$set); + _this._setNextCounterByReference(_this.getId(), referenceValue, function(err, seq) { if (err) return next(); _thisquery._update['$setOnInsert'] = _thisquery._update['$setOnInsert'] || {}; _thisquery._update['$setOnInsert'][_this._options.inc_field] = seq; diff --git a/test/base.js b/test/base.js index 7a318a8..8722eb5 100644 --- a/test/base.js +++ b/test/base.js @@ -358,18 +358,18 @@ describe('Basic => ', function() { }.bind(this)); }); - it('is called when upserting in an findOneAndUpdate and result in an insert', function(done){ + it('are called when upserting in an findOneAndUpdate and result in an insert', function(done){ this.SimpleField.findOneAndUpdate({val: '4567'}, {tag: 'pink'}, {upsert: true}, function(err, doc){ sinon.assert.calledWith( this.setNextCounterSpy, 'id_hook_test_referenced', - this.instance._getCounterReferenceField({tag:'blue'}) + this.instance._getCounterReferenceField({tag:'pink'}) ); done(err); }.bind(this)); }); - it('is not called when upserting in an findOneAndUpdate and not result in an insert', function(done){ + it('are not called when upserting in an findOneAndUpdate and not result in an insert', function(done){ this.SimpleField.findOneAndUpdate({val: '1234'}, {tag: 'yellow'}, {upsert: true}, function(err, doc){ sinon.assert.notCalled(this.setNextCounterSpy); done(err);