FIRMessagingCheckinServiceTest.m 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * Copyright 2021 Google LLC
  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 <XCTest/XCTest.h>
  17. #import <OCMock/OCMock.h>
  18. #import "FirebaseMessaging/Sources/FIRMessagingUtilities.h"
  19. #import "FirebaseMessaging/Sources/NSError+FIRMessaging.h"
  20. #import "FirebaseMessaging/Sources/Token/FIRMessagingCheckinPreferences.h"
  21. #import "FirebaseMessaging/Sources/Token/FIRMessagingCheckinService.h"
  22. #import "SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.h"
  23. static NSString *const kDeviceAuthId = @"1234";
  24. static NSString *const kSecretToken = @"567890";
  25. static NSString *const kDigest = @"com.google.digest";
  26. static NSString *const kVersionInfo = @"1.0";
  27. static NSString *const kDeviceCheckinURL = @"https://device-provisioning.googleapis.com/checkin";
  28. @interface FIRMessagingCheckinServiceTest : XCTestCase
  29. @property(nonatomic) id URLSessionMock;
  30. @property(nonatomic) FIRMessagingCheckinService *checkinService;
  31. @end
  32. @implementation FIRMessagingCheckinServiceTest
  33. - (void)setUp {
  34. [super setUp];
  35. // Stub NSURLSession constructor before instantiating FIRMessagingCheckinService to inject
  36. // URLSessionMock.
  37. self.URLSessionMock = OCMClassMock([NSURLSession class]);
  38. OCMStub(ClassMethod([self.URLSessionMock sessionWithConfiguration:[OCMArg any]]))
  39. .andReturn(self.URLSessionMock);
  40. self.checkinService = [[FIRMessagingCheckinService alloc] init];
  41. }
  42. - (void)tearDown {
  43. self.checkinService = nil;
  44. [self.URLSessionMock stopMocking];
  45. self.URLSessionMock = nil;
  46. [super tearDown];
  47. }
  48. - (void)testCheckinWithSuccessfulCompletion {
  49. FIRMessagingCheckinPreferences *existingCheckin = [self stubCheckinCacheWithValidData];
  50. NSURL *expectedRequestURL = [NSURL URLWithString:kDeviceCheckinURL];
  51. NSHTTPURLResponse *expectedResponse = [[NSHTTPURLResponse alloc] initWithURL:expectedRequestURL
  52. statusCode:200
  53. HTTPVersion:@"1.1"
  54. headerFields:nil];
  55. NSMutableDictionary *dataResponse = [NSMutableDictionary dictionary];
  56. dataResponse[@"android_id"] = @([kDeviceAuthId longLongValue]);
  57. dataResponse[@"security_token"] = @([kSecretToken longLongValue]);
  58. dataResponse[@"time_msec"] = @(FIRMessagingCurrentTimestampInMilliseconds());
  59. dataResponse[@"version_info"] = kVersionInfo;
  60. dataResponse[@"digest"] = kDigest;
  61. NSData *data = [NSJSONSerialization dataWithJSONObject:dataResponse
  62. options:NSJSONWritingPrettyPrinted
  63. error:nil];
  64. [FIRURLSessionOCMockStub
  65. stubURLSessionDataTaskWithResponse:expectedResponse
  66. body:data
  67. error:nil
  68. URLSessionMock:self.URLSessionMock
  69. requestValidationBlock:^BOOL(NSURLRequest *_Nonnull sentRequest) {
  70. [self assertValidCheckinRequest:sentRequest expectedURL:expectedRequestURL];
  71. return YES;
  72. }];
  73. XCTestExpectation *checkinCompletionExpectation =
  74. [self expectationWithDescription:@"Checkin Completion"];
  75. [self.checkinService
  76. checkinWithExistingCheckin:existingCheckin
  77. completion:^(FIRMessagingCheckinPreferences *checkinPreferences,
  78. NSError *error) {
  79. XCTAssertNil(error);
  80. XCTAssertEqualObjects(checkinPreferences.deviceID, kDeviceAuthId);
  81. XCTAssertEqualObjects(checkinPreferences.versionInfo, kVersionInfo);
  82. // For accuracy purposes it's better to compare seconds since the test
  83. // should never run for more than 1 second.
  84. NSInteger expectedTimestampInSeconds =
  85. (NSInteger)FIRMessagingCurrentTimestampInSeconds();
  86. NSInteger actualTimestampInSeconds =
  87. checkinPreferences.lastCheckinTimestampMillis / 1000.0;
  88. XCTAssertEqual(expectedTimestampInSeconds, actualTimestampInSeconds);
  89. XCTAssertTrue([checkinPreferences hasValidCheckinInfo]);
  90. [checkinCompletionExpectation fulfill];
  91. }];
  92. [self waitForExpectationsWithTimeout:5
  93. handler:^(NSError *error) {
  94. XCTAssertNil(error);
  95. }];
  96. }
  97. - (void)testCheckinServiceFailure {
  98. NSURL *expectedRequestURL = [NSURL URLWithString:kDeviceCheckinURL];
  99. NSHTTPURLResponse *failureResponse = [[NSHTTPURLResponse alloc] initWithURL:expectedRequestURL
  100. statusCode:404
  101. HTTPVersion:@"1.1"
  102. headerFields:nil];
  103. [FIRURLSessionOCMockStub
  104. stubURLSessionDataTaskWithResponse:failureResponse
  105. body:[@"Not Found" dataUsingEncoding:NSUTF8StringEncoding]
  106. error:nil
  107. URLSessionMock:self.URLSessionMock
  108. requestValidationBlock:^BOOL(NSURLRequest *_Nonnull sentRequest) {
  109. [self assertValidCheckinRequest:sentRequest expectedURL:expectedRequestURL];
  110. return YES;
  111. }];
  112. XCTestExpectation *checkinCompletionExpectation =
  113. [self expectationWithDescription:@"Checkin Completion"];
  114. [self.checkinService
  115. checkinWithExistingCheckin:nil
  116. completion:^(FIRMessagingCheckinPreferences *preferences, NSError *error) {
  117. XCTAssertNotNil(error);
  118. XCTAssertNil(preferences.deviceID);
  119. XCTAssertNil(preferences.secretToken);
  120. XCTAssertFalse([preferences hasValidCheckinInfo]);
  121. [checkinCompletionExpectation fulfill];
  122. }];
  123. [self waitForExpectationsWithTimeout:5
  124. handler:^(NSError *error) {
  125. if (error) {
  126. XCTFail(@"Checkin Timeout Error: %@", error);
  127. }
  128. }];
  129. }
  130. - (void)testCheckinServiceNetworkFailure {
  131. NSURL *expectedRequestURL = [NSURL URLWithString:kDeviceCheckinURL];
  132. NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidRequest
  133. failureReason:@"Checkin failed with invalid request."];
  134. XCTestExpectation *checkinCompletionExpectation =
  135. [self expectationWithDescription:@"Checkin Completion"];
  136. [FIRURLSessionOCMockStub
  137. stubURLSessionDataTaskWithResponse:nil
  138. body:nil
  139. error:error
  140. URLSessionMock:self.URLSessionMock
  141. requestValidationBlock:^BOOL(NSURLRequest *_Nonnull sentRequest) {
  142. [self assertValidCheckinRequest:sentRequest expectedURL:expectedRequestURL];
  143. return YES;
  144. }];
  145. [self.checkinService
  146. checkinWithExistingCheckin:nil
  147. completion:^(FIRMessagingCheckinPreferences *preferences, NSError *error) {
  148. XCTAssertNotNil(error);
  149. XCTAssertNil(preferences.deviceID);
  150. XCTAssertNil(preferences.secretToken);
  151. XCTAssertFalse([preferences hasValidCheckinInfo]);
  152. [checkinCompletionExpectation fulfill];
  153. }];
  154. [self waitForExpectationsWithTimeout:5
  155. handler:^(NSError *error) {
  156. if (error) {
  157. XCTFail(@"Checkin Timeout Error: %@", error);
  158. }
  159. }];
  160. }
  161. #pragma mark - Stub
  162. - (FIRMessagingCheckinPreferences *)stubCheckinCacheWithValidData {
  163. NSDictionary *gservicesData = @{
  164. @"FIRMessagingVersionInfo" : kVersionInfo,
  165. @"FIRMessagingLastCheckinTimestampKey" : @(FIRMessagingCurrentTimestampInMilliseconds())
  166. };
  167. FIRMessagingCheckinPreferences *checkinPreferences =
  168. [[FIRMessagingCheckinPreferences alloc] initWithDeviceID:kDeviceAuthId
  169. secretToken:kSecretToken];
  170. [checkinPreferences updateWithCheckinPlistContents:gservicesData];
  171. return checkinPreferences;
  172. }
  173. #pragma mark - Helpers
  174. - (void)assertValidCheckinRequest:(NSURLRequest *)request expectedURL:(NSURL *)expectedURL {
  175. XCTAssertEqualObjects(request.URL, expectedURL);
  176. XCTAssertEqualObjects(request.allHTTPHeaderFields, @{@"Content-Type" : @"application/json"});
  177. // TODO: Validate body.
  178. }
  179. @end