Search in sources :

Example 1 with DocumentChange

use of com.google.firebase.firestore.remote.WatchChange.DocumentChange in project firebase-android-sdk by firebase.

the class SpecTestCase method doWatchEntity.

private void doWatchEntity(JSONObject watchEntity) throws Exception {
    if (watchEntity.has("docs")) {
        Assert.hardAssert(!watchEntity.has("doc"), "Exactly one of |doc| or |docs| needs to be set.");
        JSONArray docs = watchEntity.getJSONArray("docs");
        for (int i = 0; i < docs.length(); ++i) {
            JSONObject doc = docs.getJSONObject(i);
            JSONObject watchSpec = new JSONObject();
            watchSpec.put("doc", doc);
            if (watchEntity.has("targets")) {
                watchSpec.put("targets", watchEntity.get("targets"));
            }
            if (watchEntity.has("removedTargets")) {
                watchSpec.put("removedTargets", watchEntity.get("removedTargets"));
            }
            doWatchEntity(watchSpec);
        }
    } else if (watchEntity.has("doc")) {
        JSONObject docSpec = watchEntity.getJSONObject("doc");
        String key = docSpec.getString("key");
        @Nullable Map<String, Object> value = !docSpec.isNull("value") ? parseMap(docSpec.getJSONObject("value")) : null;
        long version = docSpec.getLong("version");
        MutableDocument doc = value != null ? doc(key, version, value) : deletedDoc(key, version);
        List<Integer> updated = parseIntList(watchEntity.optJSONArray("targets"));
        List<Integer> removed = parseIntList(watchEntity.optJSONArray("removedTargets"));
        WatchChange change = new DocumentChange(updated, removed, doc.getKey(), doc);
        writeWatchChange(change, SnapshotVersion.NONE);
    } else if (watchEntity.has("key")) {
        String key = watchEntity.getString("key");
        List<Integer> removed = parseIntList(watchEntity.optJSONArray("removedTargets"));
        WatchChange change = new DocumentChange(Collections.emptyList(), removed, key(key), null);
        writeWatchChange(change, SnapshotVersion.NONE);
    } else {
        throw Assert.fail("Either key, doc or docs must be set.");
    }
}
Also used : JSONObject(org.json.JSONObject) JSONArray(org.json.JSONArray) MutableDocument(com.google.firebase.firestore.model.MutableDocument) WatchChange(com.google.firebase.firestore.remote.WatchChange) ExistenceFilterWatchChange(com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange) Collections.singletonList(java.util.Collections.singletonList) List(java.util.List) ArrayList(java.util.ArrayList) ByteString(com.google.protobuf.ByteString) DocumentChange(com.google.firebase.firestore.remote.WatchChange.DocumentChange) Map(java.util.Map) HashMap(java.util.HashMap)

Example 2 with DocumentChange

use of com.google.firebase.firestore.remote.WatchChange.DocumentChange in project firebase-android-sdk by firebase.

the class RemoteEventTest method createAggregator.

/**
 * Creates an aggregator initialized with the set of provided WatchChanges. Tests can add further
 * changes via `handleDocumentChange`, `handleTargetChange` and `handleExistenceFilterChange`.
 *
 * @param targetMap A map of query data for all active targets. The map must include an entry for
 *     every target referenced by any of the watch changes.
 * @param outstandingResponses The number of outstanding ACKs a target has to receive before it is
 *     considered active, or `noOutstandingResponses` if all targets are already active.
 * @param existingKeys The set of documents that are considered synced with the test targets as
 *     part of a previous listen. To modify this set during test execution, invoke
 *     `targetMetadataProvider.setSyncedKeys()`.
 * @param watchChanges The watch changes to apply before returning the aggregator. Supported
 *     changes are DocumentWatchChange and WatchTargetChange.
 */
private WatchChangeAggregator createAggregator(Map<Integer, TargetData> targetMap, Map<Integer, Integer> outstandingResponses, ImmutableSortedSet<DocumentKey> existingKeys, WatchChange... watchChanges) {
    WatchChangeAggregator aggregator = new WatchChangeAggregator(targetMetadataProvider);
    List<Integer> targetIds = new ArrayList<>();
    for (Map.Entry<Integer, TargetData> entry : targetMap.entrySet()) {
        targetIds.add(entry.getKey());
        targetMetadataProvider.setSyncedKeys(entry.getValue(), existingKeys);
    }
    for (Map.Entry<Integer, Integer> entry : outstandingResponses.entrySet()) {
        for (int i = 0; i < entry.getValue(); ++i) {
            aggregator.recordPendingTargetRequest(entry.getKey());
        }
    }
    for (WatchChange watchChange : watchChanges) {
        if (watchChange instanceof DocumentChange) {
            aggregator.handleDocumentChange((DocumentChange) watchChange);
        } else if (watchChange instanceof WatchTargetChange) {
            aggregator.handleTargetChange((WatchTargetChange) watchChange);
        } else {
            fail("Encountered unexpected type of WatchChange");
        }
    }
    aggregator.handleTargetChange(new WatchTargetChange(WatchTargetChangeType.NoChange, targetIds, resumeToken));
    return aggregator;
}
Also used : TargetData(com.google.firebase.firestore.local.TargetData) ArrayList(java.util.ArrayList) DocumentChange(com.google.firebase.firestore.remote.WatchChange.DocumentChange) HashMap(java.util.HashMap) Map(java.util.Map) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange)

