/*
* Copyright (c) 2008-2015 MongoDB, Inc.
*
* 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 com.mongodb.acceptancetest.atomicoperations;
import com.mongodb.client.DatabaseTestCase;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import com.mongodb.client.test.Worker;
import com.mongodb.client.test.WorkerCodecProvider;
import org.bson.Document;
import org.bson.codecs.BsonValueCodecProvider;
import org.bson.codecs.DocumentCodecProvider;
import org.bson.codecs.ValueCodecProvider;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.types.ObjectId;
import org.junit.Test;
import java.util.Date;
import static java.util.Arrays.asList;
import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
public class FindAndUpdateAcceptanceTest extends DatabaseTestCase {
private static final String KEY = "searchKey";
private static final String VALUE_TO_CARE_ABOUT = "Value to match";
@Test
public void shouldUpdateDocumentAndReturnOriginal() {
Document documentInserted = new Document(KEY, VALUE_TO_CARE_ABOUT).append("someNumber", 11);
collection.insertOne(documentInserted);
assertThat(collection.count(), is(1L));
Document updateOperation = new Document("$inc", new Document("someNumber", 1));
Document documentBeforeChange = collection.findOneAndUpdate(new Document(KEY, VALUE_TO_CARE_ABOUT), updateOperation);
assertThat("Document returned from getOneAndUpdate should be the original document",
(Integer) documentBeforeChange.get("someNumber"), equalTo(11));
}
@Test
public void shouldUpdateDocumentAndReturnNew() {
Document documentInserted = new Document(KEY, VALUE_TO_CARE_ABOUT).append("someNumber", 11);
collection.insertOne(documentInserted);
assertThat(collection.count(), is(1L));
Document updateOperation = new Document("$inc", new Document("someNumber", 1));
Document updatedDocument = collection.findOneAndUpdate(new Document(KEY, VALUE_TO_CARE_ABOUT), updateOperation,
new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER));
assertThat("Document returned from updateOneAndGet should be the updated document",
(Integer) updatedDocument.get("someNumber"), equalTo(12));
}
@Test
public void shouldFindAndReplaceWithDocumentRequiringACustomEncoder() {
Worker pat = new Worker(new ObjectId(), "Pat", "Sales", new Date(), 7);
CodecRegistry codecRegistry = fromProviders(asList(new ValueCodecProvider(), new DocumentCodecProvider(),
new BsonValueCodecProvider(), new WorkerCodecProvider()));
MongoCollection<Worker> collection = database
.getCollection(getCollectionName(), Worker.class)
.withCodecRegistry(codecRegistry);
collection.insertOne(pat);
assertThat(collection.count(), is(1L));
Document updateOperation = new Document("$inc", new Document("numberOfJobs", 1));
Worker updatedDocument = collection.findOneAndUpdate(new Document("name", "Pat"), updateOperation,
new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER));
assertThat("Worker returned from updateOneAndGet should have the",
updatedDocument.getNumberOfJobs(), equalTo(8));
}
@Test
public void shouldReturnNullWhenNothingToUpdate() {
Document documentInserted = new Document(KEY, VALUE_TO_CARE_ABOUT).append("someNumber", 11);
collection.insertOne(documentInserted);
assertThat(collection.count(), is(1L));
Document updateOperation = new Document("$inc", new Document("someNumber", 1));
Document document = collection.findOneAndUpdate(new Document(KEY, "someValueThatDoesNotExist"), updateOperation);
assertNull("Document retrieved from getOneAndUpdate should be null", document);
}
@Test
public void shouldInsertDocumentWhenFilterDoesNotMatchAnyDocumentsAndUpsertSelected() {
Document originalDocument = new Document(KEY, VALUE_TO_CARE_ABOUT).append("someNumber", 11);
collection.insertOne(originalDocument);
assertThat(collection.count(), is(1L));
String newValueThatDoesNotMatchAnythingInDatabase = "valueThatDoesNotMatch";
Document updateOperation = new Document("$inc", new Document("someNumber", 1));
Document document = collection.findOneAndUpdate(new Document(KEY, newValueThatDoesNotMatchAnythingInDatabase), updateOperation,
new FindOneAndUpdateOptions().upsert(true).returnDocument(ReturnDocument.AFTER));
assertThat(collection.count(), is(2L));
assertThat("Document retrieved from updateOneAndGet and upsert true should have the new values",
(Integer) document.get("someNumber"), equalTo(1));
assertThat("Document retrieved from updateOneAndGet and upsert true should have the new values",
document.get(KEY).toString(), equalTo(newValueThatDoesNotMatchAnythingInDatabase));
}
}