FOrder.m 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. /*
  2. * Copyright 2017 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 "FirebaseDatabase/Tests/Integration/FOrder.h"
  17. #import "FirebaseDatabase/Sources/Api/Private/FTypedefs_Private.h"
  18. #import "FirebaseDatabase/Sources/Public/FirebaseDatabase/FIRDatabaseReference.h"
  19. #import "FirebaseDatabase/Sources/Utilities/Tuples/FTupleFirebase.h"
  20. #import "FirebaseDatabase/Tests/Helpers/FEventTester.h"
  21. #import "FirebaseDatabase/Tests/Helpers/FTestHelpers.h"
  22. #import "FirebaseDatabase/Tests/Helpers/FTupleEventTypeString.h"
  23. @implementation FOrder
  24. - (void)testPushEnumerateAndCheckCorrectOrder {
  25. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  26. for (int i = 0; i < 10; i++) {
  27. [[node childByAutoId] setValue:[NSNumber numberWithInt:i]];
  28. }
  29. [super
  30. snapWaiter:node
  31. withBlock:^(FIRDataSnapshot *snapshot) {
  32. int expected = 0;
  33. for (FIRDataSnapshot *child in snapshot.children) {
  34. XCTAssertEqualObjects([NSNumber numberWithInt:expected], [child value],
  35. @"Expects values match.");
  36. expected = expected + 1;
  37. }
  38. XCTAssertTrue(expected == 10, @"Should get all of the children");
  39. XCTAssertTrue(expected == snapshot.childrenCount, @"Snapshot should report correct count");
  40. }];
  41. }
  42. - (void)testPushEnumerateManyPathsWriteAndCheckOrder {
  43. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  44. NSMutableArray *paths = [[NSMutableArray alloc] init];
  45. for (int i = 0; i < 20; i++) {
  46. [paths addObject:[node childByAutoId]];
  47. }
  48. for (int i = 0; i < 20; i++) {
  49. [(FIRDatabaseReference *)[paths objectAtIndex:i] setValue:[NSNumber numberWithInt:i]];
  50. }
  51. [super snapWaiter:node
  52. withBlock:^(FIRDataSnapshot *snap) {
  53. int expected = 0;
  54. for (FIRDataSnapshot *child in snap.children) {
  55. XCTAssertEqualObjects([NSNumber numberWithInt:expected], [child value],
  56. @"Expects values match.");
  57. expected = expected + 1;
  58. }
  59. XCTAssertTrue(expected == 20, @"Should get all of the children");
  60. XCTAssertTrue(expected == snap.childrenCount, @"Snapshot should report correct count");
  61. }];
  62. }
  63. - (void)testPushDataReconnectReadBackAndVerifyOrder {
  64. FTupleFirebase *tuple = [FTestHelpers getRandomNodePair];
  65. __block int expected = 0;
  66. __block int nodesSet = 0;
  67. FIRDatabaseReference *node = tuple.one;
  68. for (int i = 0; i < 10; i++) {
  69. [[node childByAutoId] setValue:[NSNumber numberWithInt:i]
  70. withCompletionBlock:^(NSError *err, FIRDatabaseReference *ref) {
  71. nodesSet++;
  72. }];
  73. }
  74. [self waitUntil:^BOOL {
  75. return nodesSet == 10;
  76. }];
  77. __block BOOL done = NO;
  78. [super snapWaiter:node
  79. withBlock:^(FIRDataSnapshot *snap) {
  80. expected = 0;
  81. //[snap forEach:^BOOL(FIRDataSnapshot *child) {
  82. for (FIRDataSnapshot *child in snap.children) {
  83. XCTAssertEqualObjects([NSNumber numberWithInt:expected], [child value],
  84. @"Expected child value");
  85. expected = expected + 1;
  86. // return NO;
  87. }
  88. done = YES;
  89. }];
  90. [self waitUntil:^BOOL {
  91. return done;
  92. }];
  93. done = NO;
  94. XCTAssertTrue(nodesSet == 10, @"All of the nodes have been set");
  95. [super
  96. snapWaiter:tuple.two
  97. withBlock:^(FIRDataSnapshot *snap) {
  98. expected = 0;
  99. for (FIRDataSnapshot *child in snap.children) {
  100. XCTAssertEqualObjects([NSNumber numberWithInt:expected], [child value],
  101. @"Expected child value");
  102. expected = expected + 1;
  103. }
  104. done = YES;
  105. XCTAssertTrue(expected == 10, @"Saw the expected number of children %d == 10", expected);
  106. }];
  107. }
  108. - (void)testPushDataWithPrioritiesReconnectReadBackAndVerifyOrder {
  109. FTupleFirebase *tuple = [FTestHelpers getRandomNodePair];
  110. __block int expected = 0;
  111. __block int nodesSet = 0;
  112. FIRDatabaseReference *node = tuple.one;
  113. for (int i = 0; i < 10; i++) {
  114. [[node childByAutoId] setValue:[NSNumber numberWithInt:i]
  115. andPriority:[NSNumber numberWithInt:(10 - i)]
  116. withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
  117. nodesSet = nodesSet + 1;
  118. }];
  119. }
  120. [super snapWaiter:node
  121. withBlock:^(FIRDataSnapshot *snap) {
  122. expected = 9;
  123. for (FIRDataSnapshot *child in snap.children) {
  124. XCTAssertEqualObjects([child value], [NSNumber numberWithInt:expected],
  125. @"Expected child value as per priority");
  126. expected = expected - 1;
  127. }
  128. XCTAssertTrue(expected == -1, @"Saw the expected number of children");
  129. }];
  130. [self waitUntil:^BOOL {
  131. return nodesSet == 10;
  132. }];
  133. XCTAssertTrue(nodesSet == 10, @"All of the nodes have been set");
  134. [super snapWaiter:tuple.two
  135. withBlock:^(FIRDataSnapshot *snap) {
  136. expected = 9;
  137. for (FIRDataSnapshot *child in snap.children) {
  138. XCTAssertEqualObjects([child value], [NSNumber numberWithInt:expected],
  139. @"Expected child value as per priority");
  140. expected = expected - 1;
  141. }
  142. XCTAssertTrue(expected == -1, @"Saw the expected number of children");
  143. }];
  144. }
  145. - (void)testPushDataWithExponentialPrioritiesReconnectReadBackAndVerifyOrder {
  146. FTupleFirebase *tuple = [FTestHelpers getRandomNodePair];
  147. __block int expected = 0;
  148. __block int nodesSet = 0;
  149. FIRDatabaseReference *node = tuple.one;
  150. for (int i = 0; i < 10; i++) {
  151. [[node childByAutoId] setValue:[NSNumber numberWithInt:i]
  152. andPriority:[NSNumber numberWithDouble:(111111111111111111111111111111.0 /
  153. pow(10, i))]
  154. withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
  155. nodesSet = nodesSet + 1;
  156. }];
  157. }
  158. [super snapWaiter:node
  159. withBlock:^(FIRDataSnapshot *snap) {
  160. expected = 9;
  161. for (FIRDataSnapshot *child in snap.children) {
  162. XCTAssertEqualObjects([child value], [NSNumber numberWithInt:expected],
  163. @"Expected child value as per priority");
  164. expected = expected - 1;
  165. }
  166. XCTAssertTrue(expected == -1, @"Saw the expected number of children");
  167. }];
  168. WAIT_FOR(nodesSet == 10);
  169. [super snapWaiter:tuple.two
  170. withBlock:^(FIRDataSnapshot *snap) {
  171. expected = 9;
  172. for (FIRDataSnapshot *child in snap.children) {
  173. XCTAssertEqualObjects([child value], [NSNumber numberWithInt:expected],
  174. @"Expected child value as per priority");
  175. expected = expected - 1;
  176. }
  177. XCTAssertTrue(expected == -1, @"Saw the expected number of children");
  178. }];
  179. }
  180. - (void)testThatNodesWithoutValuesAreNotEnumerated {
  181. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  182. [node child:@"foo"];
  183. [[node child:@"bar"] setValue:@"test"];
  184. __block int items = 0;
  185. [super snapWaiter:node
  186. withBlock:^(FIRDataSnapshot *snap) {
  187. for (FIRDataSnapshot *child in snap.children) {
  188. items = items + 1;
  189. XCTAssertEqualObjects([child key], @"bar",
  190. @"Saw the child which had a value set and not the empty one");
  191. }
  192. XCTAssertTrue(items == 1, @"Saw only the one that was actually set.");
  193. }];
  194. }
  195. - (void)testChildMovedEventWhenPriorityChanges {
  196. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  197. FEventTester *et = [[FEventTester alloc] initFrom:self];
  198. NSArray *expect = @[
  199. [[FTupleEventTypeString alloc] initWithFirebase:node
  200. withEvent:FIRDataEventTypeChildAdded
  201. withString:@"a"],
  202. [[FTupleEventTypeString alloc] initWithFirebase:node
  203. withEvent:FIRDataEventTypeValue
  204. withString:nil],
  205. [[FTupleEventTypeString alloc] initWithFirebase:node
  206. withEvent:FIRDataEventTypeChildAdded
  207. withString:@"b"],
  208. [[FTupleEventTypeString alloc] initWithFirebase:node
  209. withEvent:FIRDataEventTypeValue
  210. withString:nil],
  211. [[FTupleEventTypeString alloc] initWithFirebase:node
  212. withEvent:FIRDataEventTypeChildAdded
  213. withString:@"c"],
  214. [[FTupleEventTypeString alloc] initWithFirebase:node
  215. withEvent:FIRDataEventTypeValue
  216. withString:nil],
  217. [[FTupleEventTypeString alloc] initWithFirebase:node
  218. withEvent:FIRDataEventTypeChildMoved
  219. withString:@"a"],
  220. [[FTupleEventTypeString alloc] initWithFirebase:node
  221. withEvent:FIRDataEventTypeChildChanged
  222. withString:@"a"],
  223. [[FTupleEventTypeString alloc] initWithFirebase:node
  224. withEvent:FIRDataEventTypeValue
  225. withString:nil]
  226. ];
  227. [et addLookingFor:expect];
  228. [et waitForInitialization];
  229. [[node child:@"a"] setValue:@"first" andPriority:@1];
  230. [[node child:@"b"] setValue:@"second" andPriority:@2];
  231. [[node child:@"c"] setValue:@"third" andPriority:@3];
  232. [[node child:@"a"] setPriority:@15];
  233. [et wait];
  234. }
  235. - (void)testCanResetPriorityToNull {
  236. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  237. [[node child:@"a"] setValue:@"a" andPriority:@1];
  238. [[node child:@"b"] setValue:@"b" andPriority:@2];
  239. FEventTester *et = [[FEventTester alloc] initFrom:self];
  240. NSArray *expect = @[
  241. [[FTupleEventTypeString alloc] initWithFirebase:node
  242. withEvent:FIRDataEventTypeChildAdded
  243. withString:@"a"],
  244. [[FTupleEventTypeString alloc] initWithFirebase:node
  245. withEvent:FIRDataEventTypeChildAdded
  246. withString:@"b"],
  247. [[FTupleEventTypeString alloc] initWithFirebase:node
  248. withEvent:FIRDataEventTypeValue
  249. withString:nil]
  250. ];
  251. [et addLookingFor:expect];
  252. [et wait];
  253. expect = @[
  254. [[FTupleEventTypeString alloc] initWithFirebase:node
  255. withEvent:FIRDataEventTypeChildMoved
  256. withString:@"b"],
  257. [[FTupleEventTypeString alloc] initWithFirebase:node
  258. withEvent:FIRDataEventTypeChildChanged
  259. withString:@"b"],
  260. [[FTupleEventTypeString alloc] initWithFirebase:node
  261. withEvent:FIRDataEventTypeValue
  262. withString:nil]
  263. ];
  264. [et addLookingFor:expect];
  265. [[node child:@"b"] setPriority:nil];
  266. [et wait];
  267. __block BOOL ready = NO;
  268. [[node child:@"b"]
  269. observeSingleEventOfType:FIRDataEventTypeValue
  270. withBlock:^(FIRDataSnapshot *snapshot) {
  271. XCTAssertTrue([snapshot priority] == [NSNull null], @"Should be null");
  272. ready = YES;
  273. }];
  274. [self waitUntil:^BOOL {
  275. return ready;
  276. }];
  277. }
  278. - (void)testInsertingANodeUnderALeafPreservesItsPriority {
  279. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  280. __block FIRDataSnapshot *snap;
  281. [node observeEventType:FIRDataEventTypeValue
  282. withBlock:^(FIRDataSnapshot *s) {
  283. snap = s;
  284. }];
  285. [node setValue:@"a" andPriority:@10];
  286. [[node child:@"deeper"] setValue:@"deeper"];
  287. [self waitUntil:^BOOL {
  288. id result = [snap value];
  289. NSDictionary *expected = @{@"deeper" : @"deeper"};
  290. return snap != nil && [result isKindOfClass:[NSDictionary class]] &&
  291. [result isEqualToDictionary:expected];
  292. }];
  293. XCTAssertEqualObjects([snap priority], @10, @"Proper value");
  294. }
  295. - (void)testVerifyOrderOfMixedNumbersStringNoPriorities {
  296. FTupleFirebase *tuple = [FTestHelpers getRandomNodePair];
  297. NSArray *nodeAndPriorities = @[
  298. @"alpha42", @"zed", @"noPriorityC", [NSNull null], @"num41", @500,
  299. @"noPriorityB", [NSNull null], @"num80", @4000.1, @"num50", @4000,
  300. @"num10", @24, @"alpha41", @"zed", @"alpha20", @"horse",
  301. @"num20", @123, @"num70", @4000.01, @"noPriorityA", [NSNull null],
  302. @"alpha30", @"tree", @"num30", @300, @"num60", @4000.001,
  303. @"alpha10", @"0horse", @"num42", @500, @"alpha40", @"zed",
  304. @"num40", @500
  305. ];
  306. __block int setsCompleted = 0;
  307. for (int i = 0; i < [nodeAndPriorities count]; i++) {
  308. FIRDatabaseReference *n = [tuple.one child:[nodeAndPriorities objectAtIndex:i++]];
  309. [n setValue:@1
  310. andPriority:[nodeAndPriorities objectAtIndex:i]
  311. withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
  312. setsCompleted = setsCompleted + 1;
  313. }];
  314. }
  315. NSString *expected =
  316. @"noPriorityA, noPriorityB, noPriorityC, num10, num20, num30, num40, num41, num42, num50, "
  317. @"num60, num70, num80, alpha10, alpha20, alpha30, alpha40, alpha41, alpha42, ";
  318. [super snapWaiter:tuple.one
  319. withBlock:^(FIRDataSnapshot *snap) {
  320. NSMutableString *output = [[NSMutableString alloc] init];
  321. for (FIRDataSnapshot *n in snap.children) {
  322. [output appendFormat:@"%@, ", [n key]];
  323. }
  324. XCTAssertTrue([expected isEqualToString:output], @"Proper order");
  325. }];
  326. WAIT_FOR(setsCompleted == [nodeAndPriorities count] / 2);
  327. [super snapWaiter:tuple.two
  328. withBlock:^(FIRDataSnapshot *snap) {
  329. NSMutableString *output = [[NSMutableString alloc] init];
  330. for (FIRDataSnapshot *n in snap.children) {
  331. [output appendFormat:@"%@, ", [n key]];
  332. }
  333. XCTAssertTrue([expected isEqualToString:output], @"Proper order");
  334. }];
  335. }
  336. - (void)testVerifyOrderOfIntegerNames {
  337. FIRDatabaseReference *ref = [FTestHelpers getRandomNode];
  338. NSArray *keys = @[ @"foo", @"bar", @"03", @"0", @"100", @"20", @"5", @"3", @"003", @"9" ];
  339. __block int setsCompleted = 0;
  340. for (int i = 0; i < [keys count]; i++) {
  341. FIRDatabaseReference *n = [ref child:[keys objectAtIndex:i]];
  342. [n setValue:@1
  343. withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
  344. setsCompleted = setsCompleted + 1;
  345. }];
  346. }
  347. NSString *expected = @"0, 3, 03, 003, 5, 9, 20, 100, bar, foo, ";
  348. [super snapWaiter:ref
  349. withBlock:^(FIRDataSnapshot *snap) {
  350. NSMutableString *output = [[NSMutableString alloc] init];
  351. for (FIRDataSnapshot *n in snap.children) {
  352. [output appendFormat:@"%@, ", [n key]];
  353. }
  354. XCTAssertTrue([expected isEqualToString:output], @"Proper order");
  355. }];
  356. }
  357. - (void)testPrevNameIsCorrectOnChildAddedEvent {
  358. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  359. [node setValue:@{@"a" : @1, @"b" : @2, @"c" : @3}];
  360. NSMutableString *added = [[NSMutableString alloc] init];
  361. __block int count = 0;
  362. [node observeEventType:FIRDataEventTypeChildAdded
  363. andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *snap, NSString *prevName) {
  364. [added appendFormat:@"%@ %@, ", [snap key], prevName];
  365. count++;
  366. }];
  367. [self waitUntil:^BOOL {
  368. return count == 3;
  369. }];
  370. XCTAssertTrue([added isEqualToString:@"a (null), b a, c b, "], @"Proper order and prevname");
  371. }
  372. - (void)testPrevNameIsCorrectWhenAddingNewNodes {
  373. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  374. [node setValue:@{@"b" : @2, @"c" : @3, @"d" : @4}];
  375. NSMutableString *added = [[NSMutableString alloc] init];
  376. __block int count = 0;
  377. [node observeEventType:FIRDataEventTypeChildAdded
  378. andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *snap, NSString *prevName) {
  379. [added appendFormat:@"%@ %@, ", [snap key], prevName];
  380. count++;
  381. }];
  382. [self waitUntil:^BOOL {
  383. return count == 3;
  384. }];
  385. XCTAssertTrue([added isEqualToString:@"b (null), c b, d c, "], @"Proper order and prevname");
  386. [added setString:@""];
  387. [[node child:@"a"] setValue:@1];
  388. [self waitUntil:^BOOL {
  389. return count == 4;
  390. }];
  391. XCTAssertTrue([added isEqualToString:@"a (null), "], @"Proper insertion of new node");
  392. [added setString:@""];
  393. [[node child:@"e"] setValue:@5];
  394. [self waitUntil:^BOOL {
  395. return count == 5;
  396. }];
  397. XCTAssertTrue([added isEqualToString:@"e d, "], @"Proper insertion of new node");
  398. }
  399. - (void)testPrevNameIsCorrectWhenAddingNewNodesWithJSON {
  400. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  401. [node setValue:@{@"b" : @2, @"c" : @3, @"d" : @4}];
  402. NSMutableString *added = [[NSMutableString alloc] init];
  403. __block int count = 0;
  404. [node observeEventType:FIRDataEventTypeChildAdded
  405. andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *snap, NSString *prevName) {
  406. [added appendFormat:@"%@ %@, ", [snap key], prevName];
  407. count++;
  408. }];
  409. [self waitUntil:^BOOL {
  410. return count == 3;
  411. }];
  412. XCTAssertTrue([added isEqualToString:@"b (null), c b, d c, "], @"Proper order and prevname");
  413. [added setString:@""];
  414. [node setValue:@{@"a" : @1, @"b" : @2, @"c" : @3, @"d" : @4}];
  415. [self waitUntil:^BOOL {
  416. return count == 4;
  417. }];
  418. XCTAssertTrue([added isEqualToString:@"a (null), "], @"Proper insertion of new node");
  419. [added setString:@""];
  420. [node setValue:@{@"a" : @1, @"b" : @2, @"c" : @3, @"d" : @4, @"e" : @5}];
  421. [self waitUntil:^BOOL {
  422. return count == 5;
  423. }];
  424. XCTAssertTrue([added isEqualToString:@"e d, "], @"Proper insertion of new node");
  425. }
  426. - (void)testPrevNameIsCorrectWhenMovingNodes {
  427. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  428. NSMutableString *moved = [[NSMutableString alloc] init];
  429. __block int count = 0;
  430. [node observeEventType:FIRDataEventTypeChildMoved
  431. andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *snapshot, NSString *prevName) {
  432. [moved appendFormat:@"%@ %@, ", snapshot.key, prevName];
  433. count++;
  434. }];
  435. [[node child:@"a"] setValue:@"a" andPriority:@1];
  436. [[node child:@"b"] setValue:@"a" andPriority:@2];
  437. [[node child:@"c"] setValue:@"a" andPriority:@3];
  438. [[node child:@"d"] setValue:@"a" andPriority:@4];
  439. [[node child:@"d"] setPriority:@0];
  440. [self waitUntil:^BOOL {
  441. return count == 1;
  442. }];
  443. XCTAssertTrue([moved isEqualToString:@"d (null), "], @"Got first move");
  444. [moved setString:@""];
  445. [[node child:@"a"] setPriority:@4];
  446. [self waitUntil:^BOOL {
  447. return count == 2;
  448. }];
  449. XCTAssertTrue([moved isEqualToString:@"a c, "], @"Got second move");
  450. [moved setString:@""];
  451. [[node child:@"c"] setPriority:@0.5];
  452. [self waitUntil:^BOOL {
  453. return count == 3;
  454. }];
  455. XCTAssertTrue([moved isEqualToString:@"c d, "], @"Got third move");
  456. }
  457. - (void)testPrevNameIsCorrectWhenSettingWholeJsonDict {
  458. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  459. NSMutableString *moved = [[NSMutableString alloc] init];
  460. __block int count = 0;
  461. [node observeEventType:FIRDataEventTypeChildMoved
  462. andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *snapshot, NSString *prevName) {
  463. [moved appendFormat:@"%@ %@, ", snapshot.key, prevName];
  464. count++;
  465. }];
  466. [node setValue:@{
  467. @"a" : @{@".value" : @"a", @".priority" : @1},
  468. @"b" : @{@".value" : @"b", @".priority" : @2},
  469. @"c" : @{@".value" : @"c", @".priority" : @3},
  470. @"d" : @{@".value" : @"d", @".priority" : @4}
  471. }];
  472. [node setValue:@{
  473. @"d" : @{@".value" : @"d", @".priority" : @0},
  474. @"a" : @{@".value" : @"a", @".priority" : @1},
  475. @"b" : @{@".value" : @"b", @".priority" : @2},
  476. @"c" : @{@".value" : @"c", @".priority" : @3}
  477. }];
  478. [self waitUntil:^BOOL {
  479. return count == 1;
  480. }];
  481. XCTAssertTrue([moved isEqualToString:@"d (null), "], @"Got move");
  482. [moved setString:@""];
  483. [node setValue:@{
  484. @"d" : @{@".value" : @"d", @".priority" : @0},
  485. @"b" : @{@".value" : @"b", @".priority" : @2},
  486. @"c" : @{@".value" : @"c", @".priority" : @3},
  487. @"a" : @{@".value" : @"a", @".priority" : @4}
  488. }];
  489. [self waitUntil:^BOOL {
  490. return count == 2;
  491. }];
  492. XCTAssertTrue([moved isEqualToString:@"a c, "], @"Got move");
  493. [moved setString:@""];
  494. [node setValue:@{
  495. @"d" : @{@".value" : @"d", @".priority" : @0},
  496. @"c" : @{@".value" : @"c", @".priority" : @0.5},
  497. @"b" : @{@".value" : @"b", @".priority" : @2},
  498. @"a" : @{@".value" : @"a", @".priority" : @4}
  499. }];
  500. [self waitUntil:^BOOL {
  501. return count == 3;
  502. }];
  503. XCTAssertTrue([moved isEqualToString:@"c d, "], @"Got move");
  504. }
  505. - (void)testCase595NoChildMovedEventWhenDeletingPrioritizedGrandchild {
  506. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  507. __block int moves = 0;
  508. [node observeEventType:FIRDataEventTypeChildMoved
  509. withBlock:^(FIRDataSnapshot *snapshot) {
  510. moves++;
  511. }];
  512. __block BOOL ready = NO;
  513. [[node child:@"test/foo"] setValue:@42 andPriority:@"5"];
  514. [[node child:@"test/foo2"] setValue:@42 andPriority:@"10"];
  515. [[node child:@"test/foo"] removeValue];
  516. [[node child:@"test/foo"]
  517. removeValueWithCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
  518. ready = YES;
  519. }];
  520. [self waitUntil:^BOOL {
  521. return ready;
  522. }];
  523. XCTAssertTrue(moves == 0, @"Nothing should have moved");
  524. }
  525. - (void)testCanSetAValueWithPriZero {
  526. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  527. __block FIRDataSnapshot *snap = nil;
  528. [node observeEventType:FIRDataEventTypeValue
  529. withBlock:^(FIRDataSnapshot *s) {
  530. snap = s;
  531. }];
  532. [node setValue:@"test" andPriority:@0];
  533. [self waitUntil:^BOOL {
  534. return snap != nil;
  535. }];
  536. XCTAssertEqualObjects([snap value], @"test", @"Proper value");
  537. XCTAssertEqualObjects([snap priority], @0, @"Proper value");
  538. }
  539. - (void)testCanSetObjectWithPriZero {
  540. FIRDatabaseReference *node = [FTestHelpers getRandomNode];
  541. __block FIRDataSnapshot *snap = nil;
  542. [node observeEventType:FIRDataEventTypeValue
  543. withBlock:^(FIRDataSnapshot *s) {
  544. snap = s;
  545. }];
  546. [node setValue:@{@"x" : @"test", @"y" : @7} andPriority:@0];
  547. [self waitUntil:^BOOL {
  548. return snap != nil;
  549. }];
  550. XCTAssertEqualObjects([[snap value] objectForKey:@"x"], @"test", @"Proper value");
  551. XCTAssertEqualObjects([[snap value] objectForKey:@"y"], @7, @"Proper value");
  552. XCTAssertEqualObjects([snap priority], @0, @"Proper value");
  553. }
  554. @end