FSTEventManagerTests.mm 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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 "Firestore/Source/Core/FSTEventManager.h"
  17. #import <OCMock/OCMock.h>
  18. #import <XCTest/XCTest.h>
  19. #import "Firestore/Source/Core/FSTQuery.h"
  20. #import "Firestore/Source/Core/FSTSyncEngine.h"
  21. #import "Firestore/Source/Model/FSTDocumentSet.h"
  22. #import "Firestore/Source/Util/FSTDispatchQueue.h"
  23. #import "Firestore/Example/Tests/Util/FSTHelpers.h"
  24. NS_ASSUME_NONNULL_BEGIN
  25. // FSTEventManager implements this delegate privately
  26. @interface FSTEventManager () <FSTSyncEngineDelegate>
  27. @end
  28. @interface FSTEventManagerTests : XCTestCase
  29. @end
  30. @implementation FSTEventManagerTests {
  31. FSTDispatchQueue *_testUserQueue;
  32. }
  33. - (void)setUp {
  34. _testUserQueue = [FSTDispatchQueue queueWith:dispatch_get_main_queue()];
  35. }
  36. - (FSTQueryListener *)noopListenerForQuery:(FSTQuery *)query {
  37. return [[FSTQueryListener alloc]
  38. initWithQuery:query
  39. options:[FSTListenOptions defaultOptions]
  40. viewSnapshotHandler:^(FSTViewSnapshot *_Nullable snapshot, NSError *_Nullable error){
  41. }];
  42. }
  43. - (void)testHandlesManyListenersPerQuery {
  44. FSTQuery *query = FSTTestQuery("foo/bar");
  45. FSTQueryListener *listener1 = [self noopListenerForQuery:query];
  46. FSTQueryListener *listener2 = [self noopListenerForQuery:query];
  47. FSTSyncEngine *syncEngineMock = OCMStrictClassMock([FSTSyncEngine class]);
  48. OCMExpect([syncEngineMock setDelegate:[OCMArg any]]);
  49. FSTEventManager *eventManager = [FSTEventManager eventManagerWithSyncEngine:syncEngineMock];
  50. OCMExpect([syncEngineMock listenToQuery:query]);
  51. [eventManager addListener:listener1];
  52. OCMVerifyAll((id)syncEngineMock);
  53. [eventManager addListener:listener2];
  54. [eventManager removeListener:listener2];
  55. OCMExpect([syncEngineMock stopListeningToQuery:query]);
  56. [eventManager removeListener:listener1];
  57. OCMVerifyAll((id)syncEngineMock);
  58. }
  59. - (void)testHandlesUnlistenOnUnknownListenerGracefully {
  60. FSTQuery *query = FSTTestQuery("foo/bar");
  61. FSTQueryListener *listener = [self noopListenerForQuery:query];
  62. FSTSyncEngine *syncEngineMock = OCMStrictClassMock([FSTSyncEngine class]);
  63. OCMExpect([syncEngineMock setDelegate:[OCMArg any]]);
  64. FSTEventManager *eventManager = [FSTEventManager eventManagerWithSyncEngine:syncEngineMock];
  65. [eventManager removeListener:listener];
  66. OCMVerifyAll((id)syncEngineMock);
  67. }
  68. - (FSTQueryListener *)makeMockListenerForQuery:(FSTQuery *)query
  69. viewSnapshotHandler:(void (^)())handler {
  70. FSTQueryListener *listener = OCMClassMock([FSTQueryListener class]);
  71. OCMStub([listener query]).andReturn(query);
  72. OCMStub([listener queryDidChangeViewSnapshot:[OCMArg any]]).andDo(^(NSInvocation *invocation) {
  73. handler();
  74. });
  75. return listener;
  76. }
  77. - (void)testNotifiesListenersInTheRightOrder {
  78. FSTQuery *query1 = FSTTestQuery("foo/bar");
  79. FSTQuery *query2 = FSTTestQuery("bar/baz");
  80. NSMutableArray *eventOrder = [NSMutableArray array];
  81. FSTQueryListener *listener1 = [self makeMockListenerForQuery:query1
  82. viewSnapshotHandler:^{
  83. [eventOrder addObject:@"listener1"];
  84. }];
  85. FSTQueryListener *listener2 = [self makeMockListenerForQuery:query2
  86. viewSnapshotHandler:^{
  87. [eventOrder addObject:@"listener2"];
  88. }];
  89. FSTQueryListener *listener3 = [self makeMockListenerForQuery:query1
  90. viewSnapshotHandler:^{
  91. [eventOrder addObject:@"listener3"];
  92. }];
  93. FSTSyncEngine *syncEngineMock = OCMClassMock([FSTSyncEngine class]);
  94. FSTEventManager *eventManager = [FSTEventManager eventManagerWithSyncEngine:syncEngineMock];
  95. [eventManager addListener:listener1];
  96. [eventManager addListener:listener2];
  97. [eventManager addListener:listener3];
  98. OCMVerify([syncEngineMock listenToQuery:query1]);
  99. OCMVerify([syncEngineMock listenToQuery:query2]);
  100. FSTViewSnapshot *snapshot1 = OCMClassMock([FSTViewSnapshot class]);
  101. OCMStub([snapshot1 query]).andReturn(query1);
  102. FSTViewSnapshot *snapshot2 = OCMClassMock([FSTViewSnapshot class]);
  103. OCMStub([snapshot2 query]).andReturn(query2);
  104. [eventManager handleViewSnapshots:@[ snapshot1, snapshot2 ]];
  105. NSArray *expected = @[ @"listener1", @"listener3", @"listener2" ];
  106. XCTAssertEqualObjects(eventOrder, expected);
  107. }
  108. - (void)testWillForwardOnlineStateChanges {
  109. FSTQuery *query = FSTTestQuery("foo/bar");
  110. FSTQueryListener *fakeListener = OCMClassMock([FSTQueryListener class]);
  111. NSMutableArray *events = [NSMutableArray array];
  112. OCMStub([fakeListener query]).andReturn(query);
  113. OCMStub([fakeListener applyChangedOnlineState:FSTOnlineStateUnknown])
  114. .andDo(^(NSInvocation *invocation) {
  115. [events addObject:@(FSTOnlineStateUnknown)];
  116. });
  117. OCMStub([fakeListener applyChangedOnlineState:FSTOnlineStateOnline])
  118. .andDo(^(NSInvocation *invocation) {
  119. [events addObject:@(FSTOnlineStateOnline)];
  120. });
  121. FSTSyncEngine *syncEngineMock = OCMClassMock([FSTSyncEngine class]);
  122. OCMExpect([syncEngineMock setDelegate:[OCMArg any]]);
  123. FSTEventManager *eventManager = [FSTEventManager eventManagerWithSyncEngine:syncEngineMock];
  124. [eventManager addListener:fakeListener];
  125. XCTAssertEqualObjects(events, @[ @(FSTOnlineStateUnknown) ]);
  126. [eventManager applyChangedOnlineState:FSTOnlineStateOnline];
  127. XCTAssertEqualObjects(events, (@[ @(FSTOnlineStateUnknown), @(FSTOnlineStateOnline) ]));
  128. }
  129. @end
  130. NS_ASSUME_NONNULL_END