24
24
#import " Firestore/Example/Tests/Util/FSTEventAccumulator.h"
25
25
#import " Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
26
26
27
+ #include " Firestore/core/src/firebase/firestore/util/autoid.h"
28
+ #include " Firestore/core/src/firebase/firestore/util/string_apple.h"
29
+
30
+ using firebase::firestore::util::CreateAutoId;
31
+ using firebase::firestore::util::WrapNSString;
32
+
33
+ NS_ASSUME_NONNULL_BEGIN
34
+
27
35
@interface FIRWriteBatchTests : FSTIntegrationTestCase
28
36
@end
29
37
@@ -124,6 +132,52 @@ - (void)testCannotUpdateNonexistentDocuments {
124
132
XCTAssertFalse (result.exists );
125
133
}
126
134
135
+ - (void )testUpdateFieldsWithDots {
136
+ FIRDocumentReference *doc = [self documentRef ];
137
+
138
+ XCTestExpectation *expectation = [self expectationWithDescription: @" testUpdateFieldsWithDots" ];
139
+ FIRWriteBatch *batch = [doc.firestore batch ];
140
+ [batch setData: @{@" a.b" : @" old" , @" c.d" : @" old" } forDocument: doc];
141
+ [batch updateData: @{[[FIRFieldPath alloc ] initWithFields: @[ @" a.b" ]] : @" new" } forDocument: doc];
142
+
143
+ [batch commitWithCompletion: ^(NSError *_Nullable error) {
144
+ XCTAssertNil (error);
145
+ [doc getDocumentWithCompletion: ^(FIRDocumentSnapshot *snapshot, NSError *error) {
146
+ XCTAssertNil (error);
147
+ XCTAssertEqualObjects (snapshot.data , (@{@" a.b" : @" new" , @" c.d" : @" old" }));
148
+ }];
149
+ [expectation fulfill ];
150
+ }];
151
+
152
+ [self awaitExpectations ];
153
+ }
154
+
155
+ - (void )testUpdateNestedFields {
156
+ FIRDocumentReference *doc = [self documentRef ];
157
+
158
+ XCTestExpectation *expectation = [self expectationWithDescription: @" testUpdateNestedFields" ];
159
+ FIRWriteBatch *batch = [doc.firestore batch ];
160
+ [batch setData: @{@" a" : @{@" b" : @" old" }, @" c" : @{@" d" : @" old" }, @" e" : @{@" f" : @" old" }}
161
+ forDocument: doc];
162
+ [batch
163
+ updateData: @{@" a.b" : @" new" , [[FIRFieldPath alloc ] initWithFields: @[ @" c" , @" d" ]] : @" new" }
164
+ forDocument: doc];
165
+ [batch commitWithCompletion: ^(NSError *_Nullable error) {
166
+ XCTAssertNil (error);
167
+ [doc getDocumentWithCompletion: ^(FIRDocumentSnapshot *snapshot, NSError *error) {
168
+ XCTAssertNil (error);
169
+ XCTAssertEqualObjects (snapshot.data , (@{
170
+ @" a" : @{@" b" : @" new" },
171
+ @" c" : @{@" d" : @" new" },
172
+ @" e" : @{@" f" : @" old" }
173
+ }));
174
+ }];
175
+ [expectation fulfill ];
176
+ }];
177
+
178
+ [self awaitExpectations ];
179
+ }
180
+
127
181
- (void )testDeleteDocuments {
128
182
FIRDocumentReference *doc = [self documentRef ];
129
183
[self writeDocumentRef: doc data: @{@" foo" : @" bar" }];
@@ -161,6 +215,7 @@ - (void)testBatchesCommitAtomicallyRaisingCorrectEvents {
161
215
XCTAssertNil (error);
162
216
[expectation fulfill ];
163
217
}];
218
+ [self awaitExpectations ];
164
219
165
220
FIRQuerySnapshot *localSnap = [accumulator awaitEventWithName: @" local event" ];
166
221
XCTAssertTrue (localSnap.metadata .hasPendingWrites );
@@ -192,6 +247,7 @@ - (void)testBatchesFailAtomicallyRaisingCorrectEvents {
192
247
XCTAssertEqual (error.code , FIRFirestoreErrorCodeNotFound);
193
248
[expectation fulfill ];
194
249
}];
250
+ [self awaitExpectations ];
195
251
196
252
// Local event with the set document.
197
253
FIRQuerySnapshot *localSnap = [accumulator awaitEventWithName: @" local event" ];
@@ -223,6 +279,7 @@ - (void)testWriteTheSameServerTimestampAcrossWrites {
223
279
XCTAssertNil (error);
224
280
[expectation fulfill ];
225
281
}];
282
+ [self awaitExpectations ];
226
283
227
284
FIRQuerySnapshot *localSnap = [accumulator awaitEventWithName: @" local event" ];
228
285
XCTAssertTrue (localSnap.metadata .hasPendingWrites );
@@ -254,6 +311,7 @@ - (void)testCanWriteTheSameDocumentMultipleTimes {
254
311
XCTAssertNil (error);
255
312
[expectation fulfill ];
256
313
}];
314
+ [self awaitExpectations ];
257
315
258
316
FIRDocumentSnapshot *localSnap = [accumulator awaitEventWithName: @" local event" ];
259
317
XCTAssertTrue (localSnap.metadata .hasPendingWrites );
@@ -265,50 +323,39 @@ - (void)testCanWriteTheSameDocumentMultipleTimes {
265
323
XCTAssertEqualObjects (serverSnap.data , (@{@" a" : @1 , @" b" : @2 , @" when" : when}));
266
324
}
267
325
268
- - (void )testUpdateFieldsWithDots {
269
- FIRDocumentReference *doc = [self documentRef ];
326
+ - (void )testCanWriteVeryLargeBatches {
327
+ // On Android, SQLite Cursors are limited reading no more than 2 MB per row (despite being able
328
+ // to write very large values). This test verifies that the local MutationQueue is not subject
329
+ // to this limitation.
330
+
331
+ // Create a map containing nearly 1 MB of data. Note that if you use 1024 below this will create
332
+ // a document larger than 1 MB, which will be rejected by the backend as too large.
333
+ NSString *kb = [@" " stringByPaddingToLength: 1000 withString: @" a" startingAtIndex: 0 ];
334
+ NSMutableDictionary <NSString *, id > *values = [NSMutableDictionary dictionary ];
335
+ for (int i = 0 ; i < 1000 ; i++) {
336
+ values[WrapNSString (CreateAutoId ())] = kb;
337
+ }
270
338
271
- XCTestExpectation *expectation = [self expectationWithDescription: @" testUpdateFieldsWithDots " ];
339
+ FIRDocumentReference *doc = [self documentRef ];
272
340
FIRWriteBatch *batch = [doc.firestore batch ];
273
- [batch setData: @{@" a.b" : @" old" , @" c.d" : @" old" } forDocument: doc];
274
- [batch updateData: @{[[FIRFieldPath alloc ] initWithFields: @[ @" a.b" ]] : @" new" } forDocument: doc];
275
-
276
- [batch commitWithCompletion: ^(NSError *_Nullable error) {
277
- XCTAssertNil (error);
278
- [doc getDocumentWithCompletion: ^(FIRDocumentSnapshot *snapshot, NSError *error) {
279
- XCTAssertNil (error);
280
- XCTAssertEqualObjects (snapshot.data , (@{@" a.b" : @" new" , @" c.d" : @" old" }));
281
- }];
282
- [expectation fulfill ];
283
- }];
284
341
285
- [self awaitExpectations ];
286
- }
287
-
288
- - (void )testUpdateNestedFields {
289
- FIRDocumentReference *doc = [self documentRef ];
342
+ // Write a batch containing 3 copies of the data, creating a ~3 MB batch. Writing to the same
343
+ // document in a batch is allowed and so long as the net size of the document is under 1 MB the
344
+ // batch is allowed.
345
+ [batch setData: values forDocument: doc];
346
+ for (int i = 0 ; i < 2 ; i++) {
347
+ [batch updateData: values forDocument: doc];
348
+ }
290
349
291
- XCTestExpectation *expectation = [self expectationWithDescription: @" testUpdateNestedFields" ];
292
- FIRWriteBatch *batch = [doc.firestore batch ];
293
- [batch setData: @{@" a" : @{@" b" : @" old" }, @" c" : @{@" d" : @" old" }, @" e" : @{@" f" : @" old" }}
294
- forDocument: doc];
295
- [batch
296
- updateData: @{@" a.b" : @" new" , [[FIRFieldPath alloc ] initWithFields: @[ @" c" , @" d" ]] : @" new" }
297
- forDocument: doc];
350
+ XCTestExpectation *expectation = [self expectationWithDescription: @" batch written" ];
298
351
[batch commitWithCompletion: ^(NSError *_Nullable error) {
299
352
XCTAssertNil (error);
300
- [doc getDocumentWithCompletion: ^(FIRDocumentSnapshot *snapshot, NSError *error) {
301
- XCTAssertNil (error);
302
- XCTAssertEqualObjects (snapshot.data , (@{
303
- @" a" : @{@" b" : @" new" },
304
- @" c" : @{@" d" : @" new" },
305
- @" e" : @{@" f" : @" old" }
306
- }));
307
- }];
308
353
[expectation fulfill ];
309
354
}];
310
-
311
355
[self awaitExpectations ];
356
+
357
+ FIRDocumentSnapshot *snap = [self readDocumentForRef: doc];
358
+ XCTAssertEqualObjects (values, snap.data );
312
359
}
313
360
314
361
// Returns how much memory the test application is currently using, in megabytes (fractional part is
@@ -363,3 +410,5 @@ - (void)testReasonableMemoryUsageForLotsOfMutations {
363
410
}
364
411
365
412
@end
413
+
414
+ NS_ASSUME_NONNULL_END
0 commit comments