FIRMessagingServiceTest.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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 <UIKit/UIKit.h>
  17. #import <XCTest/XCTest.h>
  18. #import <OCMock/OCMock.h>
  19. #import "FIRMessaging.h"
  20. #import "FIRMessagingClient.h"
  21. #import "FIRMessagingPubSub.h"
  22. #import "FIRMessagingTopicsCommon.h"
  23. #import "InternalHeaders/FIRMessagingInternalUtilities.h"
  24. #import "NSError+FIRMessaging.h"
  25. static NSString *const kFakeToken =
  26. @"fE1e1PZJFSQ:APA91bFAOjp1ahBWn9rTlbjArwBEm_"
  27. @"yUTTzK6dhIvLqzqqCSabaa4TQVM0pGTmF6r7tmMHPe6VYiGMHuCwJFgj5v97xl78sUNMLwuPPhoci8z_"
  28. @"QGlCrTbxCFGzEUfvA3fGpGgIVQU2W6";
  29. @interface FIRMessaging () <FIRMessagingClientDelegate>
  30. @property(nonatomic, readwrite, strong) FIRMessagingClient *client;
  31. @property(nonatomic, readwrite, strong) FIRMessagingPubSub *pubsub;
  32. @property(nonatomic, readwrite, strong) NSString *defaultFcmToken;
  33. @end
  34. @interface FIRMessagingPubSub ()
  35. @property(nonatomic, readwrite, strong) FIRMessagingClient *client;
  36. @end
  37. @interface FIRMessagingServiceTest : XCTestCase {
  38. FIRMessaging *_messaging;
  39. id _mockPubSub;
  40. }
  41. @end
  42. @implementation FIRMessagingServiceTest
  43. - (void)setUp {
  44. _messaging = [FIRMessaging messaging];
  45. _messaging.defaultFcmToken = kFakeToken;
  46. _mockPubSub = OCMPartialMock(_messaging.pubsub);
  47. [super setUp];
  48. }
  49. - (void)tearDown {
  50. [_mockPubSub stopMocking];
  51. [super tearDown];
  52. }
  53. - (void)testSubscribe {
  54. id mockClient = OCMClassMock([FIRMessagingClient class]);
  55. [_messaging setClient:mockClient];
  56. [_mockPubSub setClient:mockClient];
  57. XCTestExpectation *subscribeExpectation =
  58. [self expectationWithDescription:@"Should call subscribe on FIRMessagingClient"];
  59. NSString *token = kFakeToken;
  60. NSString *topic = @"/topics/some-random-topic";
  61. [[[mockClient stub]
  62. andDo:^(NSInvocation *invocation) {
  63. [subscribeExpectation fulfill];
  64. }]
  65. updateSubscriptionWithToken:token
  66. topic:topic
  67. options:OCMOCK_ANY
  68. shouldDelete:NO
  69. handler:OCMOCK_ANY];
  70. [_mockPubSub subscribeWithToken:token
  71. topic:topic
  72. options:nil
  73. handler:^(NSError *error){
  74. // not a nil block
  75. }];
  76. // should call updateSubscription
  77. [self waitForExpectationsWithTimeout:0.1
  78. handler:^(NSError *error) {
  79. XCTAssertNil(error);
  80. [mockClient verify];
  81. }];
  82. }
  83. - (void)testUnsubscribe {
  84. id mockClient = OCMClassMock([FIRMessagingClient class]);
  85. [_messaging setClient:mockClient];
  86. [_mockPubSub setClient:mockClient];
  87. XCTestExpectation *subscribeExpectation =
  88. [self expectationWithDescription:@"Should call unsubscribe on FIRMessagingClient"];
  89. NSString *token = kFakeToken;
  90. NSString *topic = @"/topics/some-random-topic";
  91. [[[mockClient stub] andDo:^(NSInvocation *invocation) {
  92. [subscribeExpectation fulfill];
  93. }]
  94. updateSubscriptionWithToken:[OCMArg isEqual:token]
  95. topic:[OCMArg isEqual:topic]
  96. options:[OCMArg checkWithBlock:^BOOL(id obj) {
  97. if ([obj isKindOfClass:[NSDictionary class]]) {
  98. return [(NSDictionary *)obj count] == 0;
  99. }
  100. return NO;
  101. }]
  102. shouldDelete:YES
  103. handler:OCMOCK_ANY];
  104. [_mockPubSub unsubscribeWithToken:token
  105. topic:topic
  106. options:nil
  107. handler:^(NSError *error){
  108. }];
  109. // should call updateSubscription
  110. [self waitForExpectationsWithTimeout:0.1
  111. handler:^(NSError *error) {
  112. XCTAssertNil(error);
  113. [mockClient verify];
  114. }];
  115. }
  116. /**
  117. * Test using PubSub without explicitly starting FIRMessagingService.
  118. */
  119. - (void)testSubscribeWithoutStart {
  120. [_mockPubSub
  121. subscribeWithToken:kFakeToken
  122. topic:@"/topics/hello-world"
  123. options:nil
  124. handler:^(NSError *error) {
  125. XCTAssertNil(error);
  126. XCTAssertEqual(kFIRMessagingErrorCodePubSubFIRMessagingNotSetup, error.code);
  127. }];
  128. }
  129. // TODO(chliangGoogle) Investigate why invalid token can't throw assertion but the rest can under
  130. // release build.
  131. - (void)testSubscribeWithInvalidTopic {
  132. XCTestExpectation *exceptionExpectation =
  133. [self expectationWithDescription:@"Should throw exception for invalid token"];
  134. @try {
  135. #pragma clang diagnostic push
  136. #pragma clang diagnostic ignored "-Wnonnull"
  137. [_mockPubSub subscribeWithToken:kFakeToken
  138. topic:nil
  139. options:nil
  140. handler:^(NSError *error) {
  141. XCTFail(@"Should not invoke the handler");
  142. }];
  143. #pragma clang diagnostic pop
  144. }
  145. @catch (NSException *exception) {
  146. [exceptionExpectation fulfill];
  147. }
  148. @finally {
  149. [self waitForExpectationsWithTimeout:0.1 handler:^(NSError *error) {
  150. XCTAssertNil(error);
  151. }];
  152. }
  153. }
  154. - (void)testUnsubscribeWithInvalidTopic {
  155. XCTestExpectation *exceptionExpectation =
  156. [self expectationWithDescription:@"Should throw exception for invalid token"];
  157. @try {
  158. #pragma clang diagnostic push
  159. #pragma clang diagnostic ignored "-Wnonnull"
  160. [_mockPubSub unsubscribeWithToken:kFakeToken
  161. topic:nil
  162. options:nil
  163. handler:^(NSError *error) {
  164. XCTFail(@"Should not invoke the handler");
  165. }];
  166. #pragma clang diagnostic pop
  167. }
  168. @catch (NSException *exception) {
  169. [exceptionExpectation fulfill];
  170. }
  171. @finally {
  172. [self waitForExpectationsWithTimeout:0.1 handler:^(NSError *error) {
  173. XCTAssertNil(error);
  174. }];
  175. }
  176. }
  177. - (void)testSubscribeWithNoTopicPrefix {
  178. NSString *topicName = @"topicWithoutPrefix";
  179. NSString *topicNameWithPrefix = [FIRMessagingPubSub addPrefixToTopic:topicName];
  180. OCMExpect(
  181. [_mockPubSub subscribeToTopic:[OCMArg isEqual:topicNameWithPrefix] handler:[OCMArg any]]);
  182. [_messaging subscribeToTopic:topicName];
  183. OCMVerifyAll(_mockPubSub);
  184. }
  185. - (void)testSubscribeWithTopicPrefix {
  186. NSString *topicName = @"/topics/topicWithoutPrefix";
  187. OCMExpect([_mockPubSub subscribeToTopic:[OCMArg isEqual:topicName] handler:[OCMArg any]]);
  188. [_messaging subscribeToTopic:topicName];
  189. OCMVerifyAll(_mockPubSub);
  190. }
  191. - (void)testUnsubscribeWithNoTopicPrefix {
  192. NSString *topicName = @"topicWithoutPrefix";
  193. NSString *topicNameWithPrefix = [FIRMessagingPubSub addPrefixToTopic:topicName];
  194. OCMExpect(
  195. [_mockPubSub unsubscribeFromTopic:[OCMArg isEqual:topicNameWithPrefix] handler:[OCMArg any]]);
  196. [_messaging unsubscribeFromTopic:topicName];
  197. OCMVerifyAll(_mockPubSub);
  198. }
  199. - (void)testUnsubscribeWithTopicPrefix {
  200. NSString *topicName = @"/topics/topicWithPrefix";
  201. OCMExpect([_mockPubSub unsubscribeFromTopic:[OCMArg isEqual:topicName] handler:[OCMArg any]]);
  202. [_messaging unsubscribeFromTopic:topicName];
  203. OCMVerifyAll(_mockPubSub);
  204. }
  205. - (void)testSubscriptionCompletionHandlerWithSuccess {
  206. OCMStub([_mockPubSub subscribeToTopic:[OCMArg any]
  207. handler:([OCMArg invokeBlockWithArgs:[NSNull null], nil])]);
  208. XCTestExpectation *subscriptionCompletionExpectation =
  209. [self expectationWithDescription:@"Subscription is complete"];
  210. [_messaging subscribeToTopic:@"news"
  211. completion:^(NSError *error) {
  212. XCTAssertNil(error);
  213. [subscriptionCompletionExpectation fulfill];
  214. }];
  215. [self waitForExpectationsWithTimeout:0.2
  216. handler:^(NSError *_Nullable error){
  217. }];
  218. }
  219. - (void)testUnsubscribeCompletionHandlerWithSuccess {
  220. OCMStub([_mockPubSub unsubscribeFromTopic:[OCMArg any]
  221. handler:([OCMArg invokeBlockWithArgs:[NSNull null], nil])]);
  222. XCTestExpectation *unsubscriptionCompletionExpectation =
  223. [self expectationWithDescription:@"Unsubscription is complete"];
  224. [_messaging unsubscribeFromTopic:@"news"
  225. completion:^(NSError *_Nullable error) {
  226. XCTAssertNil(error);
  227. [unsubscriptionCompletionExpectation fulfill];
  228. }];
  229. [self waitForExpectationsWithTimeout:0.2
  230. handler:^(NSError *_Nullable error){
  231. }];
  232. }
  233. - (void)testFIRMessagingSDKVersionInFIRMessagingService {
  234. Class versionClass = NSClassFromString(kFIRMessagingSDKClassString);
  235. SEL versionSelector = NSSelectorFromString(kFIRMessagingSDKVersionSelectorString);
  236. if ([versionClass respondsToSelector:versionSelector]) {
  237. #pragma clang diagnostic push
  238. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  239. id versionString = [versionClass performSelector:versionSelector];
  240. #pragma clang diagnostic pop
  241. XCTAssertTrue([versionString isKindOfClass:[NSString class]]);
  242. } else {
  243. XCTFail("%@ does not respond to selector %@",
  244. kFIRMessagingSDKClassString, kFIRMessagingSDKVersionSelectorString);
  245. }
  246. }
  247. - (void)testFIRMessagingSDKLocaleInFIRMessagingService {
  248. Class klass = NSClassFromString(kFIRMessagingSDKClassString);
  249. SEL localeSelector = NSSelectorFromString(kFIRMessagingSDKLocaleSelectorString);
  250. if ([klass respondsToSelector:localeSelector]) {
  251. #pragma clang diagnostic push
  252. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  253. id locale = [klass performSelector:localeSelector];
  254. #pragma clang diagnostic pop
  255. XCTAssertTrue([locale isKindOfClass:[NSString class]]);
  256. XCTAssertNotNil(locale);
  257. } else {
  258. XCTFail("%@ does not respond to selector %@",
  259. kFIRMessagingSDKClassString, kFIRMessagingSDKLocaleSelectorString);
  260. }
  261. }
  262. @end