Example 3 with DocumentChange

use of com.google.firebase.firestore.remote.WatchChange.DocumentChange in project firebase-android-sdk by firebase.

the class RemoteEventTest method testExistenceFilterMismatchRemovesCurrentChanges.

@Test
public void testExistenceFilterMismatchRemovesCurrentChanges() {
    Map<Integer, TargetData> targetMap = activeQueries(1);
    WatchChangeAggregator aggregator = createAggregator(targetMap, noOutstandingResponses, noExistingKeys);
    WatchTargetChange markCurrent = new WatchTargetChange(WatchTargetChangeType.Current, asList(1));
    aggregator.handleTargetChange(markCurrent);
    MutableDocument doc1 = doc("docs/1", 1, map("value", 1));
    DocumentChange addDoc = new DocumentChange(asList(1), emptyList(), doc1.getKey(), doc1);
    aggregator.handleDocumentChange(addDoc);
    // The existence filter mismatch will remove the document from target 1, but not synthesize a
    // document delete.
    WatchChange.ExistenceFilterWatchChange existenceFilter = new WatchChange.ExistenceFilterWatchChange(1, new ExistenceFilter(0));
    aggregator.handleExistenceFilter(existenceFilter);
    RemoteEvent event = aggregator.createRemoteEvent(version(3));
    assertEquals(version(3), event.getSnapshotVersion());
    assertEquals(1, event.getDocumentUpdates().size());
    assertEquals(1, event.getTargetMismatches().size());
    assertEquals(doc1, event.getDocumentUpdates().get(doc1.getKey()));
    assertEquals(1, event.getTargetChanges().size());
    TargetChange mapping1 = targetChange(ByteString.EMPTY, false, null, null, null);
    assertEquals(mapping1, event.getTargetChanges().get(1));
}
Also used : MutableDocument(com.google.firebase.firestore.model.MutableDocument) DocumentChange(com.google.firebase.firestore.remote.WatchChange.DocumentChange) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) TargetData(com.google.firebase.firestore.local.TargetData) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) Test(org.junit.Test)

Example 4 with DocumentChange

use of com.google.firebase.firestore.remote.WatchChange.DocumentChange in project firebase-android-sdk by firebase.

the class RemoteEventTest method testWillAccumulateDocumentAddedAndRemovedEvents.

@Test
public void testWillAccumulateDocumentAddedAndRemovedEvents() {
    Map<Integer, TargetData> targetMap = activeQueries(1, 2, 3, 4, 5, 6);
    MutableDocument existingDoc = doc("docs/1", 1, map("value", 1));
    MutableDocument newDoc = doc("docs/2", 2, map("value", 2));
    WatchChange change1 = new DocumentChange(asList(1, 2, 3), asList(4, 5, 6), existingDoc.getKey(), existingDoc);
    WatchChange change2 = new DocumentChange(asList(1, 4), asList(2, 6), newDoc.getKey(), newDoc);
    RemoteEvent event = createRemoteEvent(3, targetMap, noOutstandingResponses, keySet(existingDoc.getKey()), change1, change2);
    assertEquals(version(3), event.getSnapshotVersion());
    assertEquals(2, event.getDocumentUpdates().size());
    assertEquals(existingDoc, event.getDocumentUpdates().get(existingDoc.getKey()));
    assertEquals(newDoc, event.getDocumentUpdates().get(newDoc.getKey()));
    assertEquals(6, event.getTargetChanges().size());
    TargetChange mapping1 = targetChange(resumeToken, false, asList(newDoc), asList(existingDoc), null);
    assertEquals(mapping1, event.getTargetChanges().get(1));
    TargetChange mapping2 = targetChange(resumeToken, false, null, asList(existingDoc), null);
    assertEquals(mapping2, event.getTargetChanges().get(2));
    TargetChange mapping3 = targetChange(resumeToken, false, null, asList(existingDoc), null);
    assertEquals(mapping3, event.getTargetChanges().get(3));
    TargetChange mapping4 = targetChange(resumeToken, false, asList(newDoc), null, asList(existingDoc));
    assertEquals(mapping4, event.getTargetChanges().get(4));
    TargetChange mapping5 = targetChange(resumeToken, false, null, null, asList(existingDoc));
    assertEquals(mapping5, event.getTargetChanges().get(5));
    TargetChange mapping6 = targetChange(resumeToken, false, null, null, asList(existingDoc));
    assertEquals(mapping6, event.getTargetChanges().get(6));
}
Also used : TargetData(com.google.firebase.firestore.local.TargetData) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) MutableDocument(com.google.firebase.firestore.model.MutableDocument) DocumentChange(com.google.firebase.firestore.remote.WatchChange.DocumentChange) Test(org.junit.Test)

