Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.

Commit bf7f4a3

Browse files
authored
fix(java): fix error message returned for invalid snapshot listener inequality filter (#1093)
1 parent 32ba8ac commit bf7f4a3

4 files changed

Lines changed: 123 additions & 6 deletions

File tree

google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryCountTest.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.cloud.firestore.it;
1818

1919
import static com.google.cloud.firestore.LocalFirestoreHelper.autoId;
20+
import static com.google.cloud.firestore.it.TestHelper.isRunningAgainstFirestoreEmulator;
2021
import static com.google.common.truth.Truth.assertThat;
2122
import static java.util.Collections.singletonMap;
2223
import static org.junit.Assert.assertThrows;
@@ -247,7 +248,7 @@ public void aggregateQueryInATransactionShouldLockTheCountedDocuments() throws E
247248
assumeTrue(
248249
"Skip this test when running against production because "
249250
+ "it appears that production is failing to lock the counted documents b/248152832",
250-
isRunningAgainstFirestoreEmulator());
251+
isRunningAgainstFirestoreEmulator(firestore));
251252

252253
CollectionReference collection = createEmptyCollection();
253254
DocumentReference document = createDocumentInCollection(collection);
@@ -418,11 +419,6 @@ private static void await(ApiFuture<?> future) throws InterruptedException {
418419
executor.shutdown();
419420
}
420421

