Skip to content

Commit

Permalink
Merge pull request #31 from janis-commerce/JCN-381-Arreglar-unset-update
Browse files Browse the repository at this point in the history
JCN-381 arreglar unset update
  • Loading branch information
jormaechea committed May 2, 2022
2 parents 71a4889 + 1c27ec2 commit bae8c67
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 27 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Fixed
- Bug using `$unset` operator in stages in `update` method

## [2.3.1] - 2022-05-02
### Fixed
Expand Down
2 changes: 1 addition & 1 deletion lib/helpers/object-id.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = class ObjectIdHelper {

static ensureObjectIdsForWrite(model, item) {

if(typeof item !== 'object')
if(typeof item !== 'object' || (Array.isArray(item) && item.length && typeof item[0] === 'string'))
return item;

if(Array.isArray(item))
Expand Down
23 changes: 22 additions & 1 deletion lib/mongodb.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ module.exports = class MongoDB {
}
};

const operationGroupedValues = Array.isArray(values) ? [...values, initialValues].map(value => this.groupByWriteOperation(value, {})) :
const operationGroupedValues = Array.isArray(values) ? [...values, initialValues].map(value => this.formatPipelineStage(value)) :
this.groupByWriteOperation(values, initialValues);

const updateData = Array.isArray(operationGroupedValues) ? operationGroupedValues.map(value => this.getUpdateData(model, value)) :
Expand Down Expand Up @@ -600,6 +600,27 @@ module.exports = class MongoDB {
}
}


/**
* @private
*/
formatPipelineStage(pipeline) {

const everyStage = Object.entries(pipeline);

if(everyStage.every(([key]) => !key.startsWith('$')))
return this.groupByWriteOperation(pipeline, {});

if(everyStage.length > 1)
throw new MongoDBError('Can only be one stage per pipeline', MongoDBError.codes.INVALID_STAGES);

const [[op, value]] = everyStage;

return {
[op]: value
};
}

/**
* @private
*/
Expand Down
73 changes: 48 additions & 25 deletions tests/mongodb.js
Original file line number Diff line number Diff line change
Expand Up @@ -1071,22 +1071,11 @@ describe('MongoDB', () => {
const item = {
otherId: '5df0151dbc1d570011949d87',
name: 'Some name',
$set: {
description: 'The description'
},
$inc: {
quantity: -5
},
$push: {
children: {
id: '5df0151dbc1d570011949d88',
name: 'Children name'
}
}
description: 'The description'
};

const item2 = {
age: 10
$unset: ['children.5df0151dbc1d570011949d88', 'children.5df0151dbc1d570011949d89']
};

const options = { upsert: true };
Expand All @@ -1107,15 +1096,33 @@ describe('MongoDB', () => {

sinon.assert.calledOnceWithExactly(collection, 'myCollection');

const expectedItem = {
$set: {
otherId: ObjectId('5df0151dbc1d570011949d87'),
name: 'Some name',
description: 'The description'
},
$inc: {
quantity: -5
const expectedItem = [
{
$set: {
otherId: ObjectId('5df0151dbc1d570011949d87'),
name: 'Some name',
description: 'The description'
}
},
{ $unset: ['children.5df0151dbc1d570011949d88', 'children.5df0151dbc1d570011949d89'] },
{ $set: { dateModified: sinon.match.date } }
];

sinon.assert.calledOnceWithExactly(updateMany, {
_id: {
$eq: ObjectId(id)
}
}, expectedItem, options);
});

it('Should throw with multiple data but multiple stage in one pipeline', async () => {

const id = '5df0151dbc1d570011949d86';

const item = {
otherId: '5df0151dbc1d570011949d87',
name: 'Some name',
description: 'The description',
$push: {
children: {
id: '5df0151dbc1d570011949d88',
Expand All @@ -1124,11 +1131,27 @@ describe('MongoDB', () => {
}
};

sinon.assert.calledOnceWithExactly(updateMany, {
_id: {
$eq: ObjectId(id)
const item2 = {
$unset: 'children.5df0151dbc1d570011949d88'
};

const options = { upsert: true };

const updateMany = sinon.stub();

const collection = stubMongo(true, { updateMany });

const mongodb = new MongoDB(config);

await assert.rejects(() => mongodb.update(getModel({
otherId: {
isID: true
}
}, [expectedItem, { $set: { age: 10 } }, { $set: { dateModified: sinon.match.date } }], options);
}), [item, item2], { id }, options));


sinon.assert.notCalled(collection);
sinon.assert.notCalled(updateMany);
});
});

Expand Down

0 comments on commit bae8c67

Please sign in to comment.