Example 5 with DocumentChange

use of com.google.firebase.firestore.remote.WatchChange.DocumentChange in project firebase-android-sdk by firebase.

the class RemoteEventTest method testTargetAddedChangeWillResetPreviousState.

@Test
public void testTargetAddedChangeWillResetPreviousState() {
    Map<Integer, TargetData> targetMap = activeQueries(1, 3);
    MutableDocument doc1 = doc("docs/1", 1, map("value", 1));
    MutableDocument doc2 = doc("docs/2", 2, map("value", 2));
    WatchChange change1 = new DocumentChange(asList(1, 3), asList(2), doc1.getKey(), doc1);
    WatchChange change2 = new WatchTargetChange(WatchTargetChangeType.Current, asList(1, 2, 3));
    WatchChange change3 = new WatchTargetChange(WatchTargetChangeType.Removed, asList(1));
    WatchChange change4 = new WatchTargetChange(WatchTargetChangeType.Removed, asList(2));
    WatchChange change5 = new WatchTargetChange(WatchTargetChangeType.Added, asList(1));
    WatchChange change6 = new DocumentChange(asList(1), asList(3), doc2.getKey(), doc2);
    Map<Integer, Integer> outstanding = new HashMap<>();
    outstanding.put(1, 2);
    outstanding.put(2, 1);
    RemoteEvent event = createRemoteEvent(3, targetMap, outstanding, keySet(doc2.getKey()), change1, change2, change3, change4, change5, change6);
    assertEquals(version(3), event.getSnapshotVersion());
    assertEquals(2, event.getDocumentUpdates().size());
    assertEquals(doc1, event.getDocumentUpdates().get(doc1.getKey()));
    assertEquals(doc2, event.getDocumentUpdates().get(doc2.getKey()));
    // target 1 and 3 are affected (1 because of re-add), target 2 is not because of remove.
    assertEquals(2, event.getTargetChanges().size());
    // doc1 was before the remove, so it does not show up in the mapping.
    // Current was before the remove.
    TargetChange mapping1 = targetChange(resumeToken, false, null, asList(doc2), null);
    assertEquals(mapping1, event.getTargetChanges().get(1));
    // Doc1 was before the remove.
    // Current was after the remove
    TargetChange mapping3 = targetChange(resumeToken, true, asList(doc1), null, asList(doc2));
    assertEquals(mapping3, event.getTargetChanges().get(3));
}
Also used : TargetData(com.google.firebase.firestore.local.TargetData) HashMap(java.util.HashMap) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) MutableDocument(com.google.firebase.firestore.model.MutableDocument) DocumentChange(com.google.firebase.firestore.remote.WatchChange.DocumentChange) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) Test(org.junit.Test)

Aggregations

DocumentChange (com.google.firebase.firestore.remote.WatchChange.DocumentChange)16 TargetData (com.google.firebase.firestore.local.TargetData)14 MutableDocument (com.google.firebase.firestore.model.MutableDocument)13 WatchTargetChange (com.google.firebase.firestore.remote.WatchChange.WatchTargetChange)13 Test (org.junit.Test)11 HashMap (java.util.HashMap)5 ImmutableSortedSet (com.google.firebase.database.collection.ImmutableSortedSet)2 SnapshotVersion (com.google.firebase.firestore.model.SnapshotVersion)2 ExistenceFilterWatchChange (com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange)2 WatchChangeAggregator (com.google.firebase.firestore.remote.WatchChangeAggregator)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 DocumentKey (com.google.firebase.firestore.model.DocumentKey)1 ResourcePath (com.google.firebase.firestore.model.ResourcePath)1 WatchChange (com.google.firebase.firestore.remote.WatchChange)1 ByteString (com.google.protobuf.ByteString)1 Collections.singletonList (java.util.Collections.singletonList)1 List (java.util.List)1 JSONArray (org.json.JSONArray)1 JSONObject (org.json.JSONObject)1