diff --git a/src/main/java/com/github/fakemongo/impl/UpdateEngine.java b/src/main/java/com/github/fakemongo/impl/UpdateEngine.java index d9f4e66b..a5b0ce42 100644 --- a/src/main/java/com/github/fakemongo/impl/UpdateEngine.java +++ b/src/main/java/com/github/fakemongo/impl/UpdateEngine.java @@ -136,7 +136,11 @@ public void handlePositionalUpdate(final String updateKey, Object object, List v } else { //this is kind of a waste DBObject o = ExpressionParser.isDbObject(listItem) ? ExpressionParser.toDbObject(listItem) : new BasicDBObject(prePath, listItem); - if (filter.apply(o)) { + BasicDBList listWithSingleItem = new BasicDBList(); + listWithSingleItem.add(listItem); + if (filter.apply(o) || + //Case of a nested $elemMatch + filter.apply(new BasicDBObject(prePath, listWithSingleItem))) { BasicDBList newList = new BasicDBList(); newList.addAll(valueList); //do not put any data on ownerObj, because the prePath can be composed of different parts diff --git a/src/test/java/com/github/fakemongo/impl/UpdateEngineTest.java b/src/test/java/com/github/fakemongo/impl/UpdateEngineTest.java index 747e73fd..90e68f73 100644 --- a/src/test/java/com/github/fakemongo/impl/UpdateEngineTest.java +++ b/src/test/java/com/github/fakemongo/impl/UpdateEngineTest.java @@ -413,10 +413,10 @@ public void testPositionalOperator() { } @Test - public void testPositionalOperatorWithElemMatch() { + public void testPositionalOperatorWithElemMatchWithPostPath() { String random1 = UUID.randomUUID().toString(); String random2 = UUID.randomUUID().toString(); - + DBObject object = (DBObject) FongoJSON.parse("{ \"name\" : \"Tenant 1\", \"appAllocations\" : [ { \"appId\" : \"" + random1 + "\" , \"maxUser\" : 4} , { \"appId\"" + ": \"" + random2 + "\" , \"maxUser\" : 42}]}"); @@ -431,12 +431,32 @@ public void testPositionalOperatorWithElemMatch() { assertEquals(expected.toString(), updateEngine.doUpdate(object, update, query, false).toString()); } - + + @Test + public void testPositionalOperatorWithElemMatchWithoutPostPath() { + String random1 = UUID.randomUUID().toString(); + String random2 = UUID.randomUUID().toString(); + + DBObject object = (DBObject) FongoJSON.parse("{ \"name\" : \"Tenant 1\", \"appAllocations\" : [ { \"appId\" : \"" + + random1 + "\" , \"maxUser\" : 4} , { \"appId\"" + + ": \"" + random2 + "\" , \"maxUser\" : 42}]}"); + DBObject query = (DBObject) FongoJSON.parse("{ \"appAllocations\" : { \"$elemMatch\" : { \"appId\" : \"" + random1 + "\"}}}"); + DBObject update = (DBObject) FongoJSON.parse("{ \"$set\" : { \"appAllocations.$\" : { \"appId\" : \"" + random1 + "\", \"maxUser\" : 9 }}}"); + + DBObject expected = (DBObject) FongoJSON.parse("{ \"name\" : \"Tenant 1\", \"appAllocations\" : [ { \"appId\" : \"" + + random1 + "\" , \"maxUser\" : 9} , { \"appId\"" + + ": \"" + random2 + "\" , \"maxUser\" : 42}]}"); + UpdateEngine updateEngine = new UpdateEngine(); + + assertEquals(expected.toString(), + updateEngine.doUpdate(object, update, query, false).toString()); + } + @Test public void testAddOrReplaceElementMustWorkWithDollarOperator() { String random1 = UUID.randomUUID().toString(); String random2 = UUID.randomUUID().toString(); - + DBObject object = (DBObject) FongoJSON.parse("{ \"_id\" : \"1234\" , \"var1\" : \"val1\" , \"parentObject\" : { \"var2\" : \"val21\" , \"subObject\" : [ { \"_id\" : \"" + random1 + "\" , \"var3\" : \"val31\"}, { \"_id\" : \"" + random2 + "\" , \"var3\" : \"val32\"}]}}"); DBObject update = (DBObject) FongoJSON.parse("{ \"$set\" : { \"parentObject.subObject.$\" : { \"_id\" : \"" + random1 + "\" , \"var3\" : \"val33\"}}}"); DBObject query = (DBObject) FongoJSON.parse("{ \"_id\" : \"1234\" , \"parentObject.subObject._id\" : \"" + random1 + "\"}");