diff --git a/lib/changed.js b/lib/changed.js index 1e7d996..af5b1aa 100644 --- a/lib/changed.js +++ b/lib/changed.js @@ -394,11 +394,11 @@ module.exports = function(Model, options) { _.forEach(properties, function(key) { debug('getChangedProperties: - checking property %s ', key); - if (newVals[key]) { + if (newVals[key] !== undefined) { var newVal = newVals[key]; debug('getChangedProperties: - new value %s ', newVal); - if (!oldVals[key] || !_.isEqual(oldVals[key], newVal)) { + if (oldVals[key] === undefined || !_.isEqual(oldVals[key], newVal)) { debug('getChangedProperties: - changed or new value: %s itemId: %s', newVal, itemId); changedProperties[itemId][key] = newVal; diff --git a/test/fixtures/simple-app/common/models/person.js b/test/fixtures/simple-app/common/models/person.js index a7ad1ec..beb92a1 100644 --- a/test/fixtures/simple-app/common/models/person.js +++ b/test/fixtures/simple-app/common/models/person.js @@ -21,6 +21,14 @@ module.exports = function(Person) { }); return cb.promise; }; + Person.changeFlag = function(args, cb) { + cb = cb || utils.createPromiseCallback(); + debug('this.changeFlag() called with %o', args); + process.nextTick(function() { + cb(null); + }); + return cb.promise; + }; // Define a function that should be called when a change is detected. Person.changeAge = function(args, cb) { diff --git a/test/fixtures/simple-app/common/models/person.json b/test/fixtures/simple-app/common/models/person.json index bf5cc3f..24ac6e7 100644 --- a/test/fixtures/simple-app/common/models/person.json +++ b/test/fixtures/simple-app/common/models/person.json @@ -9,7 +9,8 @@ "name": "String", "nickname": "String", "age": "Number", - "status": "String" + "status": "String", + "flag": "boolean" }, "validations": [], "relations": {}, @@ -20,7 +21,8 @@ "name": "changeName", "nickname": "changeName", "age": "changeAge", - "status": "changeStatus" + "status": "changeStatus", + "flag": "changeFlag" } } } diff --git a/test/test.js b/test/test.js index 4883058..ba23555 100644 --- a/test/test.js +++ b/test/test.js @@ -38,24 +38,26 @@ describe('loopback datasource changed property', function() { this.spyAge = this.sinon.spy(app.models.Person, 'changeAge'); this.spyStatus = this.sinon.spy(app.models.Person, 'changeStatus'); this.spyName = this.sinon.spy(app.models.Person, 'changeName'); + this.spyFlag = this.sinon.spy(app.models.Person, 'changeFlag'); }); lt.beforeEach.withApp(app); describe('when called internally', function() { lt.beforeEach.givenModel('Person', - {title: 'Mr', name:'Joe Blogs', nickname: 'joe', age: 21, status: 'active'}, 'joe'); + {title: 'Mr', name:'Joe Blogs', nickname: 'joe', age: 21, status: 'active', flag: true}, 'joe'); lt.beforeEach.givenModel('Person', - {title: 'Mr', name:'Bilbo Baggins', nickname: 'bilbo', age: 99, status: 'active'}, 'bilbo'); + {title: 'Mr', name:'Bilbo Baggins', nickname: 'bilbo', age: 99, status: 'active', flag: true}, 'bilbo'); lt.beforeEach.givenModel('Person', - {title: 'Miss', name:'Tina Turner', nickname: 'tina', age: 80, status: 'pending'}, 'tina'); + {title: 'Miss', name:'Tina Turner', nickname: 'tina', age: 80, status: 'pending', flag: false}, 'tina'); describe('Model.create', function() { it('should not run callback when creating new instances.', function(done) { var self = this; - expect(self.spyAge).not.to.have.been.called; + expect(self.spyAge).not.to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }); }); @@ -68,6 +70,7 @@ describe('loopback datasource changed property', function() { expect(self.spyAge).not.to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }) .catch(done); @@ -80,6 +83,7 @@ describe('loopback datasource changed property', function() { expect(self.spyAge).not.to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }) .catch(done); @@ -92,6 +96,7 @@ describe('loopback datasource changed property', function() { expect(self.spyAge).not.to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }) .catch(done); @@ -105,10 +110,38 @@ describe('loopback datasource changed property', function() { expect(self.spyAge).to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }) .catch(done); }); + + it('should run the callback after updating a watched property', function(done) { + var self = this; + this.joe.updateAttribute('flag', false) + .then(function(res) { + expect(res.flag).to.equal(false); + expect(self.spyAge).not.to.have.been.called; + expect(self.spyStatus).not.to.have.been.called; + expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).to.have.been.called; + done(); + }) + .catch(done); + }); + it('should run the callback after updating a watched property', function(done) { + var self = this; + this.tina.updateAttribute('flag', true) + .then(function(res) { + expect(res.flag).to.equal(true); + expect(self.spyAge).not.to.have.been.called; + expect(self.spyStatus).not.to.have.been.called; + expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).to.have.been.called; + done(); + }) + .catch(done); + }); }); describe('Model.updateAttributes', function() { @@ -119,6 +152,7 @@ describe('loopback datasource changed property', function() { expect(self.spyAge).not.to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }) .catch(done);