FIRMessagingServiceTest.m 12 KB

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