Skip to content

Commit

Permalink
Convert bson to json before comparing. Fixes #6
Browse files Browse the repository at this point in the history
  • Loading branch information
codepunkt committed Feb 11, 2017
1 parent da40045 commit 57579f6
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
11 changes: 9 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ exports.default = function (schema, opts) {
// after a document is initialized or saved, fresh snapshots of the
// documents data are created
var snapshot = function snapshot() {
this._original = this.data();
this._original = toJSON(this.data());
};
schema.post('init', snapshot);
schema.post('save', snapshot);
Expand Down Expand Up @@ -105,7 +105,7 @@ exports.default = function (schema, opts) {

var ref = this._id;

var ops = _fastJsonPatch2.default.compare(this.isNew ? {} : this._original, this.data());
var ops = _fastJsonPatch2.default.compare(this.isNew ? {} : this._original, toJSON(this.data()));

// don't save a patch when there are no changes to save
if (!ops.length) {
Expand Down Expand Up @@ -170,4 +170,11 @@ var defaultOptions = {
includes: {},
removePatches: true,
transforms: [_humps.pascalize, _humps.decamelize]
};

// used to convert bson to json - especially ObjectID references need
// to be converted to hex strings so that the jsonpatch `compare` method
// works correctly
var toJSON = function toJSON(obj) {
return JSON.parse(JSON.stringify(obj));
};
9 changes: 7 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ const defaultOptions = {
transforms: [ pascalize, decamelize ]
}

// used to convert bson to json - especially ObjectID references need
// to be converted to hex strings so that the jsonpatch `compare` method
// works correctly
const toJSON = (obj) => JSON.parse(JSON.stringify(obj))

export default function (schema, opts) {
const options = merge({}, defaultOptions, opts)

Expand Down Expand Up @@ -102,7 +107,7 @@ export default function (schema, opts) {
// after a document is initialized or saved, fresh snapshots of the
// documents data are created
const snapshot = function () {
this._original = this.data()
this._original = toJSON(this.data())
}
schema.post('init', snapshot)
schema.post('save', snapshot)
Expand All @@ -126,7 +131,7 @@ export default function (schema, opts) {
// added to the associated patch collection
schema.pre('save', function (next) {
const { _id: ref } = this
const ops = jsonpatch.compare(this.isNew ? {} : this._original, this.data())
const ops = jsonpatch.compare(this.isNew ? {} : this._original, toJSON(this.data()))

// don't save a patch when there are no changes to save
if (!ops.length) {
Expand Down
41 changes: 41 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,45 @@ describe('mongoose-patch-history', () => {
).then(() => done()).catch(done)
})
})

describe('jsonpatch.compare', () => {
let Organization
let Person

before(() => {
Organization = mongoose.model('Organization', new mongoose.Schema({
name: String
}))

const PersonSchema = new mongoose.Schema({
name: String,
organization: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Organization'
}
})

PersonSchema.plugin(patchHistory, { mongoose, name: 'roomPatches' })
Person = mongoose.model('Person', PersonSchema)
})

it('is able to handle ObjectId references correctly', (done) => {
Organization.create({ text: 'Home' })
.then((o1) => join(o1, Organization.create({ text: 'Work' })))
.then(([ o1, o2 ]) => join(o1, o2, Person.create({ name: 'Bob', organization: o1._id })))
.then(([ o1, o2, p ]) => join(o1, o2, p.set({ organization: o2._id }).save()))
.then(([ o1, o2, p ]) => join(o1, o2, p.patches.find({ ref: p.id })))
.then(([ o1, o2, patches ]) => {
const pathFilter = (path) => (elem) => elem.path === path
const firstOrganizationOperation = patches[0].ops.find(pathFilter('/organization'))
const secondOrganizationOperation = patches[1].ops.find(pathFilter('/organization'))
assert.equal(patches.length, 2)
assert(firstOrganizationOperation)
assert(secondOrganizationOperation)
assert.equal(firstOrganizationOperation.value, o1._id.toString())
assert.equal(secondOrganizationOperation.value, o2._id.toString())
})
.then(done).catch(done)
})
})
})

0 comments on commit 57579f6

Please sign in to comment.