Skip to content

Commit

Permalink
fix: avoid applying map property getters when saving
Browse files Browse the repository at this point in the history
Fix #13657
  • Loading branch information
vkarpov15 committed Aug 7, 2023
1 parent 570be58 commit 197f169
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
16 changes: 15 additions & 1 deletion lib/utils.js
Expand Up @@ -630,9 +630,23 @@ function _populateObj(obj) {
*/

exports.getValue = function(path, obj, map) {
return mpath.get(path, obj, '_doc', map);
return mpath.get(path, obj, getValueLookup, map);
};

/*!
* ignore
*/

const mapGetterOptions = Object.freeze({ getters: false });

function getValueLookup(obj, part) {
const _from = obj && obj._doc ? obj._doc : obj;
obj = _from instanceof Map ?
_from.get(part, mapGetterOptions) :
_from[part];
return obj;
}

/**
* Sets the value of `obj` at the given `path`.
*
Expand Down
31 changes: 31 additions & 0 deletions test/schema.uuid.test.js
Expand Up @@ -172,6 +172,37 @@ describe('SchemaUUID', function() {
assert.equal(_id, uuid.toString());
});

it('avoids converting maps of uuids to strings (gh-13657)', async function() {
const schema = new mongoose.Schema(
{
doc_map: {
type: mongoose.Schema.Types.Map,
of: mongoose.Schema.Types.UUID
}
}
);
db.deleteModel(/Test/);
const Test = db.model('Test', schema);
await Test.deleteMany({});

const user = new Test({
doc_map: new Map([
['role_1', new mongoose.Types.UUID()],
['role_2', new mongoose.Types.UUID()]
])
});

await user.save();

user.doc_map.set('role_1', new mongoose.Types.UUID());
await user.save();

const exists = await Test.findOne({ 'doc_map.role_1': { $type: 'binData' } });
assert.ok(exists);

assert.equal(typeof user.get('doc_map.role_1'), 'string');
});

// the following are TODOs based on SchemaUUID.prototype.$conditionalHandlers which are not tested yet
it('should work with $bits* operators');
it('should work with $all operator');
Expand Down

0 comments on commit 197f169

Please sign in to comment.