Skip to content

Commit 2fec016

Browse files
committed
Spec test for 8474
1 parent a97ac88 commit 2fec016

File tree

2 files changed

+108
-1
lines changed

2 files changed

+108
-1
lines changed

packages/firestore/test/unit/specs/collection_spec.test.ts

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,113 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { doc, query } from '../../util/helpers';
18+
import {doc, filter, query} from '../../util/helpers';
1919

2020
import { describeSpec, specTest } from './describe_spec';
2121
import { spec } from './spec_builder';
22+
import {newQueryForPath} from "../../../src/core/query";
2223

2324
describeSpec('Collections:', [], () => {
25+
26+
specTest('8474', ['exclusive', 'durable-persistence'], () => {
27+
28+
// onSnapshot(fullQuery)
29+
const fullQuery = query('collection');
30+
31+
// getDocs(filterQuery)
32+
const filterQuery = query('collection', filter('included', '==', true));
33+
34+
const docA = doc('collection/a', 1000, {key: 'a', included: false});
35+
const docA2 = doc('collection/a', 1007, {key: 'a', included: true});
36+
const docC = doc('collection/c', 1002, {key: 'c', included: true});
37+
38+
const limboQueryC = newQueryForPath(docC.key.path);
39+
40+
return spec()
41+
// onSnapshot(fullQuery) - fullQuery is listening to documents in the collection for the full test
42+
.userListens(fullQuery)
43+
.watchAcksFull(fullQuery, 1001, docA, docC)
44+
.expectEvents(fullQuery, {
45+
fromCache: false,
46+
added: [docA, docC]
47+
})
48+
49+
// docC was deleted, this puts docC in limbo and causes a snapshot from cache (metadata-only change)
50+
.watchSends({removed: [fullQuery]}, docC)
51+
.watchCurrents(fullQuery, 'resume-token-1002')
52+
.watchSnapshots(1002)
53+
.expectLimboDocs(docC.key)
54+
.expectEvents(fullQuery, {
55+
fromCache: true,
56+
})
57+
58+
// User begins getDocs(filterQuery)
59+
.userListensForGet(filterQuery)
60+
61+
// getDocs(filterQuery) will not resolve on the snapshot from cache
62+
.expectEvents(filterQuery, {
63+
fromCache: true,
64+
added: [docC]
65+
})
66+
67+
// Watch acks limbo and filter queries
68+
.watchAcks(limboQueryC)
69+
.watchAcks(filterQuery)
70+
71+
// Watch responds to limboQueryC - docC was deleted
72+
.watchSends({affects: [limboQueryC]})
73+
.watchCurrents(limboQueryC, 'resume-token-1009')
74+
.watchSnapshots(1009, [limboQueryC, fullQuery])
75+
76+
// However, docC is still in limbo because there has not been a global snapshot
77+
.expectLimboDocs(docC.key)
78+
79+
// Rapid events of document update and delete caused by application
80+
.watchSends({removed: [filterQuery]}, docA)
81+
.watchCurrents(filterQuery, 'resume-token-1004')
82+
.watchSends({affects: [filterQuery]}, docC)
83+
.watchCurrents(filterQuery, 'resume-token-1005')
84+
.watchSends({removed: [filterQuery]}, docC)
85+
.watchSends({affects: [filterQuery]}, docA2)
86+
.watchCurrents(filterQuery, 'resume-token-1007')
87+
88+
.watchSnapshots(1010, [fullQuery, limboQueryC])
89+
90+
// All changes are current and we get a global snapshot
91+
.watchSnapshots(1010, [])
92+
93+
// UNEXPECTED docC is still in limbo
94+
.expectLimboDocs(docC.key)
95+
96+
// This causes snapshots for fullQuery and filterQuery
97+
// to be raised as from cache
98+
.expectEvents(fullQuery, {
99+
fromCache: true,
100+
modified: [docA2]
101+
})
102+
103+
// getDocs(filterQuery) will not be resolved with this snapsho
104+
// because it is from cache
105+
.expectEvents(filterQuery, {
106+
fromCache: true,
107+
added: [docA2]
108+
})
109+
110+
// 45-seconds later on heartbeat/global-snapshot
111+
.watchSnapshots(1100, [])
112+
// Now docC is out of limbo
113+
.expectLimboDocs()
114+
.expectEvents(fullQuery, {
115+
fromCache: false,
116+
removed: [docC]
117+
})
118+
// Now getDocs(filterQuery) can be resolved
119+
.expectEvents(filterQuery, {
120+
fromCache: false,
121+
removed: [docC]
122+
});
123+
});
124+
24125
specTest('Events are raised after watch ack', [], () => {
25126
const query1 = query('collection');
26127
const doc1 = doc('collection/key', 1000, { foo: 'bar' });

packages/firestore/test/unit/specs/spec_builder.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,12 @@ export class SpecBuilder {
315315
return this;
316316
}
317317

318+
/** Listen to query using the same options as executing a getDoc or getDocs */
319+
userListensForGet(query: Query, resume?: ResumeSpec): this {
320+
this.addUserListenStep(query, resume, { includeMetadataChanges: true, waitForSyncWhenOnline: true });
321+
return this;
322+
}
323+
318324
userListensToCache(query: Query, resume?: ResumeSpec): this {
319325
this.addUserListenStep(query, resume, { source: Source.Cache });
320326
return this;

0 commit comments

Comments
 (0)