421-
/** Returns whether the tests are running against the Firestore emulator. */
422-
private boolean isRunningAgainstFirestoreEmulator() {
423-
return firestore.getOptions().getHost().startsWith("localhost:");
424-
}
425-
426422
@AutoValue
427423
abstract static class CreatedCollectionInfo {
428424

google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
package com.google.cloud.firestore.it;
1818

1919
import static com.google.cloud.firestore.LocalFirestoreHelper.map;
20+
import static com.google.cloud.firestore.it.TestHelper.isRunningAgainstFirestoreEmulator;
2021
import static com.google.common.collect.ImmutableList.toImmutableList;
2122
import static com.google.common.truth.Truth.assertThat;
2223
import static com.google.common.truth.Truth.assertWithMessage;
2324
import static java.util.Arrays.asList;
2425
import static java.util.Collections.emptyList;
2526
import static java.util.Collections.singletonList;
27+
import static org.junit.Assume.assumeFalse;
2628

2729
import com.google.cloud.firestore.CollectionReference;
2830
import com.google.cloud.firestore.DocumentChange;
@@ -152,6 +154,63 @@ public void nonEmptyResults() throws Exception {
152154
listenerAssertions.removedIdsIsAnyOf(emptyList());
153155
}
154156

157+
/**
158+
* Testing multiple inequality filters on same and different properties, and validate the error
159+
* message returned for invalid filter.
160+
*/
161+
@Test
162+
public void inequalityFilterOnSamePropertiesShouldBeSupported() throws Exception {
163+
setDocument("doc", map("foo", 1, "bar", 2));
164+
165+
final Query query = randomColl.whereGreaterThan("foo", 0).whereLessThanOrEqualTo("foo", 2);
166+
QuerySnapshotEventListener listener =
167+
QuerySnapshotEventListener.builder().setInitialEventCount(1).build();
168+
ListenerRegistration registration = query.addSnapshotListener(listener);
169+
170+
try {
171+
listener.eventsCountDownLatch.awaitInitialEvents();
172+
} finally {
173+
registration.remove();
174+
}
175+
ListenerAssertions listenerAssertions = listener.assertions();
176+
listenerAssertions.noError();
177+
listenerAssertions.eventCountIsAnyOf(Range.closed(1, 1));
178+
listenerAssertions.addedIdsIsAnyOf(singletonList("doc"));
179+
listenerAssertions.modifiedIdsIsAnyOf(emptyList());
180+
listenerAssertions.removedIdsIsAnyOf(emptyList());
181+
}
182+
183+
/** Based on https://github.com/googleapis/java-firestore/issues/1085 */
184+
@Test
185+
public void inequalityFilterOnDifferentPropertiesShouldThrow() throws Exception {
186+
assumeFalse(
187+
"Skip this test when running against emulator because the fix is only applied in the "
188+
+ "production",
189+
isRunningAgainstFirestoreEmulator(firestore));
190+
191+
setDocument("doc1", map("foo", "1", "bar", 1));
192+
193+
final Query query = randomColl.whereGreaterThan("foo", "0").whereLessThan("bar", 2);
194+
QuerySnapshotEventListener listener =
195+
QuerySnapshotEventListener.builder().setExpectError().build();
196+
ListenerRegistration registration = query.addSnapshotListener(listener);
197+
198+
try {
199+
listener.eventsCountDownLatch.awaitError();
200+
} finally {
201+
registration.remove();
202+
}
203+
204+
ListenerAssertions listenerAssertions = listener.assertions();
205+
listenerAssertions.hasError();
206+
FirestoreException error = listener.receivedEvents.get(0).error;
207+
assertThat(error)
208+
.hasMessageThat()
209+
.ignoringCase()
210+
.contains(
211+
"Backend ended Listen stream: Cannot have inequality filters on multiple properties: [foo, bar]");
212+
}
213+
155214
/**
156215
*
157216
*

google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import static com.google.cloud.firestore.LocalFirestoreHelper.UPDATE_SINGLE_FIELD_OBJECT;
2626
import static com.google.cloud.firestore.LocalFirestoreHelper.fullPath;
2727
import static com.google.cloud.firestore.LocalFirestoreHelper.map;
28+
import static com.google.cloud.firestore.it.TestHelper.isRunningAgainstFirestoreEmulator;
2829
import static com.google.common.truth.Truth.assertThat;
2930
import static java.util.Arrays.asList;
3031
import static org.junit.Assert.assertArrayEquals;
@@ -36,6 +37,7 @@
3637
import static org.junit.Assert.assertThrows;
3738
import static org.junit.Assert.assertTrue;
3839
import static org.junit.Assert.fail;
40+
import static org.junit.Assume.assumeFalse;
3941

4042
import com.google.api.core.ApiFuture;
4143
import com.google.api.core.ApiFutures;
@@ -488,6 +490,37 @@ public void greaterThanQuery() throws Exception {
488490
assertEquals(2L, querySnapshot.getDocuments().get(0).get("foo"));
489491
}
490492

493+
@Test
494+
public void multipleInequalityQueryOnSamePropertiesShouldBeSupported() throws Exception {
495+
addDocument("foo", 1);
496+
497+
QuerySnapshot querySnapshot =
498+
randomColl.whereGreaterThan("foo", 0).whereLessThanOrEqualTo("foo", 2).get().get();
499+
assertEquals(1, querySnapshot.size());
500+
assertEquals(1L, querySnapshot.getDocuments().get(0).get("foo"));
501+
}
502+
503+
/** Based on https://github.com/googleapis/java-firestore/issues/1085 */
504+
@Test
505+
public void multipleInequalityQueryOnDifferentPropertiesShouldThrow() throws Exception {
506+
assumeFalse(
507+
"Skip this test when running against emulator because the fix is only applied in the "
508+
+ "production",
509+
isRunningAgainstFirestoreEmulator(firestore));
510+
511+
addDocument("foo", 1, "bar", 2);
512+
513+
ExecutionException executionException =
514+
assertThrows(
515+
ExecutionException.class,
516+
() -> randomColl.whereGreaterThan("foo", 1).whereNotEqualTo("bar", 3).get().get());
517+
assertThat(executionException)
518+
.hasCauseThat()
519+
.hasMessageThat()
520+
.contains(
521+
"INVALID_ARGUMENT: Cannot have inequality filters on multiple properties: [bar, foo]");
522+
}
523+
491524
@Test
492525
public void greaterThanOrEqualQuery() throws Exception {
493526
addDocument("foo", 1);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.firestore.it;
18+
19+
import com.google.cloud.firestore.Firestore;
20+
21+
public final class TestHelper {
22+
/** Make constructor private to prevent creating instances. */
23+
private TestHelper() {}
24+
25+
/** Returns whether the tests are running against the Firestore emulator. */
26+
static boolean isRunningAgainstFirestoreEmulator(Firestore firestore) {
27+
return firestore.getOptions().getHost().startsWith("localhost:");
28+
}
29+
}

0 commit comments

Comments
 (0)