/*
* Copyright 2011 VZ Netzwerke Ltd
* Copyright 2014 devbliss GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mongojack;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
import static org.mongojack.TestDBUpdateSerialization.NestedIdFieldWithDifferentType.NESTED_ID_FIELD_VALUE;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
public class TestDBUpdateSerialization extends MongoDBTestBase {
private JacksonDBCollection<MockObject, String> coll;
private JacksonDBCollection<NestedRepeatedAttributeName, String> coll2;
@Before
public void setUp() {
coll = getCollection(MockObject.class, String.class);
}
@Test
public void testSimpleCustomSerializer() {
coll.save(new MockObject());
coll.updateById("id", DBUpdate.set("simple", "foo"));
assertThat(coll.findOneById("id").simple, equalTo("bar"));
}
@Test
public void testSimpleCustomSerializerNotApplied() {
MockObject o = new MockObject();
o.simple = "blah";
coll.save(o);
coll.updateById("id", DBUpdate.unset("simple"));
assertThat(coll.findOneById("id").simple, nullValue());
}
@Test
@Ignore("Ignored until JACKSON-829 is fixed")
public void testListSetCustomSerializer() {
coll.save(new MockObject());
coll.updateById("id",
DBUpdate.set("list", Arrays.asList("some", "foo")));
assertThat(coll.findOneById("id").list,
equalTo(Arrays.asList("some", "bar")));
}
@Test
@Ignore("Ignored until JACKSON-829 is fixed")
public void testListSingleValueCustomSerializer() {
coll.save(new MockObject());
coll.updateById("id", DBUpdate.push("list", "foo"));
assertThat(coll.findOneById("id").list, equalTo(Arrays.asList("bar")));
}
@Test
@Ignore("Ignored until JACKSON-829 is fixed")
public void testListMultiValueCustomSerializer() {
coll.save(new MockObject());
coll.updateById("id", DBUpdate.pushAll("list", "some", "foo"));
assertThat(coll.findOneById("id").list,
equalTo(Arrays.asList("some", "bar")));
}
@Test
public void testNestedValueCustomSerializer() {
MockObject o = new MockObject();
o.child = new MockObject();
coll.save(o);
coll.updateById("id", DBUpdate.set("child.simple", "foo"));
assertThat(coll.findOneById("id").child.simple, equalTo("bar"));
}
@Test
public void testDollarsCustomSerializer() {
MockObject o = new MockObject();
MockObject c1 = new MockObject();
c1.simple = "one";
MockObject c2 = new MockObject();
c2.simple = "two";
o.childList = Arrays.asList(c1, c2);
coll.save(o);
coll.update(DBQuery.is("childList.simple", "one"),
DBUpdate.set("childList.$.simple", "foo"));
assertThat(coll.findOneById("id").childList.get(0).simple,
equalTo("bar"));
assertThat(coll.findOneById("id").childList.get(1).simple,
equalTo("two"));
}
@Test
@Ignore("Ignored until JACKSON-829 is fixed")
public void testMapValueCustomSerializer() {
MockObject o = new MockObject();
o.customMap = new HashMap<String, String>();
o.customMap.put("blah", "blah");
coll.save(o);
coll.updateById("id", DBUpdate.set("customMap.blah", "foo"));
assertThat(coll.findOneById("id").customMap.get("blah"), equalTo("bar"));
}
@Test
public void testSimpleObjectId() {
MockObject o = new MockObject();
coll.save(o);
String objectId = new org.bson.types.ObjectId().toString();
coll.updateById("id", DBUpdate.set("objectId", objectId));
assertThat(coll.findOneById("id").objectId, equalTo(objectId));
}
@Test
public void testObjectIdCollection() {
MockObject o = new MockObject();
coll.save(o);
String objectId = new org.bson.types.ObjectId().toString();
coll.updateById("id", DBUpdate.push("objectIds", objectId));
assertThat(coll.findOneById("id").objectIds.get(0), equalTo(objectId));
}
@Test
public void testSimpleMap() {
MockObject o = new MockObject();
coll.save(o);
Map<String, String> map = new HashMap<String, String>();
map.put("foo", "bar");
coll.updateById("id", DBUpdate.set("map", map));
assertThat(coll.findOneById("id").map, equalTo(map));
}
// Test to detect presence of issue https://github.com/mongojack/mongojack/issues/98
@Test
public void testUpdateOfNestedRepeatedAttributeName() {
coll2 = getCollection(NestedRepeatedAttributeName.class, String.class);
Date d1 = new Date(10000L);
Date d2 = new Date(20000L);
NestedRepeatedAttributeName original = new NestedRepeatedAttributeName();
original.inner.timestamp = d1;
original.timestamp = 30000;
coll2.insert(original);
coll2.updateById(original._id, DBUpdate.set("inner.timestamp", d2));
NestedRepeatedAttributeName updated = coll2.findOneById(original._id);
assertThat(updated, notNullValue());
assertThat(updated.inner.timestamp, equalTo(d2));
assertThat(updated.timestamp, equalTo(original.timestamp));
}
// Test to detect presence of issue https://github.com/mongojack/mongojack/issues/127
@Test
public void testUpdateOfNestedIdFieldWithDifferentType() {
JacksonDBCollection<NestedIdFieldWithDifferentType, String> collection = getCollection(NestedIdFieldWithDifferentType.class, String.class);
NestedIdFieldWithDifferentType original = new NestedIdFieldWithDifferentType();
collection.insert(original);
String newValue = "new value";
collection.update(DBQuery.is("nested._id", NESTED_ID_FIELD_VALUE), DBUpdate.set("value", newValue));
NestedIdFieldWithDifferentType updated = collection.findOneById(original._id);
assertThat(updated, notNullValue());
assertThat(updated.value, equalTo(newValue));
}
public static class MockObject {
public String _id = "id";
@JsonSerialize(using = FooToBarSerializer.class)
public String simple;
@JsonSerialize(contentUsing = FooToBarSerializer.class)
public List<String> list;
public MockObject child;
public List<MockObject> childList;
public Map<String, String> map;
@JsonSerialize(contentUsing = FooToBarSerializer.class)
public Map<String, String> customMap;
@ObjectId
public String objectId;
@ObjectId
public List<String> objectIds;
}
public static class FooToBarSerializer extends JsonSerializer<String> {
@Override
public void serialize(String value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
if ("foo".equals(value)) {
jgen.writeString("bar");
} else {
jgen.writeString(value);
}
}
}
public static class NestedRepeatedAttributeName {
public static class Inner {
public Date timestamp;
}
public String _id = "id";
public Inner inner = new Inner();
public long timestamp;
}
public static class NestedIdFieldWithDifferentType {
public static final String DEFAULT_VALUE = "default-value";
public static final Date NESTED_ID_FIELD_VALUE = new Date();
public static class Nested {
public Date _id = NESTED_ID_FIELD_VALUE;
}
public String _id = "id";
public Nested nested = new Nested();
public String value = DEFAULT_VALUE;
}
}