FIRAuthNotificationManagerTests.m 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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 <TargetConditionals.h>
  17. #if TARGET_OS_IOS
  18. #import <XCTest/XCTest.h>
  19. #import "OCMock.h"
  20. #import "FirebaseAuth/Sources/SystemService/FIRAuthAppCredential.h"
  21. #import "FirebaseAuth/Sources/SystemService/FIRAuthAppCredentialManager.h"
  22. #import "FirebaseAuth/Sources/SystemService/FIRAuthNotificationManager.h"
  23. NS_ASSUME_NONNULL_BEGIN
  24. /** @var kReceipt
  25. @brief A fake receipt used for testing.
  26. */
  27. static NSString *const kReceipt = @"FAKE_RECEIPT";
  28. /** @var kSecret
  29. @brief A fake secret used for testing.
  30. */
  31. static NSString *const kSecret = @"FAKE_SECRET";
  32. /** @class FIRAuthFakeForwardingDelegate
  33. @brief The base class for a fake UIApplicationDelegate that forwards remote notifications.
  34. */
  35. @interface FIRAuthFakeForwardingDelegate : NSObject <UIApplicationDelegate>
  36. /** @property notificationManager
  37. @brief The notification manager to forward.
  38. */
  39. @property(nonatomic, strong) FIRAuthNotificationManager *notificationManager;
  40. /** @property forwardsNotification
  41. @brief Whether notifications are being forwarded.
  42. */
  43. @property(nonatomic, assign) BOOL forwardsNotification;
  44. /** @property notificationReceived
  45. @brief Whether a notification has been received.
  46. */
  47. @property(nonatomic, assign) BOOL notificationReceived;
  48. /** @property notificationhandled
  49. @brief Whether a notification has been handled.
  50. */
  51. @property(nonatomic, assign) BOOL notificationhandled;
  52. @end
  53. @implementation FIRAuthFakeForwardingDelegate
  54. @end
  55. /** @class FIRAuthFakeForwardingDelegate
  56. @brief A fake UIApplicationDelegate that implements the modern deegate method to receive
  57. notification.
  58. */
  59. @interface FIRAuthModernForwardingDelegate : FIRAuthFakeForwardingDelegate
  60. @end
  61. @implementation FIRAuthModernForwardingDelegate
  62. - (void)application:(UIApplication *)application
  63. didReceiveRemoteNotification:(NSDictionary *)userInfo
  64. fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  65. self.notificationReceived = YES;
  66. if (self.forwardsNotification) {
  67. self.notificationhandled = [self.notificationManager canHandleNotification:userInfo];
  68. }
  69. }
  70. @end
  71. /** @class FIRAuthNotificationManagerTests
  72. @brief Unit tests for @c FIRAuthNotificationManager .
  73. */
  74. @interface FIRAuthNotificationManagerTests : XCTestCase
  75. @end
  76. @implementation FIRAuthNotificationManagerTests {
  77. /** @var _mockApplication
  78. @brief The mock UIApplication for testing.
  79. */
  80. id _mockApplication;
  81. /** @var _mockAppCredentialManager
  82. @brief The mock FIRAuthAppCredentialManager for testing.
  83. */
  84. id _mockAppCredentialManager;
  85. /** @var _notificationManager
  86. @brief The FIRAuthNotificationManager to be tested.
  87. */
  88. FIRAuthNotificationManager *_notificationManager;
  89. /** @var _modernDelegate
  90. @brief The modern fake UIApplicationDelegate for testing.
  91. */
  92. FIRAuthModernForwardingDelegate *_modernDelegate;
  93. }
  94. - (void)setUp {
  95. _mockApplication = OCMClassMock([UIApplication class]);
  96. _mockAppCredentialManager = OCMClassMock([FIRAuthAppCredentialManager class]);
  97. _notificationManager =
  98. [[FIRAuthNotificationManager alloc] initWithApplication:_mockApplication
  99. appCredentialManager:_mockAppCredentialManager];
  100. _modernDelegate = [[FIRAuthModernForwardingDelegate alloc] init];
  101. _modernDelegate.notificationManager = _notificationManager;
  102. }
  103. /** @fn testForwardingModernDelegate
  104. @brief Tests checking notification forwarding on modern fake delegate.
  105. */
  106. - (void)testForwardingModernDelegate {
  107. [self verifyForwarding:YES delegate:_modernDelegate];
  108. }
  109. /** @fn testNotForwardingModernDelegate
  110. @brief Tests checking notification not forwarding on modern fake delegate.
  111. */
  112. - (void)testNotForwardingModernDelegate {
  113. [self verifyForwarding:NO delegate:_modernDelegate];
  114. }
  115. /** @fn verifyForwarding:delegate:
  116. @brief Tests checking notification forwarding on a particular delegate.
  117. @param forwarding Whether the notification is being forwarded or not.
  118. @param delegate The fake UIApplicationDelegate used for testing.
  119. */
  120. - (void)verifyForwarding:(BOOL)forwarding delegate:(FIRAuthFakeForwardingDelegate *)delegate {
  121. delegate.forwardsNotification = forwarding;
  122. OCMStub([_mockApplication delegate]).andReturn(delegate);
  123. XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
  124. [_notificationManager
  125. checkNotificationForwardingWithCallback:^(BOOL isNotificationBeingForwarded) {
  126. XCTAssertEqual(isNotificationBeingForwarded, forwarding);
  127. [expectation fulfill];
  128. }];
  129. XCTAssertFalse(delegate.notificationReceived);
  130. NSTimeInterval timeout = _notificationManager.timeout * (1.5 - forwarding);
  131. [self waitForExpectationsWithTimeout:timeout handler:nil];
  132. XCTAssertTrue(delegate.notificationReceived);
  133. XCTAssertEqual(delegate.notificationhandled, forwarding);
  134. }
  135. /** @fn testCachedResult
  136. @brief Test notification forwarding is only checked once.
  137. */
  138. - (void)testCachedResult {
  139. FIRAuthFakeForwardingDelegate *delegate = _modernDelegate;
  140. [self verifyForwarding:NO delegate:delegate];
  141. delegate.notificationReceived = NO;
  142. __block BOOL calledBack = NO;
  143. [_notificationManager
  144. checkNotificationForwardingWithCallback:^(BOOL isNotificationBeingForwarded) {
  145. XCTAssertFalse(isNotificationBeingForwarded);
  146. calledBack = YES;
  147. }];
  148. XCTAssertTrue(calledBack);
  149. XCTAssertFalse(delegate.notificationReceived);
  150. }
  151. /** @fn testPassingToCredentialManager
  152. @brief Test notification with the right structure is passed to credential manager.
  153. */
  154. - (void)testPassingToCredentialManager {
  155. NSDictionary *payload = @{@"receipt" : kReceipt, @"secret" : kSecret};
  156. NSDictionary *notification = @{@"com.google.firebase.auth" : payload};
  157. OCMExpect([_mockAppCredentialManager canFinishVerificationWithReceipt:kReceipt secret:kSecret])
  158. .andReturn(YES);
  159. XCTAssertTrue([_notificationManager canHandleNotification:notification]);
  160. OCMVerifyAll(_mockAppCredentialManager);
  161. // JSON string form
  162. NSData *data = [NSJSONSerialization dataWithJSONObject:payload options:0 error:NULL];
  163. NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  164. notification = @{@"com.google.firebase.auth" : string};
  165. OCMExpect([_mockAppCredentialManager canFinishVerificationWithReceipt:kReceipt secret:kSecret])
  166. .andReturn(YES);
  167. XCTAssertTrue([_notificationManager canHandleNotification:notification]);
  168. OCMVerifyAll(_mockAppCredentialManager);
  169. }
  170. /** @fn testNotHandling
  171. @brief Test unrecognized notifications are not handled.
  172. */
  173. - (void)testNotHandling {
  174. XCTAssertFalse([_notificationManager canHandleNotification:@{@"random" : @"string"}]);
  175. XCTAssertFalse([_notificationManager
  176. canHandleNotification:@{@"com.google.firebase.auth" : @"something wrong"}]);
  177. XCTAssertFalse([_notificationManager canHandleNotification:@{
  178. @"com.google.firebase.auth" : @{
  179. @"receipt" : kReceipt
  180. // missing secret
  181. }
  182. }]);
  183. XCTAssertFalse([_notificationManager canHandleNotification:@{
  184. @"com.google.firebase.auth" : @{
  185. // missing receipt
  186. @"secret" : kSecret
  187. }
  188. }]);
  189. XCTAssertFalse([_notificationManager canHandleNotification:@{
  190. @"com.google.firebase.auth" : @{
  191. // probing notification does not belong to this instance
  192. @"warning" : @"asdf"
  193. }
  194. }]);
  195. }
  196. @end
  197. NS_ASSUME_NONNULL_END
  198. #endif