@@ -47,6 +47,7 @@ import {
4747 Query ,
4848 query ,
4949 QuerySnapshot ,
50+ runTransaction ,
5051 setDoc ,
5152 startAfter ,
5253 startAt ,
@@ -1614,6 +1615,32 @@ apiDescribe('Queries', (persistence: boolean) => {
16141615 } ) ;
16151616 } ) ;
16161617 } ) ;
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 = { } ;
1624+ for ( let i = 1 ; i <= 100 ; i ++ ) {
1625+ Object . assign ( 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' ) ;
16171644} ) ;
16181645
16191646function verifyDocumentChange < T > (
0 commit comments