FIRFirestoreSourceTests.mm 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /*
  2. * Copyright 2018 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import <FirebaseFirestore/FirebaseFirestore.h>
  17. #import <XCTest/XCTest.h>
  18. #import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
  19. #import "Firestore/Source/API/FIRFirestore+Internal.h"
  20. #import "Firestore/Source/Core/FSTFirestoreClient.h"
  21. @interface FIRFirestoreSourceTests : FSTIntegrationTestCase
  22. @end
  23. @implementation FIRFirestoreSourceTests
  24. - (void)testGetDocumentWhileOnlineWithDefaultSource {
  25. FIRDocumentReference *doc = [self documentRef];
  26. // set document to a known value
  27. NSDictionary<NSString *, id> *initialData = @{@"key" : @"value"};
  28. [self writeDocumentRef:doc data:initialData];
  29. // get doc and ensure that it exists, is *not* from the cache, and matches
  30. // the initialData.
  31. FIRDocumentSnapshot *result = [self readDocumentForRef:doc];
  32. XCTAssertTrue(result.exists);
  33. XCTAssertFalse(result.metadata.fromCache);
  34. XCTAssertFalse(result.metadata.hasPendingWrites);
  35. XCTAssertEqualObjects(result.data, initialData);
  36. }
  37. - (void)testGetCollectionWhileOnlineWithDefaultSource {
  38. FIRCollectionReference *col = [self collectionRef];
  39. // set a few documents to known values
  40. NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
  41. @"doc1" : @{@"key1" : @"value1"},
  42. @"doc2" : @{@"key2" : @"value2"},
  43. @"doc3" : @{@"key3" : @"value3"}
  44. };
  45. [self writeAllDocuments:initialDocs toCollection:col];
  46. // get docs and ensure they are *not* from the cache, and match the
  47. // initialDocs.
  48. FIRQuerySnapshot *result = [self readDocumentSetForRef:col];
  49. XCTAssertFalse(result.metadata.fromCache);
  50. XCTAssertFalse(result.metadata.hasPendingWrites);
  51. XCTAssertEqualObjects(
  52. FIRQuerySnapshotGetData(result),
  53. (@[ @{@"key1" : @"value1"}, @{@"key2" : @"value2"}, @{@"key3" : @"value3"} ]));
  54. XCTAssertEqualObjects(FIRQuerySnapshotGetDocChangesData(result), (@[
  55. @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
  56. @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2"} ],
  57. @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3" : @"value3"} ]
  58. ]));
  59. }
  60. - (void)testGetDocumentWhileOfflineWithDefaultSource {
  61. FIRDocumentReference *doc = [self documentRef];
  62. // set document to a known value
  63. NSDictionary<NSString *, id> *initialData = @{@"key1" : @"value1"};
  64. [self writeDocumentRef:doc data:initialData];
  65. // go offline for the rest of this test
  66. [self disableNetwork];
  67. // update the doc (though don't wait for a server response. We're offline; so
  68. // that ain't happening!). This allows us to further distinguished cached vs
  69. // server responses below.
  70. NSDictionary<NSString *, id> *newData = @{@"key2" : @"value2"};
  71. [doc setData:newData
  72. completion:^(NSError *_Nullable error) {
  73. XCTAssertTrue(false, "Because we're offline, this should never occur.");
  74. }];
  75. // get doc and ensure it exists, *is* from the cache, and matches the
  76. // newData.
  77. FIRDocumentSnapshot *result = [self readDocumentForRef:doc];
  78. XCTAssertTrue(result.exists);
  79. XCTAssertTrue(result.metadata.fromCache);
  80. XCTAssertTrue(result.metadata.hasPendingWrites);
  81. XCTAssertEqualObjects(result.data, newData);
  82. }
  83. - (void)testGetCollectionWhileOfflineWithDefaultSource {
  84. FIRCollectionReference *col = [self collectionRef];
  85. // set a few documents to known values
  86. NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
  87. @"doc1" : @{@"key1" : @"value1"},
  88. @"doc2" : @{@"key2" : @"value2"},
  89. @"doc3" : @{@"key3" : @"value3"}
  90. };
  91. [self writeAllDocuments:initialDocs toCollection:col];
  92. // go offline for the rest of this test
  93. [self disableNetwork];
  94. // update the docs (though don't wait for a server response. We're offline; so
  95. // that ain't happening!). This allows us to further distinguished cached vs
  96. // server responses below.
  97. [[col documentWithPath:@"doc2"] setData:@{@"key2b" : @"value2b"} merge:YES];
  98. [[col documentWithPath:@"doc3"] setData:@{@"key3b" : @"value3b"}];
  99. [[col documentWithPath:@"doc4"] setData:@{@"key4" : @"value4"}];
  100. // get docs and ensure they *are* from the cache, and matches the updated data.
  101. FIRQuerySnapshot *result = [self readDocumentSetForRef:col];
  102. XCTAssertTrue(result.metadata.fromCache);
  103. XCTAssertTrue(result.metadata.hasPendingWrites);
  104. XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
  105. @{@"key1" : @"value1"}, @{@"key2" : @"value2", @"key2b" : @"value2b"},
  106. @{@"key3b" : @"value3b"}, @{@"key4" : @"value4"}
  107. ]));
  108. XCTAssertEqualObjects(
  109. FIRQuerySnapshotGetDocChangesData(result), (@[
  110. @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
  111. @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2", @"key2b" : @"value2b"} ],
  112. @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3b" : @"value3b"} ],
  113. @[ @(FIRDocumentChangeTypeAdded), @"doc4", @{@"key4" : @"value4"} ]
  114. ]));
  115. }
  116. - (void)testGetDocumentWhileOnlineCacheOnly {
  117. FIRDocumentReference *doc = [self documentRef];
  118. // set document to a known value
  119. NSDictionary<NSString *, id> *initialData = @{@"key" : @"value"};
  120. [self writeDocumentRef:doc data:initialData];
  121. // get doc and ensure that it exists, *is* from the cache, and matches
  122. // the initialData.
  123. FIRDocumentSnapshot *result = [self readDocumentForRef:doc source:FIRFirestoreSourceCache];
  124. XCTAssertTrue(result.exists);
  125. XCTAssertTrue(result.metadata.fromCache);
  126. XCTAssertFalse(result.metadata.hasPendingWrites);
  127. XCTAssertEqualObjects(result.data, initialData);
  128. }
  129. - (void)testGetCollectionWhileOnlineCacheOnly {
  130. FIRCollectionReference *col = [self collectionRef];
  131. // set a few documents to a known value
  132. NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
  133. @"doc1" : @{@"key1" : @"value1"},
  134. @"doc2" : @{@"key2" : @"value2"},
  135. @"doc3" : @{@"key3" : @"value3"},
  136. };
  137. [self writeAllDocuments:initialDocs toCollection:col];
  138. // get docs and ensure they *are* from the cache, and matches the
  139. // initialDocs.
  140. FIRQuerySnapshot *result = [self readDocumentSetForRef:col source:FIRFirestoreSourceCache];
  141. XCTAssertTrue(result.metadata.fromCache);
  142. XCTAssertFalse(result.metadata.hasPendingWrites);
  143. XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
  144. @{@"key1" : @"value1"},
  145. @{@"key2" : @"value2"},
  146. @{@"key3" : @"value3"},
  147. ]));
  148. XCTAssertEqualObjects(FIRQuerySnapshotGetDocChangesData(result), (@[
  149. @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
  150. @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2"} ],
  151. @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3" : @"value3"} ]
  152. ]));
  153. }
  154. - (void)testGetDocumentWhileOfflineCacheOnly {
  155. FIRDocumentReference *doc = [self documentRef];
  156. // set document to a known value
  157. NSDictionary<NSString *, id> *initialData = @{@"key1" : @"value1"};
  158. [self writeDocumentRef:doc data:initialData];
  159. // go offline for the rest of this test
  160. [self disableNetwork];
  161. // update the doc (though don't wait for a server response. We're offline; so
  162. // that ain't happening!). This allows us to further distinguished cached vs
  163. // server responses below.
  164. NSDictionary<NSString *, id> *newData = @{@"key2" : @"value2"};
  165. [doc setData:newData
  166. completion:^(NSError *_Nullable error) {
  167. XCTFail("Because we're offline, this should never occur.");
  168. }];
  169. // get doc and ensure it exists, *is* from the cache, and matches the
  170. // newData.
  171. FIRDocumentSnapshot *result = [self readDocumentForRef:doc source:FIRFirestoreSourceCache];
  172. XCTAssertTrue(result.exists);
  173. XCTAssertTrue(result.metadata.fromCache);
  174. XCTAssertTrue(result.metadata.hasPendingWrites);
  175. XCTAssertEqualObjects(result.data, newData);
  176. }
  177. - (void)testGetCollectionWhileOfflineCacheOnly {
  178. FIRCollectionReference *col = [self collectionRef];
  179. // set a few documents to a known value
  180. NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
  181. @"doc1" : @{@"key1" : @"value1"},
  182. @"doc2" : @{@"key2" : @"value2"},
  183. @"doc3" : @{@"key3" : @"value3"},
  184. };
  185. [self writeAllDocuments:initialDocs toCollection:col];
  186. // go offline for the rest of this test
  187. [self disableNetwork];
  188. // update the docs (though don't wait for a server response. We're offline; so
  189. // that ain't happening!). This allows us to further distinguished cached vs
  190. // server responses below.
  191. [[col documentWithPath:@"doc2"] setData:@{@"key2b" : @"value2b"} merge:YES];
  192. [[col documentWithPath:@"doc3"] setData:@{@"key3b" : @"value3b"}];
  193. [[col documentWithPath:@"doc4"] setData:@{@"key4" : @"value4"}];
  194. // get docs and ensure they *are* from the cache, and matches the updated
  195. // data.
  196. FIRQuerySnapshot *result = [self readDocumentSetForRef:col source:FIRFirestoreSourceCache];
  197. XCTAssertTrue(result.metadata.fromCache);
  198. XCTAssertTrue(result.metadata.hasPendingWrites);
  199. XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
  200. @{@"key1" : @"value1"}, @{@"key2" : @"value2", @"key2b" : @"value2b"},
  201. @{@"key3b" : @"value3b"}, @{@"key4" : @"value4"}
  202. ]));
  203. XCTAssertEqualObjects(
  204. FIRQuerySnapshotGetDocChangesData(result), (@[
  205. @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
  206. @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2", @"key2b" : @"value2b"} ],
  207. @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3b" : @"value3b"} ],
  208. @[ @(FIRDocumentChangeTypeAdded), @"doc4", @{@"key4" : @"value4"} ]
  209. ]));
  210. }
  211. - (void)testGetDocumentWhileOnlineServerOnly {
  212. FIRDocumentReference *doc = [self documentRef];
  213. // set document to a known value
  214. NSDictionary<NSString *, id> *initialData = @{@"key" : @"value"};
  215. [self writeDocumentRef:doc data:initialData];
  216. // get doc and ensure that it exists, is *not* from the cache, and matches
  217. // the initialData.
  218. FIRDocumentSnapshot *result = [self readDocumentForRef:doc source:FIRFirestoreSourceServer];
  219. XCTAssertTrue(result.exists);
  220. XCTAssertFalse(result.metadata.fromCache);
  221. XCTAssertFalse(result.metadata.hasPendingWrites);
  222. XCTAssertEqualObjects(result.data, initialData);
  223. }
  224. - (void)testGetCollectionWhileOnlineServerOnly {
  225. FIRCollectionReference *col = [self collectionRef];
  226. // set a few documents to a known value
  227. NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
  228. @"doc1" : @{@"key1" : @"value1"},
  229. @"doc2" : @{@"key2" : @"value2"},
  230. @"doc3" : @{@"key3" : @"value3"},
  231. };
  232. [self writeAllDocuments:initialDocs toCollection:col];
  233. // get docs and ensure they are *not* from the cache, and matches the
  234. // initialData.
  235. FIRQuerySnapshot *result = [self readDocumentSetForRef:col source:FIRFirestoreSourceServer];
  236. XCTAssertFalse(result.metadata.fromCache);
  237. XCTAssertFalse(result.metadata.hasPendingWrites);
  238. XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
  239. @{@"key1" : @"value1"},
  240. @{@"key2" : @"value2"},
  241. @{@"key3" : @"value3"},
  242. ]));
  243. XCTAssertEqualObjects(FIRQuerySnapshotGetDocChangesData(result), (@[
  244. @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
  245. @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2"} ],
  246. @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3" : @"value3"} ]
  247. ]));
  248. }
  249. - (void)testGetDocumentWhileOfflineServerOnly {
  250. FIRDocumentReference *doc = [self documentRef];
  251. // set document to a known value
  252. NSDictionary<NSString *, id> *initialData = @{@"key1" : @"value1"};
  253. [self writeDocumentRef:doc data:initialData];
  254. // go offline for the rest of this test
  255. [self disableNetwork];
  256. // attempt to get doc and ensure it cannot be retreived
  257. XCTestExpectation *failedGetDocCompletion = [self expectationWithDescription:@"failedGetDoc"];
  258. [doc getDocumentWithSource:FIRFirestoreSourceServer
  259. completion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
  260. XCTAssertNotNil(error);
  261. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  262. XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
  263. [failedGetDocCompletion fulfill];
  264. }];
  265. [self awaitExpectations];
  266. }
  267. - (void)testGetCollectionWhileOfflineServerOnly {
  268. FIRCollectionReference *col = [self collectionRef];
  269. // set a few documents to a known value
  270. NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
  271. @"doc1" : @{@"key1" : @"value1"},
  272. @"doc2" : @{@"key2" : @"value2"},
  273. @"doc3" : @{@"key3" : @"value3"},
  274. };
  275. [self writeAllDocuments:initialDocs toCollection:col];
  276. // go offline for the rest of this test
  277. [self disableNetwork];
  278. // attempt to get docs and ensure they cannot be retreived
  279. XCTestExpectation *failedGetDocsCompletion = [self expectationWithDescription:@"failedGetDocs"];
  280. [col getDocumentsWithSource:FIRFirestoreSourceServer
  281. completion:^(FIRQuerySnapshot *snapshot, NSError *error) {
  282. XCTAssertNotNil(error);
  283. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  284. XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
  285. [failedGetDocsCompletion fulfill];
  286. }];
  287. [self awaitExpectations];
  288. }
  289. - (void)testGetDocumentWhileOfflineWithDifferentSource {
  290. FIRDocumentReference *doc = [self documentRef];
  291. // set document to a known value
  292. NSDictionary<NSString *, id> *initialData = @{@"key1" : @"value1"};
  293. [self writeDocumentRef:doc data:initialData];
  294. // go offline for the rest of this test
  295. [self disableNetwork];
  296. // update the doc (though don't wait for a server response. We're offline; so
  297. // that ain't happening!). This allows us to further distinguished cached vs
  298. // server responses below.
  299. NSDictionary<NSString *, id> *newData = @{@"key2" : @"value2"};
  300. [doc setData:newData
  301. completion:^(NSError *_Nullable error) {
  302. XCTAssertTrue(false, "Because we're offline, this should never occur.");
  303. }];
  304. // Create an initial listener for this query (to attempt to disrupt the gets below) and wait for
  305. // the listener to deliver its initial snapshot before continuing.
  306. XCTestExpectation *listenerReady = [self expectationWithDescription:@"listenerReady"];
  307. [doc addSnapshotListener:^(FIRDocumentSnapshot *snapshot, NSError *error) {
  308. [listenerReady fulfill];
  309. }];
  310. [self awaitExpectations];
  311. // get doc (from cache) and ensure it exists, *is* from the cache, and
  312. // matches the newData.
  313. FIRDocumentSnapshot *result = [self readDocumentForRef:doc source:FIRFirestoreSourceCache];
  314. XCTAssertTrue(result.exists);
  315. XCTAssertTrue(result.metadata.fromCache);
  316. XCTAssertTrue(result.metadata.hasPendingWrites);
  317. XCTAssertEqualObjects(result.data, newData);
  318. // attempt to get doc (with default get source)
  319. result = [self readDocumentForRef:doc source:FIRFirestoreSourceDefault];
  320. XCTAssertTrue(result.exists);
  321. XCTAssertTrue(result.metadata.fromCache);
  322. XCTAssertTrue(result.metadata.hasPendingWrites);
  323. XCTAssertEqualObjects(result.data, newData);
  324. // attempt to get doc (from the server) and ensure it cannot be retreived
  325. XCTestExpectation *failedGetDocCompletion = [self expectationWithDescription:@"failedGetDoc"];
  326. [doc getDocumentWithSource:FIRFirestoreSourceServer
  327. completion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
  328. XCTAssertNotNil(error);
  329. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  330. XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
  331. [failedGetDocCompletion fulfill];
  332. }];
  333. [self awaitExpectations];
  334. }
  335. - (void)testGetCollectionWhileOfflineWithDifferentSource {
  336. FIRCollectionReference *col = [self collectionRef];
  337. // set a few documents to a known value
  338. NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
  339. @"doc1" : @{@"key1" : @"value1"},
  340. @"doc2" : @{@"key2" : @"value2"},
  341. @"doc3" : @{@"key3" : @"value3"},
  342. };
  343. [self writeAllDocuments:initialDocs toCollection:col];
  344. // go offline for the rest of this test
  345. [self disableNetwork];
  346. // update the docs (though don't wait for a server response. We're offline; so
  347. // that ain't happening!). This allows us to further distinguished cached vs
  348. // server responses below.
  349. [[col documentWithPath:@"doc2"] setData:@{@"key2b" : @"value2b"} merge:YES];
  350. [[col documentWithPath:@"doc3"] setData:@{@"key3b" : @"value3b"}];
  351. [[col documentWithPath:@"doc4"] setData:@{@"key4" : @"value4"}];
  352. // Create an initial listener for this query (to attempt to disrupt the gets
  353. // below) and wait for the listener to deliver its initial snapshot before
  354. // continuing.
  355. XCTestExpectation *listenerReady = [self expectationWithDescription:@"listenerReady"];
  356. [col addSnapshotListener:^(FIRQuerySnapshot *snapshot, NSError *error) {
  357. [listenerReady fulfill];
  358. }];
  359. [self awaitExpectations];
  360. // get docs (from cache) and ensure they *are* from the cache, and
  361. // matches the updated data.
  362. FIRQuerySnapshot *result = [self readDocumentSetForRef:col source:FIRFirestoreSourceCache];
  363. XCTAssertTrue(result.metadata.fromCache);
  364. XCTAssertTrue(result.metadata.hasPendingWrites);
  365. XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
  366. @{@"key1" : @"value1"}, @{@"key2" : @"value2", @"key2b" : @"value2b"},
  367. @{@"key3b" : @"value3b"}, @{@"key4" : @"value4"}
  368. ]));
  369. XCTAssertEqualObjects(
  370. FIRQuerySnapshotGetDocChangesData(result), (@[
  371. @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
  372. @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2", @"key2b" : @"value2b"} ],
  373. @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3b" : @"value3b"} ],
  374. @[ @(FIRDocumentChangeTypeAdded), @"doc4", @{@"key4" : @"value4"} ]
  375. ]));
  376. // attempt to get docs (with default get source)
  377. result = [self readDocumentSetForRef:col source:FIRFirestoreSourceDefault];
  378. XCTAssertTrue(result.metadata.fromCache);
  379. XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
  380. @{@"key1" : @"value1"}, @{@"key2" : @"value2", @"key2b" : @"value2b"},
  381. @{@"key3b" : @"value3b"}, @{@"key4" : @"value4"}
  382. ]));
  383. XCTAssertEqualObjects(
  384. FIRQuerySnapshotGetDocChangesData(result), (@[
  385. @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
  386. @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2", @"key2b" : @"value2b"} ],
  387. @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3b" : @"value3b"} ],
  388. @[ @(FIRDocumentChangeTypeAdded), @"doc4", @{@"key4" : @"value4"} ]
  389. ]));
  390. // attempt to get docs (from the server) and ensure they cannot be retreived
  391. XCTestExpectation *failedGetDocsCompletion = [self expectationWithDescription:@"failedGetDocs"];
  392. [col getDocumentsWithSource:FIRFirestoreSourceServer
  393. completion:^(FIRQuerySnapshot *snapshot, NSError *error) {
  394. XCTAssertNotNil(error);
  395. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  396. XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
  397. [failedGetDocsCompletion fulfill];
  398. }];
  399. [self awaitExpectations];
  400. }
  401. - (void)testGetNonExistingDocWhileOnlineWithDefaultSource {
  402. FIRDocumentReference *doc = [self documentRef];
  403. // get doc and ensure that it does not exist and is *not* from the cache.
  404. FIRDocumentSnapshot *snapshot = [self readDocumentForRef:doc];
  405. XCTAssertFalse(snapshot.exists);
  406. XCTAssertFalse(snapshot.metadata.fromCache);
  407. XCTAssertFalse(snapshot.metadata.hasPendingWrites);
  408. }
  409. - (void)testGetNonExistingCollectionWhileOnlineWithDefaultSource {
  410. FIRCollectionReference *col = [self collectionRef];
  411. // get collection and ensure it's empty and that it's *not* from the cache.
  412. FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:col];
  413. XCTAssertEqual(snapshot.count, 0);
  414. XCTAssertEqual(snapshot.documentChanges.count, 0);
  415. XCTAssertFalse(snapshot.metadata.fromCache);
  416. XCTAssertFalse(snapshot.metadata.hasPendingWrites);
  417. }
  418. - (void)testGetNonExistingDocWhileOfflineWithDefaultSource {
  419. FIRDocumentReference *doc = [self documentRef];
  420. // go offline for the rest of this test
  421. [self disableNetwork];
  422. // attempt to get doc. Currently, this is expected to fail. In the future, we
  423. // might consider adding support for negative cache hits so that we know
  424. // certain documents *don't* exist.
  425. XCTestExpectation *getNonExistingDocCompletion =
  426. [self expectationWithDescription:@"getNonExistingDoc"];
  427. [doc getDocumentWithCompletion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
  428. XCTAssertNotNil(error);
  429. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  430. XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
  431. [getNonExistingDocCompletion fulfill];
  432. }];
  433. [self awaitExpectations];
  434. }
  435. - (void)testGetNonExistingCollectionWhileOfflineWithDefaultSource {
  436. FIRCollectionReference *col = [self collectionRef];
  437. // go offline for the rest of this test
  438. [self disableNetwork];
  439. // get collection and ensure it's empty and that it *is* from the cache.
  440. FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:col];
  441. XCTAssertEqual(snapshot.count, 0);
  442. XCTAssertEqual(snapshot.documentChanges.count, 0);
  443. XCTAssertTrue(snapshot.metadata.fromCache);
  444. XCTAssertFalse(snapshot.metadata.hasPendingWrites);
  445. }
  446. - (void)testGetNonExistingDocWhileOnlineCacheOnly {
  447. FIRDocumentReference *doc = [self documentRef];
  448. // attempt to get doc. Currently, this is expected to fail. In the future, we
  449. // might consider adding support for negative cache hits so that we know
  450. // certain documents *don't* exist.
  451. XCTestExpectation *getNonExistingDocCompletion =
  452. [self expectationWithDescription:@"getNonExistingDoc"];
  453. [doc getDocumentWithSource:FIRFirestoreSourceCache
  454. completion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
  455. XCTAssertNotNil(error);
  456. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  457. XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
  458. [getNonExistingDocCompletion fulfill];
  459. }];
  460. [self awaitExpectations];
  461. }
  462. - (void)testGetNonExistingCollectionWhileOnlineCacheOnly {
  463. FIRCollectionReference *col = [self collectionRef];
  464. // get collection and ensure it's empty and that it *is* from the cache.
  465. FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:col source:FIRFirestoreSourceCache];
  466. XCTAssertEqual(snapshot.count, 0);
  467. XCTAssertEqual(snapshot.documentChanges.count, 0);
  468. XCTAssertTrue(snapshot.metadata.fromCache);
  469. XCTAssertFalse(snapshot.metadata.hasPendingWrites);
  470. }
  471. - (void)testGetNonExistingDocWhileOfflineCacheOnly {
  472. FIRDocumentReference *doc = [self documentRef];
  473. // go offline for the rest of this test
  474. [self disableNetwork];
  475. // attempt to get doc. Currently, this is expected to fail. In the future, we
  476. // might consider adding support for negative cache hits so that we know
  477. // certain documents *don't* exist.
  478. XCTestExpectation *getNonExistingDocCompletion =
  479. [self expectationWithDescription:@"getNonExistingDoc"];
  480. [doc getDocumentWithSource:FIRFirestoreSourceCache
  481. completion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
  482. XCTAssertNotNil(error);
  483. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  484. XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
  485. [getNonExistingDocCompletion fulfill];
  486. }];
  487. [self awaitExpectations];
  488. }
  489. - (void)testGetNonExistingCollectionWhileOfflineCacheOnly {
  490. FIRCollectionReference *col = [self collectionRef];
  491. // go offline for the rest of this test
  492. [self disableNetwork];
  493. // get collection and ensure it's empty and that it *is* from the cache.
  494. FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:col source:FIRFirestoreSourceCache];
  495. XCTAssertEqual(snapshot.count, 0);
  496. XCTAssertEqual(snapshot.documentChanges.count, 0);
  497. XCTAssertTrue(snapshot.metadata.fromCache);
  498. XCTAssertFalse(snapshot.metadata.hasPendingWrites);
  499. }
  500. - (void)testGetNonExistingDocWhileOnlineServerOnly {
  501. FIRDocumentReference *doc = [self documentRef];
  502. // get doc and ensure that it does not exist and is *not* from the cache.
  503. FIRDocumentSnapshot *snapshot = [self readDocumentForRef:doc source:FIRFirestoreSourceServer];
  504. XCTAssertFalse(snapshot.exists);
  505. XCTAssertFalse(snapshot.metadata.fromCache);
  506. XCTAssertFalse(snapshot.metadata.hasPendingWrites);
  507. }
  508. - (void)testGetNonExistingCollectionWhileOnlineServerOnly {
  509. FIRCollectionReference *col = [self collectionRef];
  510. // get collection and ensure that it's empty and that it's *not* from the cache.
  511. FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:col source:FIRFirestoreSourceServer];
  512. XCTAssertEqual(snapshot.count, 0);
  513. XCTAssertEqual(snapshot.documentChanges.count, 0);
  514. XCTAssertFalse(snapshot.metadata.fromCache);
  515. XCTAssertFalse(snapshot.metadata.hasPendingWrites);
  516. }
  517. - (void)testGetNonExistingDocWhileOfflineServerOnly {
  518. FIRDocumentReference *doc = [self documentRef];
  519. // go offline for the rest of this test
  520. [self disableNetwork];
  521. // attempt to get doc. Currently, this is expected to fail. In the future, we
  522. // might consider adding support for negative cache hits so that we know
  523. // certain documents *don't* exist.
  524. XCTestExpectation *getNonExistingDocCompletion =
  525. [self expectationWithDescription:@"getNonExistingDoc"];
  526. [doc getDocumentWithSource:FIRFirestoreSourceServer
  527. completion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
  528. XCTAssertNotNil(error);
  529. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  530. XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
  531. [getNonExistingDocCompletion fulfill];
  532. }];
  533. [self awaitExpectations];
  534. }
  535. - (void)testGetNonExistingCollectionWhileOfflineServerOnly {
  536. FIRCollectionReference *col = [self collectionRef];
  537. // go offline for the rest of this test
  538. [self disableNetwork];
  539. // attempt to get collection and ensure that it cannot be retreived
  540. XCTestExpectation *failedGetDocsCompletion = [self expectationWithDescription:@"failedGetDocs"];
  541. [col getDocumentsWithSource:FIRFirestoreSourceServer
  542. completion:^(FIRQuerySnapshot *snapshot, NSError *error) {
  543. XCTAssertNotNil(error);
  544. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  545. XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
  546. [failedGetDocsCompletion fulfill];
  547. }];
  548. [self awaitExpectations];
  549. }
  550. @end