Skip to content

Commit 57579f6

Browse files
committed
Convert bson to json before comparing. Fixes #6
1 parent da40045 commit 57579f6

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

lib/index.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ exports.default = function (schema, opts) {
7575
// after a document is initialized or saved, fresh snapshots of the
7676
// documents data are created
7777
var snapshot = function snapshot() {
78-
this._original = this.data();
78+
this._original = toJSON(this.data());
7979
};
8080
schema.post('init', snapshot);
8181
schema.post('save', snapshot);
@@ -105,7 +105,7 @@ exports.default = function (schema, opts) {
105105

106106
var ref = this._id;
107107

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

110110
// don't save a patch when there are no changes to save
111111
if (!ops.length) {
@@ -170,4 +170,11 @@ var defaultOptions = {
170170
includes: {},
171171
removePatches: true,
172172
transforms: [_humps.pascalize, _humps.decamelize]
173+
};
174+
175+
// used to convert bson to json - especially ObjectID references need
176+
// to be converted to hex strings so that the jsonpatch `compare` method
177+
// works correctly
178+
var toJSON = function toJSON(obj) {
179+
return JSON.parse(JSON.stringify(obj));
173180
};

src/index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ const defaultOptions = {
3939
transforms: [ pascalize, decamelize ]
4040
}
4141

42+
// used to convert bson to json - especially ObjectID references need
43+
// to be converted to hex strings so that the jsonpatch `compare` method
44+
// works correctly
45+
const toJSON = (obj) => JSON.parse(JSON.stringify(obj))
46+
4247
export default function (schema, opts) {
4348
const options = merge({}, defaultOptions, opts)
4449

@@ -102,7 +107,7 @@ export default function (schema, opts) {
102107
// after a document is initialized or saved, fresh snapshots of the
103108
// documents data are created
104109
const snapshot = function () {
105-
this._original = this.data()
110+
this._original = toJSON(this.data())
106111
}
107112
schema.post('init', snapshot)
108113
schema.post('save', snapshot)
@@ -126,7 +131,7 @@ export default function (schema, opts) {
126131
// added to the associated patch collection
127132
schema.pre('save', function (next) {
128133
const { _id: ref } = this
129-
const ops = jsonpatch.compare(this.isNew ? {} : this._original, this.data())
134+
const ops = jsonpatch.compare(this.isNew ? {} : this._original, toJSON(this.data()))
130135

131136
// don't save a patch when there are no changes to save
132137
if (!ops.length) {

test/index.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,45 @@ describe('mongoose-patch-history', () => {
223223
).then(() => done()).catch(done)
224224
})
225225
})
226+
227+
describe('jsonpatch.compare', () => {
228+
let Organization
229+
let Person
230+
231+
before(() => {
232+
Organization = mongoose.model('Organization', new mongoose.Schema({
233+
name: String
234+
}))
235+
236+
const PersonSchema = new mongoose.Schema({
237+
name: String,
238+
organization: {
239+
type: mongoose.Schema.Types.ObjectId,
240+
ref: 'Organization'
241+
}
242+
})
243+
244+
PersonSchema.plugin(patchHistory, { mongoose, name: 'roomPatches' })
245+
Person = mongoose.model('Person', PersonSchema)
246+
})
247+
248+
it('is able to handle ObjectId references correctly', (done) => {
249+
Organization.create({ text: 'Home' })
250+
.then((o1) => join(o1, Organization.create({ text: 'Work' })))
251+
.then(([ o1, o2 ]) => join(o1, o2, Person.create({ name: 'Bob', organization: o1._id })))
252+
.then(([ o1, o2, p ]) => join(o1, o2, p.set({ organization: o2._id }).save()))
253+
.then(([ o1, o2, p ]) => join(o1, o2, p.patches.find({ ref: p.id })))
254+
.then(([ o1, o2, patches ]) => {
255+
const pathFilter = (path) => (elem) => elem.path === path
256+
const firstOrganizationOperation = patches[0].ops.find(pathFilter('/organization'))
257+
const secondOrganizationOperation = patches[1].ops.find(pathFilter('/organization'))
258+
assert.equal(patches.length, 2)
259+
assert(firstOrganizationOperation)
260+
assert(secondOrganizationOperation)
261+
assert.equal(firstOrganizationOperation.value, o1._id.toString())
262+
assert.equal(secondOrganizationOperation.value, o2._id.toString())
263+
})
264+
.then(done).catch(done)
265+
})
266+
})
226267
})

0 commit comments

Comments
 (0)