@@ -47,6 +47,7 @@ import {
47
47
Query ,
48
48
query ,
49
49
QuerySnapshot ,
50
+ runTransaction ,
50
51
setDoc ,
51
52
startAfter ,
52
53
startAt ,
@@ -1614,6 +1615,32 @@ apiDescribe('Queries', (persistence: boolean) => {
1614
1615
} ) ;
1615
1616
} ) ;
1616
1617
} ) ;
1618
+
1619
+ // eslint-disable-next-line no-restricted-properties
1620
+ ( persistence ? it . skip : it ) (
1621
+ 'resuming a query should remove deleted documents indicated by existence filter' ,
1622
+ ( ) => {
1623
+ const testDocs : { [ key : string ] : object } = { } ;
1624
+ for ( let i = 1 ; i <= 100 ; i ++ ) {
1625
+ testDocs [ 'doc' + i ] = { key : i } ;
1626
+ }
1627
+ return withTestCollection ( persistence , testDocs , async ( coll , db ) => {
1628
+ const snapshot1 = await getDocs ( coll ) ;
1629
+ expect ( snapshot1 . size ) . to . equal ( 100 ) ;
1630
+ // Delete 50 docs in transaction so that it doesn't affect local cache.
1631
+ await runTransaction ( db , async txn => {
1632
+ for ( let i = 1 ; i <= 50 ; i ++ ) {
1633
+ txn . delete ( doc ( coll , 'doc' + i ) ) ;
1634
+ }
1635
+ } ) ;
1636
+ // Wait 10 seconds, during which Watch will stop tracking the query
1637
+ // and will send an existence filter rather than "delete" events.
1638
+ await new Promise ( resolve => setTimeout ( resolve , 10000 ) ) ;
1639
+ const snapshot2 = await getDocs ( coll ) ;
1640
+ expect ( snapshot2 . size ) . to . equal ( 50 ) ;
1641
+ } ) ;
1642
+ }
1643
+ ) . timeout ( '20s' ) ;
1617
1644
} ) ;
1618
1645
1619
1646
function verifyDocumentChange < T > (
0 commit comments