mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Fix collection driver upsert callbacks.
Run a bunch of upsert tests on the direct collections (LocalCollection and MongoConnection). Revealed a weirdness with MongoConnection.upsert(); if there is no id from the selector or modifier, then mongo ends up generating one and we don't return it.
This commit is contained in:
@@ -637,7 +637,7 @@ LocalCollection.prototype.upsert = function (selector, mod, options, callback) {
|
||||
return self.update(selector, mod, _.extend({}, options, {
|
||||
upsert: true,
|
||||
_returnObject: true
|
||||
}, callback));
|
||||
}), callback);
|
||||
};
|
||||
|
||||
LocalCollection.prototype._modifyAndNotify = function (
|
||||
|
||||
@@ -489,6 +489,9 @@ _.each(["insert", "update", "remove"], function (method) {
|
||||
};
|
||||
});
|
||||
|
||||
// XXX MongoConnection.upsert() does not return the id of the inserted document
|
||||
// unless you set it explicitly in the selector or modifier (as a replacement
|
||||
// doc).
|
||||
MongoConnection.prototype.upsert = function (collectionName, selector, mod,
|
||||
options, callback) {
|
||||
var self = this;
|
||||
@@ -501,7 +504,7 @@ MongoConnection.prototype.upsert = function (collectionName, selector, mod,
|
||||
_.extend({}, options, {
|
||||
upsert: true,
|
||||
_returnObject: true
|
||||
}, callback));
|
||||
}), callback);
|
||||
};
|
||||
|
||||
MongoConnection.prototype.find = function (collectionName, selector, options) {
|
||||
|
||||
@@ -30,8 +30,8 @@ var stripId = function (obj) {
|
||||
delete obj._id;
|
||||
};
|
||||
|
||||
var compareResults = function (test, useUpdate, actual, expected) {
|
||||
if (useUpdate) {
|
||||
var compareResults = function (test, skipIds, actual, expected) {
|
||||
if (skipIds) {
|
||||
_.map(actual, stripId);
|
||||
_.map(expected, stripId);
|
||||
}
|
||||
@@ -1057,291 +1057,343 @@ if (Meteor.isServer) {
|
||||
// over the network.
|
||||
_.each(Meteor.isServer ? [true, false] : [true], function (minimongo) {
|
||||
_.each([true, false], function (useUpdate) {
|
||||
Tinytest.add("mongo-livedata - " + (useUpdate ? "update " : "") + "upsert" + (minimongo ? " minimongo" : "") + ", " + idGeneration, function (test) {
|
||||
var run = test.runId();
|
||||
var options = collectionOptions;
|
||||
if (minimongo)
|
||||
options = _.extend({}, collectionOptions, { connection: null });
|
||||
var coll = new Meteor.Collection("livedata_upsert_collection_"+run, options);
|
||||
_.each([true, false], function (useDirectCollection) {
|
||||
Tinytest.add("mongo-livedata - " + (useUpdate ? "update " : "") + "upsert" + (minimongo ? " minimongo" : "") + (useDirectCollection ? " direct collection " : "") + ", " + idGeneration, function (test) {
|
||||
var run = test.runId();
|
||||
var options = collectionOptions;
|
||||
// We don't get ids back when we use update() to upsert, or when we are
|
||||
// directly calling MongoConnection.upsert().
|
||||
var skipIds = useUpdate || (! minimongo && useDirectCollection);
|
||||
if (minimongo)
|
||||
options = _.extend({}, collectionOptions, { connection: null });
|
||||
var coll = new Meteor.Collection(
|
||||
"livedata_upsert_collection_"+run+
|
||||
(useUpdate ? "_update_" : "") +
|
||||
(minimongo ? "_minimongo_" : "") +
|
||||
(useDirectCollection ? "_direct_" : "") + "",
|
||||
options
|
||||
);
|
||||
if (useDirectCollection)
|
||||
coll = coll._collection;
|
||||
|
||||
var result1 = upsert(coll, useUpdate, {foo: 'bar'}, {foo: 'bar'});
|
||||
test.equal(result1.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isTrue(result1.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: 'bar', _id: result1.insertedId}]);
|
||||
var result1 = upsert(coll, useUpdate, {foo: 'bar'}, {foo: 'bar'});
|
||||
test.equal(result1.numberAffected, 1);
|
||||
if (! skipIds)
|
||||
test.isTrue(result1.insertedId);
|
||||
compareResults(test, skipIds, coll.find().fetch(), [{foo: 'bar', _id: result1.insertedId}]);
|
||||
|
||||
var result2 = upsert(coll, useUpdate, {foo: 'bar'}, {foo: 'baz'});
|
||||
test.equal(result2.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result2.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: 'baz', _id: result1.insertedId}]);
|
||||
var result2 = upsert(coll, useUpdate, {foo: 'bar'}, {foo: 'baz'});
|
||||
test.equal(result2.numberAffected, 1);
|
||||
if (! skipIds)
|
||||
test.isFalse(result2.insertedId);
|
||||
compareResults(test, skipIds, coll.find().fetch(), [{foo: 'baz', _id: result1.insertedId}]);
|
||||
|
||||
coll.remove({});
|
||||
coll.remove({});
|
||||
|
||||
// Test values that require transformation to go into Mongo:
|
||||
// Test values that require transformation to go into Mongo:
|
||||
|
||||
var t1 = new Meteor.Collection.ObjectID();
|
||||
var t2 = new Meteor.Collection.ObjectID();
|
||||
var result3 = upsert(coll, useUpdate, {foo: t1}, {foo: t1});
|
||||
test.equal(result3.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isTrue(result3.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: t1, _id: result3.insertedId}]);
|
||||
var t1 = new Meteor.Collection.ObjectID();
|
||||
var t2 = new Meteor.Collection.ObjectID();
|
||||
var result3 = upsert(coll, useUpdate, {foo: t1}, {foo: t1});
|
||||
test.equal(result3.numberAffected, 1);
|
||||
if (! skipIds)
|
||||
test.isTrue(result3.insertedId);
|
||||
compareResults(test, skipIds, coll.find().fetch(), [{foo: t1, _id: result3.insertedId}]);
|
||||
|
||||
var result4 = upsert(coll, useUpdate, {foo: t1}, {foo: t2});
|
||||
test.equal(result2.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result2.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: t2, _id: result3.insertedId}]);
|
||||
var result4 = upsert(coll, useUpdate, {foo: t1}, {foo: t2});
|
||||
test.equal(result2.numberAffected, 1);
|
||||
if (! skipIds)
|
||||
test.isFalse(result2.insertedId);
|
||||
compareResults(test, skipIds, coll.find().fetch(), [{foo: t2, _id: result3.insertedId}]);
|
||||
|
||||
coll.remove({});
|
||||
coll.remove({});
|
||||
|
||||
// Test modification by upsert
|
||||
// Test modification by upsert
|
||||
|
||||
var result5 = upsert(coll, useUpdate, {name: 'David'}, {$set: {foo: 1}});
|
||||
test.equal(result5.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isTrue(result5.insertedId);
|
||||
var davidId = result5.insertedId;
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{name: 'David', foo: 1, _id: davidId}]);
|
||||
var result5 = upsert(coll, useUpdate, {name: 'David'}, {$set: {foo: 1}});
|
||||
test.equal(result5.numberAffected, 1);
|
||||
if (! skipIds)
|
||||
test.isTrue(result5.insertedId);
|
||||
var davidId = result5.insertedId;
|
||||
compareResults(test, skipIds, coll.find().fetch(), [{name: 'David', foo: 1, _id: davidId}]);
|
||||
|
||||
test.throws(function () {
|
||||
// test that bad modifier fails fast
|
||||
upsert(coll, useUpdate, {name: 'David'}, {$blah: {foo: 2}});
|
||||
test.throws(function () {
|
||||
// test that bad modifier fails fast
|
||||
upsert(coll, useUpdate, {name: 'David'}, {$blah: {foo: 2}});
|
||||
});
|
||||
|
||||
|
||||
var result6 = upsert(coll, useUpdate, {name: 'David'}, {$set: {foo: 2}});
|
||||
test.equal(result6.numberAffected, 1);
|
||||
if (! skipIds)
|
||||
test.isFalse(result6.insertedId);
|
||||
compareResults(test, skipIds, coll.find().fetch(), [{name: 'David', foo: 2,
|
||||
_id: result5.insertedId}]);
|
||||
|
||||
var emilyId = coll.insert({name: 'Emily', foo: 2});
|
||||
compareResults(test, skipIds, coll.find().fetch(), [{name: 'David', foo: 2, _id: davidId},
|
||||
{name: 'Emily', foo: 2, _id: emilyId}]);
|
||||
|
||||
// multi update by upsert
|
||||
var result7 = upsert(coll, useUpdate, {foo: 2},
|
||||
{$set: {bar: 7},
|
||||
$setOnInsert: {name: 'Fred', foo: 2}},
|
||||
{multi: true});
|
||||
test.equal(result7.numberAffected, 2);
|
||||
if (! skipIds)
|
||||
test.isFalse(result7.insertedId);
|
||||
compareResults(test, skipIds, coll.find().fetch(), [{name: 'David', foo: 2, bar: 7, _id: davidId},
|
||||
{name: 'Emily', foo: 2, bar: 7, _id: emilyId}]);
|
||||
|
||||
// insert by multi upsert
|
||||
var result8 = upsert(coll, useUpdate, {foo: 3},
|
||||
{$set: {bar: 7},
|
||||
$setOnInsert: {name: 'Fred', foo: 2}},
|
||||
{multi: true});
|
||||
test.equal(result8.numberAffected, 1);
|
||||
if (! skipIds)
|
||||
test.isTrue(result8.insertedId);
|
||||
var fredId = result8.insertedId;
|
||||
compareResults(test, skipIds, coll.find().fetch(),
|
||||
[{name: 'David', foo: 2, bar: 7, _id: davidId},
|
||||
{name: 'Emily', foo: 2, bar: 7, _id: emilyId},
|
||||
{name: 'Fred', foo: 2, bar: 7, _id: fredId}]);
|
||||
|
||||
// test `insertedId` option
|
||||
var result9 = upsert(coll, useUpdate, {name: 'Steve'},
|
||||
{name: 'Steve'},
|
||||
{insertedId: 'steve'});
|
||||
test.equal(result9.numberAffected, 1);
|
||||
if (! skipIds)
|
||||
test.equal(result9.insertedId, 'steve');
|
||||
compareResults(test, skipIds, coll.find().fetch(),
|
||||
[{name: 'David', foo: 2, bar: 7, _id: davidId},
|
||||
{name: 'Emily', foo: 2, bar: 7, _id: emilyId},
|
||||
{name: 'Fred', foo: 2, bar: 7, _id: fredId},
|
||||
{name: 'Steve', _id: 'steve'}]);
|
||||
test.isTrue(coll.findOne('steve'));
|
||||
test.isFalse(coll.findOne('fred'));
|
||||
|
||||
// Test $ operator in selectors.
|
||||
|
||||
var result10 = upsert(coll, useUpdate,
|
||||
{$or: [{name: 'David'}, {name: 'Emily'}]},
|
||||
{$set: {foo: 3}}, {multi: true});
|
||||
test.equal(result10.numberAffected, 2);
|
||||
if (! skipIds)
|
||||
test.isFalse(result10.insertedId);
|
||||
compareResults(test, skipIds,
|
||||
[coll.findOne({name: 'David'}), coll.findOne({name: 'Emily'})],
|
||||
[{name: 'David', foo: 3, bar: 7, _id: davidId},
|
||||
{name: 'Emily', foo: 3, bar: 7, _id: emilyId}]
|
||||
);
|
||||
|
||||
var result11 = upsert(
|
||||
coll, useUpdate,
|
||||
{
|
||||
name: 'Charlie',
|
||||
$or: [{ foo: 2}, { bar: 7 }]
|
||||
},
|
||||
{ $set: { foo: 3 } }
|
||||
);
|
||||
test.equal(result11.numberAffected, 1);
|
||||
if (! skipIds)
|
||||
test.isTrue(result11.insertedId);
|
||||
var charlieId = result11.insertedId;
|
||||
compareResults(test, skipIds,
|
||||
coll.find({ name: 'Charlie' }).fetch(),
|
||||
[{name: 'Charlie', foo: 3, _id: charlieId}]);
|
||||
});
|
||||
|
||||
|
||||
var result6 = upsert(coll, useUpdate, {name: 'David'}, {$set: {foo: 2}});
|
||||
test.equal(result6.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result6.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{name: 'David', foo: 2,
|
||||
_id: result5.insertedId}]);
|
||||
|
||||
var emilyId = coll.insert({name: 'Emily', foo: 2});
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{name: 'David', foo: 2, _id: davidId},
|
||||
{name: 'Emily', foo: 2, _id: emilyId}]);
|
||||
|
||||
// multi update by upsert
|
||||
var result7 = upsert(coll, useUpdate, {foo: 2},
|
||||
{$set: {bar: 7},
|
||||
$setOnInsert: {name: 'Fred', foo: 2}},
|
||||
{multi: true});
|
||||
test.equal(result7.numberAffected, 2);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result7.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{name: 'David', foo: 2, bar: 7, _id: davidId},
|
||||
{name: 'Emily', foo: 2, bar: 7, _id: emilyId}]);
|
||||
|
||||
// insert by multi upsert
|
||||
var result8 = upsert(coll, useUpdate, {foo: 3},
|
||||
{$set: {bar: 7},
|
||||
$setOnInsert: {name: 'Fred', foo: 2}},
|
||||
{multi: true});
|
||||
test.equal(result8.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isTrue(result8.insertedId);
|
||||
var fredId = result8.insertedId;
|
||||
compareResults(test, useUpdate, coll.find().fetch(),
|
||||
[{name: 'David', foo: 2, bar: 7, _id: davidId},
|
||||
{name: 'Emily', foo: 2, bar: 7, _id: emilyId},
|
||||
{name: 'Fred', foo: 2, bar: 7, _id: fredId}]);
|
||||
|
||||
// test `insertedId` option
|
||||
var result9 = upsert(coll, useUpdate, {name: 'Steve'},
|
||||
{name: 'Steve'},
|
||||
{insertedId: 'steve'});
|
||||
test.equal(result9.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.equal(result9.insertedId, 'steve');
|
||||
compareResults(test, useUpdate, coll.find().fetch(),
|
||||
[{name: 'David', foo: 2, bar: 7, _id: davidId},
|
||||
{name: 'Emily', foo: 2, bar: 7, _id: emilyId},
|
||||
{name: 'Fred', foo: 2, bar: 7, _id: fredId},
|
||||
{name: 'Steve', _id: 'steve'}]);
|
||||
test.isTrue(coll.findOne('steve'));
|
||||
test.isFalse(coll.findOne('fred'));
|
||||
|
||||
// Test $ operator in selectors.
|
||||
|
||||
var result10 = upsert(coll, useUpdate,
|
||||
{$or: [{name: 'David'}, {name: 'Emily'}]},
|
||||
{$set: {foo: 3}}, {multi: true});
|
||||
test.equal(result10.numberAffected, 2);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result10.insertedId);
|
||||
compareResults(test, useUpdate,
|
||||
[coll.findOne({name: 'David'}), coll.findOne({name: 'Emily'})],
|
||||
[{name: 'David', foo: 3, bar: 7, _id: davidId},
|
||||
{name: 'Emily', foo: 3, bar: 7, _id: emilyId}]
|
||||
);
|
||||
|
||||
var result11 = upsert(
|
||||
coll, useUpdate,
|
||||
{
|
||||
name: 'Charlie',
|
||||
$or: [{ foo: 2}, { bar: 7 }]
|
||||
},
|
||||
{ $set: { foo: 3 } }
|
||||
);
|
||||
test.equal(result11.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isTrue(result11.insertedId);
|
||||
var charlieId = result11.insertedId;
|
||||
compareResults(test, useUpdate,
|
||||
coll.find({ name: 'Charlie' }).fetch(),
|
||||
[{name: 'Charlie', foo: 3, _id: charlieId}]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var asyncUpsertTestName = function (useNetwork, useDirectCollection,
|
||||
useUpdate, idGeneration) {
|
||||
return "mongo-livedata - async " +
|
||||
(useUpdate ? "update " : "") +
|
||||
"upsert " +
|
||||
(useNetwork ? "over network " : "") +
|
||||
(useDirectCollection ? ", direct collection " : "") +
|
||||
idGeneration;
|
||||
};
|
||||
|
||||
// This is a duplicate of the test above, with some changes to make it work for
|
||||
// async upserts that go over the network.
|
||||
if (Meteor.isClient) {
|
||||
_.each([true, false], function (useUpdate) {
|
||||
Tinytest.addAsync("mongo-livedata - async " + (useUpdate ? "update " : "") + "upsert" + ", " + idGeneration, function (test, onComplete) {
|
||||
var coll;
|
||||
var run = test.runId();
|
||||
var collName = "livedata_upsert_collection_"+run;
|
||||
Meteor.call("createInsecureCollection", collName, collectionOptions);
|
||||
coll = new Meteor.Collection(collName, collectionOptions);
|
||||
Meteor.subscribe("c-" + collName);
|
||||
|
||||
var result1;
|
||||
var next1 = function (err, result) {
|
||||
result1 = result;
|
||||
test.equal(result1.numberAffected, 1);
|
||||
if (! useUpdate) {
|
||||
test.isTrue(result1.insertedId);
|
||||
test.equal(result1.insertedId, 'foo');
|
||||
// callback style. On the client, we test server-backed and in-memory
|
||||
// collections, and run the tests for both the Meteor.Collection and the
|
||||
// LocalCollection. On the server, we test mongo-backed collections, for both
|
||||
// the Meteor.Collection and the MongoConnection.
|
||||
_.each(Meteor.isServer ? [false] : [true, false], function (useNetwork) {
|
||||
_.each(useNetwork ? [false] : [true, false], function (useDirectCollection) {
|
||||
_.each([true, false], function (useUpdate) {
|
||||
Tinytest.addAsync(asyncUpsertTestName(useNetwork, useDirectCollection, useUpdate, idGeneration), function (test, onComplete) {
|
||||
var coll;
|
||||
var run = test.runId();
|
||||
var collName = "livedata_upsert_collection_"+run+
|
||||
(useUpdate ? "_update_" : "") +
|
||||
(useNetwork ? "_network_" : "") +
|
||||
(useDirectCollection ? "_direct_" : "");
|
||||
if (useNetwork) {
|
||||
Meteor.call("createInsecureCollection", collName, collectionOptions);
|
||||
coll = new Meteor.Collection(collName, collectionOptions);
|
||||
Meteor.subscribe("c-" + collName);
|
||||
} else {
|
||||
var opts = _.clone(collectionOptions);
|
||||
if (Meteor.isClient)
|
||||
opts.connection = null;
|
||||
coll = new Meteor.Collection(collName, opts);
|
||||
if (useDirectCollection)
|
||||
coll = coll._collection;
|
||||
}
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: 'bar', _id: 'foo'}]);
|
||||
upsert(coll, useUpdate, {_id: 'foo'}, {foo: 'baz'}, next2);
|
||||
};
|
||||
|
||||
// Test starts here.
|
||||
upsert(coll, useUpdate, {_id: 'foo'}, {_id: 'foo', foo: 'bar'}, next1);
|
||||
var result1;
|
||||
var next1 = function (err, result) {
|
||||
result1 = result;
|
||||
test.equal(result1.numberAffected, 1);
|
||||
if (! useUpdate) {
|
||||
test.isTrue(result1.insertedId);
|
||||
test.equal(result1.insertedId, 'foo');
|
||||
}
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: 'bar', _id: 'foo'}]);
|
||||
upsert(coll, useUpdate, {_id: 'foo'}, {foo: 'baz'}, next2);
|
||||
};
|
||||
|
||||
var t1, t2, result2;
|
||||
var next2 = function (err, result) {
|
||||
result2 = result;
|
||||
test.equal(result2.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result2.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: 'baz', _id: result1.insertedId}]);
|
||||
coll.remove({_id: 'foo'});
|
||||
compareResults(test, useUpdate, coll.find().fetch(), []);
|
||||
// Test starts here.
|
||||
upsert(coll, useUpdate, {_id: 'foo'}, {_id: 'foo', foo: 'bar'}, next1);
|
||||
|
||||
// Test values that require transformation to go into Mongo:
|
||||
var t1, t2, result2;
|
||||
var next2 = function (err, result) {
|
||||
result2 = result;
|
||||
test.equal(result2.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result2.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: 'baz', _id: result1.insertedId}]);
|
||||
coll.remove({_id: 'foo'});
|
||||
compareResults(test, useUpdate, coll.find().fetch(), []);
|
||||
|
||||
t1 = new Meteor.Collection.ObjectID();
|
||||
t2 = new Meteor.Collection.ObjectID();
|
||||
upsert(coll, useUpdate, {_id: t1}, {_id: t1, foo: 'bar'}, next3);
|
||||
};
|
||||
// Test values that require transformation to go into Mongo:
|
||||
|
||||
var result3;
|
||||
var next3 = function (err, result) {
|
||||
result3 = result;
|
||||
test.equal(result3.numberAffected, 1);
|
||||
if (! useUpdate) {
|
||||
test.isTrue(result3.insertedId);
|
||||
test.equal(t1, result3.insertedId);
|
||||
}
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{_id: t1, foo: 'bar'}]);
|
||||
t1 = new Meteor.Collection.ObjectID();
|
||||
t2 = new Meteor.Collection.ObjectID();
|
||||
upsert(coll, useUpdate, {_id: t1}, {_id: t1, foo: 'bar'}, next3);
|
||||
};
|
||||
|
||||
upsert(coll, useUpdate, {_id: t1}, {foo: t2}, next4);
|
||||
};
|
||||
var result3;
|
||||
var next3 = function (err, result) {
|
||||
result3 = result;
|
||||
test.equal(result3.numberAffected, 1);
|
||||
if (! useUpdate) {
|
||||
test.isTrue(result3.insertedId);
|
||||
test.equal(t1, result3.insertedId);
|
||||
}
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{_id: t1, foo: 'bar'}]);
|
||||
|
||||
var next4 = function (err, result4) {
|
||||
test.equal(result2.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result2.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: t2, _id: result3.insertedId}]);
|
||||
upsert(coll, useUpdate, {_id: t1}, {foo: t2}, next4);
|
||||
};
|
||||
|
||||
coll.remove({_id: t1});
|
||||
var next4 = function (err, result4) {
|
||||
test.equal(result2.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result2.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: t2, _id: result3.insertedId}]);
|
||||
|
||||
// Test modification by upsert
|
||||
upsert(coll, useUpdate, {_id: 'David'}, {$set: {foo: 1}}, next5);
|
||||
};
|
||||
coll.remove({_id: t1});
|
||||
|
||||
var result5;
|
||||
var next5 = function (err, result) {
|
||||
result5 = result;
|
||||
test.equal(result5.numberAffected, 1);
|
||||
if (! useUpdate) {
|
||||
test.isTrue(result5.insertedId);
|
||||
test.equal(result5.insertedId, 'David');
|
||||
}
|
||||
var davidId = result5.insertedId;
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: 1, _id: davidId}]);
|
||||
// Test modification by upsert
|
||||
upsert(coll, useUpdate, {_id: 'David'}, {$set: {foo: 1}}, next5);
|
||||
};
|
||||
|
||||
// test that bad modifier fails
|
||||
// The stub throws an exception about the invalid modifier, which
|
||||
// livedata logs (so we suppress it).
|
||||
Meteor._suppress_log(1);
|
||||
upsert(coll, useUpdate, {_id: 'David'}, {$blah: {foo: 2}}, function (err) {
|
||||
test.isTrue(err);
|
||||
upsert(coll, useUpdate, {_id: 'David'}, {$set: {foo: 2}}, next6);
|
||||
});
|
||||
};
|
||||
var result5;
|
||||
var next5 = function (err, result) {
|
||||
result5 = result;
|
||||
test.equal(result5.numberAffected, 1);
|
||||
if (! useUpdate) {
|
||||
test.isTrue(result5.insertedId);
|
||||
test.equal(result5.insertedId, 'David');
|
||||
}
|
||||
var davidId = result5.insertedId;
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{foo: 1, _id: davidId}]);
|
||||
|
||||
var result6;
|
||||
var next6 = function (err, result) {
|
||||
result6 = result;
|
||||
test.equal(result6.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result6.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{_id: 'David', foo: 2}]);
|
||||
if (! Meteor.isClient && useDirectCollection) {
|
||||
// test that bad modifier fails
|
||||
// The stub throws an exception about the invalid modifier, which
|
||||
// livedata logs (so we suppress it).
|
||||
Meteor._suppress_log(1);
|
||||
upsert(coll, useUpdate, {_id: 'David'}, {$blah: {foo: 2}}, function (err) {
|
||||
if (! (Meteor.isClient && useDirectCollection))
|
||||
test.isTrue(err);
|
||||
upsert(coll, useUpdate, {_id: 'David'}, {$set: {foo: 2}}, next6);
|
||||
});
|
||||
} else {
|
||||
// XXX skip this test for now for LocalCollection; the fact that
|
||||
// we're in a nested sequence of callbacks means we're inside a
|
||||
// Meteor.defer, which means the exception just gets
|
||||
// logged. Something should be done about this at some point? Maybe
|
||||
// LocalCollection callbacks don't really have to be deferred.
|
||||
upsert(coll, useUpdate, {_id: 'David'}, {$set: {foo: 2}}, next6);
|
||||
}
|
||||
};
|
||||
|
||||
var emilyId = coll.insert({_id: 'Emily', foo: 2});
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{_id: 'David', foo: 2},
|
||||
{_id: 'Emily', foo: 2}]);
|
||||
var result6;
|
||||
var next6 = function (err, result) {
|
||||
result6 = result;
|
||||
test.equal(result6.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result6.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{_id: 'David', foo: 2}]);
|
||||
|
||||
// multi update by upsert.
|
||||
// We can't actually update multiple documents since we have to do it by
|
||||
// id, but at least make sure the multi flag doesn't mess anything up.
|
||||
upsert(coll, useUpdate, {_id: 'Emily'},
|
||||
{$set: {bar: 7},
|
||||
$setOnInsert: {name: 'Fred', foo: 2}},
|
||||
{multi: true}, next7);
|
||||
};
|
||||
var emilyId = coll.insert({_id: 'Emily', foo: 2});
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{_id: 'David', foo: 2},
|
||||
{_id: 'Emily', foo: 2}]);
|
||||
|
||||
var result7;
|
||||
var next7 = function (err, result) {
|
||||
result7 = result;
|
||||
test.equal(result7.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result7.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{_id: 'David', foo: 2},
|
||||
{_id: 'Emily', foo: 2, bar: 7}]);
|
||||
// multi update by upsert.
|
||||
// We can't actually update multiple documents since we have to do it by
|
||||
// id, but at least make sure the multi flag doesn't mess anything up.
|
||||
upsert(coll, useUpdate, {_id: 'Emily'},
|
||||
{$set: {bar: 7},
|
||||
$setOnInsert: {name: 'Fred', foo: 2}},
|
||||
{multi: true}, next7);
|
||||
};
|
||||
|
||||
// insert by multi upsert
|
||||
upsert(coll, useUpdate, {_id: 'Fred'},
|
||||
{$set: {bar: 7},
|
||||
$setOnInsert: {name: 'Fred', foo: 2}},
|
||||
{multi: true}, next8);
|
||||
var result7;
|
||||
var next7 = function (err, result) {
|
||||
result7 = result;
|
||||
test.equal(result7.numberAffected, 1);
|
||||
if (! useUpdate)
|
||||
test.isFalse(result7.insertedId);
|
||||
compareResults(test, useUpdate, coll.find().fetch(), [{_id: 'David', foo: 2},
|
||||
{_id: 'Emily', foo: 2, bar: 7}]);
|
||||
|
||||
};
|
||||
// insert by multi upsert
|
||||
upsert(coll, useUpdate, {_id: 'Fred'},
|
||||
{$set: {bar: 7},
|
||||
$setOnInsert: {name: 'Fred', foo: 2}},
|
||||
{multi: true}, next8);
|
||||
|
||||
var result8;
|
||||
var next8 = function (err, result) {
|
||||
result8 = result;
|
||||
};
|
||||
|
||||
test.equal(result8.numberAffected, 1);
|
||||
if (! useUpdate) {
|
||||
test.isTrue(result8.insertedId);
|
||||
test.equal(result8.insertedId, 'Fred');
|
||||
}
|
||||
var fredId = result8.insertedId;
|
||||
compareResults(test, useUpdate, coll.find().fetch(),
|
||||
[{_id: 'David', foo: 2},
|
||||
{_id: 'Emily', foo: 2, bar: 7},
|
||||
{name: 'Fred', foo: 2, bar: 7, _id: fredId}]);
|
||||
onComplete();
|
||||
};
|
||||
var result8;
|
||||
var next8 = function (err, result) {
|
||||
result8 = result;
|
||||
|
||||
test.equal(result8.numberAffected, 1);
|
||||
if (! useUpdate) {
|
||||
test.isTrue(result8.insertedId);
|
||||
test.equal(result8.insertedId, 'Fred');
|
||||
}
|
||||
var fredId = result8.insertedId;
|
||||
compareResults(test, useUpdate, coll.find().fetch(),
|
||||
[{_id: 'David', foo: 2},
|
||||
{_id: 'Emily', foo: 2, bar: 7},
|
||||
{name: 'Fred', foo: 2, bar: 7, _id: fredId}]);
|
||||
onComplete();
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if (Meteor.isClient) {
|
||||
Tinytest.addAsync("mongo-livedata - async update/remove return values over network " + idGeneration, function (test, onComplete) {
|
||||
var coll;
|
||||
var run = test.runId();
|
||||
@@ -1372,8 +1424,7 @@ if (Meteor.isClient) {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
} // end isClient
|
||||
}
|
||||
|
||||
// Runs a method and its stub which do some upserts. The method throws an error
|
||||
// if we don't get the right return values.
|
||||
|
||||
Reference in New Issue
Block a user