diff --git a/README.md b/README.md index 681a74b699..8f1f51f62d 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.28.0') +implementation platform('com.google.cloud:libraries-bom:26.29.0') implementation 'com.google.cloud:google-cloud-firestore' ``` diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UpdateBuilder.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UpdateBuilder.java index d7f98808a1..87cf833079 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UpdateBuilder.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UpdateBuilder.java @@ -161,7 +161,10 @@ private T performCreate( private void verifyNotCommitted() { Preconditions.checkState( - !isCommitted(), "Cannot modify a WriteBatch that has already been committed."); + !isCommitted(), + String.format( + "Cannot modify a %s that has already been committed.", + this.getClass().getSimpleName())); } /** diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/LocalFirestoreHelper.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/LocalFirestoreHelper.java index b86cc0bc95..9ee7f6ff59 100644 --- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/LocalFirestoreHelper.java +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/LocalFirestoreHelper.java @@ -1242,4 +1242,20 @@ public static List bundleToElementList(ByteBuffer bundle) { return result; } + + @FunctionalInterface + interface VoidFunction { + void apply(); + } + + static void assertException(VoidFunction voidFunction, String expectedErrorMessage) { + String errorMessage = ""; + try { + voidFunction.apply(); + } catch (Exception e) { + errorMessage = e.getMessage(); + } finally { + assertEquals(errorMessage, expectedErrorMessage); + } + } } diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TransactionTest.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TransactionTest.java index eeef59e0c8..df9c72cedb 100644 --- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TransactionTest.java +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TransactionTest.java @@ -36,6 +36,7 @@ import static com.google.cloud.firestore.LocalFirestoreHelper.rollbackResponse; import static com.google.cloud.firestore.LocalFirestoreHelper.set; import static com.google.cloud.firestore.LocalFirestoreHelper.update; +import static com.google.cloud.firestore.it.ITQueryTest.map; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -959,6 +960,43 @@ public void getShouldThrowWhenInvokedAfterAWriteWithAnAggregateQuery() throws Ex assertThat(executionException.getCause()).isInstanceOf(IllegalStateException.class); } + @Test + public void givesProperErrorMessageForCommittedTransaction() throws Exception { + doReturn(beginResponse()) + .doReturn(commitResponse(0, 0)) + .when(firestoreMock) + .sendRequest( + requestCapture.capture(), ArgumentMatchers.>any()); + String expectedErrorMessage = "Cannot modify a Transaction that has already been committed."; + + DocumentReference docRef = firestoreMock.collection("foo").document("bar"); + + // Commit a transaction. + Transaction t = firestoreMock.runTransaction(transaction -> transaction).get(); + + // Then run other operations in the same transaction. + LocalFirestoreHelper.assertException( + () -> { + t.set(docRef, map("foo", "bar")); + }, + expectedErrorMessage); + LocalFirestoreHelper.assertException( + () -> { + t.update(docRef, map("foo", "bar")); + }, + expectedErrorMessage); + LocalFirestoreHelper.assertException( + () -> { + t.create(docRef, map("foo", "bar")); + }, + expectedErrorMessage); + LocalFirestoreHelper.assertException( + () -> { + t.delete(docRef); + }, + expectedErrorMessage); + } + private ApiException exception(Status.Code code, boolean shouldRetry) { return exception(code, "Test exception", shouldRetry); } diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WriteBatchTest.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WriteBatchTest.java index 92ca905c79..1fec528406 100644 --- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WriteBatchTest.java +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WriteBatchTest.java @@ -341,4 +341,43 @@ public void deleteDocument() throws Exception { CommitRequest commitRequest = commitCapture.getValue(); assertEquals(commit(writes.toArray(new Write[] {})), commitRequest); } + + @Test + public void throwsWhenModifyingACommittedWriteBatch() throws Exception { + doReturn(commitResponse(0, 0)) + .when(firestoreMock) + .sendRequest( + commitCapture.capture(), + ArgumentMatchers.>any()); + + String expectedErrorMessage = "Cannot modify a WriteBatch that has already been committed."; + + DocumentReference docRef = firestoreMock.collection("foo").document("bar"); + + // Commit a batch. + WriteBatch batch = firestoreMock.batch(); + batch.commit().get(); + + // Then run other operations in the same batch. + LocalFirestoreHelper.assertException( + () -> { + batch.set(docRef, map("foo", "bar")); + }, + expectedErrorMessage); + LocalFirestoreHelper.assertException( + () -> { + batch.update(docRef, map("foo", "bar")); + }, + expectedErrorMessage); + LocalFirestoreHelper.assertException( + () -> { + batch.create(docRef, map("foo", "bar")); + }, + expectedErrorMessage); + LocalFirestoreHelper.assertException( + () -> { + batch.delete(docRef); + }, + expectedErrorMessage); + } }