diff --git a/packages/minimongo/local_collection.js b/packages/minimongo/local_collection.js index 4366d65645..ac14703cc8 100644 --- a/packages/minimongo/local_collection.js +++ b/packages/minimongo/local_collection.js @@ -660,6 +660,22 @@ export default class LocalCollection { this._observeQueue.drain(); + + // If we are doing an upsert, and we didn't modify any documents yet, then + // it's time to do an insert. Figure out what document we are inserting, and + // generate an id for it. + let insertedId; + if (updateCount === 0 && options.upsert) { + const doc = LocalCollection._createUpsertDocument(selector, mod); + if (!doc._id && options.insertedId) { + doc._id = options.insertedId; + } + + insertedId = this.insert(doc); + updateCount = 1; + } + + return this.finishUpdate({ options, updateCount, diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index fd14e99fa4..2546316119 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -212,6 +212,21 @@ Tinytest.addAsync('minimongo - basics', async test => { test.equal(after.d, undefined); }); + +Tinytest.addAsync('minimongo - upsert', async test => { + const c = new LocalCollection(); + + await c.upsertAsync({ name: 'doc' }, { name: 'doc' }); + + test.equal(c.find({}).count(), 1); + + await c.removeAsync({}); + + c.upsert({ name: 'doc' }, { name: 'doc' }); + test.equal(c.find({}).count(), 1); +}); + + Tinytest.add('minimongo - error - no options', test => { try { throw MinimongoError('Not fun to have errors');