FOrder.m 22 KB

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