FIRMessagingExtensionHelperTest.m 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright 2019 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 <OCMock/OCMock.h>
  17. #import <XCTest/XCTest.h>
  18. #import <GoogleUtilities/GULAppEnvironmentUtil.h>
  19. #import "FirebaseMessaging/Sources/FIRMessagingConstants.h"
  20. #import "FirebaseMessaging/Sources/Public/FirebaseMessaging/FIRMessaging.h"
  21. #import "FirebaseMessaging/Sources/Public/FirebaseMessaging/FIRMessagingExtensionHelper.h"
  22. API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0))
  23. typedef void (^FIRMessagingContentHandler)(UNNotificationContent *content);
  24. #if TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH
  25. static NSString *const kFCMPayloadOptionsName = @"fcm_options";
  26. static NSString *const kFCMPayloadOptionsImageURLName = @"image";
  27. static NSString *const kValidImageURL =
  28. @"https://firebasestorage.googleapis.com/v0/b/fcm-ios-f7f9c.appspot.com/o/"
  29. @"chubbyBunny.jpg?alt=media&token=d6c56a57-c007-4b27-b20f-f267cc83e9e5";
  30. @interface FIRMessagingExtensionHelper (ExposedForTest)
  31. - (void)loadAttachmentForURL:(NSURL *)attachmentURL
  32. completionHandler:(void (^)(UNNotificationAttachment *))completionHandler;
  33. + (NSString *)bundleIdentifierByRemovingLastPartFrom:(NSString *)bundleIdentifier;
  34. - (NSString *)fileExtensionForResponse:(NSURLResponse *)response;
  35. @end
  36. @interface FIRMessagingExtensionHelperTest : XCTestCase {
  37. id _mockExtensionHelper;
  38. id _mockUtilClass;
  39. id _mockURLResponse;
  40. }
  41. @end
  42. @implementation FIRMessagingExtensionHelperTest
  43. - (void)setUp {
  44. [super setUp];
  45. if (@available(macOS 10.14, iOS 10.0, watchos 3.0, *)) {
  46. FIRMessagingExtensionHelper *extensionHelper = [FIRMessaging extensionHelper];
  47. _mockExtensionHelper = OCMPartialMock(extensionHelper);
  48. _mockUtilClass = OCMClassMock([GULAppEnvironmentUtil class]);
  49. _mockURLResponse = OCMClassMock([NSURLResponse class]);
  50. } else {
  51. // Fallback on earlier versions
  52. }
  53. }
  54. - (void)tearDown {
  55. [_mockExtensionHelper stopMocking];
  56. [_mockUtilClass stopMocking];
  57. [_mockURLResponse stopMocking];
  58. }
  59. #ifdef COCOAPODS
  60. // This test requires internet access.
  61. - (void)testModifyNotificationWithValidPayloadData {
  62. if (@available(macOS 10.14, iOS 10.0, watchos 3.0, *)) {
  63. XCTestExpectation *validPayloadExpectation =
  64. [self expectationWithDescription:@"Test payload is valid."];
  65. UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
  66. content.userInfo =
  67. @{kFCMPayloadOptionsName : @{kFCMPayloadOptionsImageURLName : kValidImageURL}};
  68. FIRMessagingContentHandler handler = ^(UNNotificationContent *content) {
  69. [validPayloadExpectation fulfill];
  70. };
  71. [_mockExtensionHelper populateNotificationContent:content withContentHandler:handler];
  72. OCMVerify([_mockExtensionHelper loadAttachmentForURL:[OCMArg any]
  73. completionHandler:[OCMArg any]]);
  74. // Wait longer to accomodate increased network latency when running on CI.
  75. [self waitForExpectationsWithTimeout:5.0 handler:nil];
  76. }
  77. }
  78. #endif // COCOAPODS
  79. - (void)testModifyNotificationWithInvalidPayloadData {
  80. if (@available(macOS 10.14, iOS 10.0, watchos 3.0, *)) {
  81. XCTestExpectation *validPayloadExpectation =
  82. [self expectationWithDescription:@"Test payload is valid."];
  83. UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
  84. content.userInfo =
  85. @{kFCMPayloadOptionsName : @{kFCMPayloadOptionsImageURLName : @"a invalid URL"}};
  86. FIRMessagingContentHandler handler = ^(UNNotificationContent *content) {
  87. [validPayloadExpectation fulfill];
  88. };
  89. [_mockExtensionHelper populateNotificationContent:content withContentHandler:handler];
  90. OCMReject([_mockExtensionHelper loadAttachmentForURL:[OCMArg any]
  91. completionHandler:[OCMArg any]]);
  92. [self waitForExpectationsWithTimeout:1.0 handler:nil];
  93. }
  94. }
  95. - (void)testModifyNotificationWithEmptyPayloadData {
  96. if (@available(macOS 10.14, iOS 10.0, watchos 3.0, *)) {
  97. XCTestExpectation *validPayloadExpectation =
  98. [self expectationWithDescription:@"Test payload is valid."];
  99. UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
  100. content.userInfo =
  101. @{kFCMPayloadOptionsName : @{kFCMPayloadOptionsImageURLName : @"a invalid URL"}};
  102. FIRMessagingContentHandler handler = ^(UNNotificationContent *content) {
  103. [validPayloadExpectation fulfill];
  104. };
  105. [_mockExtensionHelper populateNotificationContent:content withContentHandler:handler];
  106. OCMReject([_mockExtensionHelper loadAttachmentForURL:[OCMArg any]
  107. completionHandler:[OCMArg any]]);
  108. [self waitForExpectationsWithTimeout:1.0 handler:nil];
  109. }
  110. }
  111. - (void)testModifyNotificationWithValidPayloadDataNoMimeType {
  112. if (@available(macOS 10.14, iOS 10.0, *)) {
  113. NSString *const kValidTestURL = @"test.jpg";
  114. NSString *const kValidTestExtension = @".jpg";
  115. OCMStub([_mockURLResponse suggestedFilename]).andReturn(kValidTestURL);
  116. NSString *const extension = [_mockExtensionHelper fileExtensionForResponse:_mockURLResponse];
  117. XCTAssertTrue([extension isEqualToString:kValidTestExtension]);
  118. }
  119. }
  120. - (void)testModifyNotificationWithInvalidPayloadDataInvalidMimeType {
  121. if (@available(macOS 10.14, iOS 10.0, *)) {
  122. NSString *const kInvalidTestURL = @"test";
  123. NSString *const kInvalidTestExtension = @"";
  124. OCMStub([_mockURLResponse suggestedFilename]).andReturn(kInvalidTestURL);
  125. OCMStub([_mockURLResponse MIMEType]).andReturn(nil);
  126. NSString *const extension = [_mockExtensionHelper fileExtensionForResponse:_mockURLResponse];
  127. XCTAssertTrue([extension isEqualToString:kInvalidTestExtension]);
  128. }
  129. }
  130. - (void)testModifyNotificationWithInvalidPayloadDataValidMimeType {
  131. if (@available(macOS 10.14, iOS 10.0, *)) {
  132. NSString *const kValidMIMETypeTestURL = @"test";
  133. NSString *const kValidMIMETypeTestMIMEType = @"image/jpeg";
  134. NSString *const kValidMIMETypeTestExtension = @".jpeg";
  135. OCMStub([_mockURLResponse suggestedFilename]).andReturn(kValidMIMETypeTestURL);
  136. OCMStub([_mockURLResponse MIMEType]).andReturn(kValidMIMETypeTestMIMEType);
  137. NSString *const extension = [_mockExtensionHelper fileExtensionForResponse:_mockURLResponse];
  138. XCTAssertTrue([extension isEqualToString:kValidMIMETypeTestExtension]);
  139. }
  140. }
  141. - (void)testDeliveryMetricsLoggingWithEmptyPayload {
  142. OCMStub([_mockUtilClass isAppExtension]).andReturn(YES);
  143. NSDictionary *fakeMessageInfo = @{@"aps" : @{}};
  144. OCMReject([_mockExtensionHelper bundleIdentifierByRemovingLastPartFrom:[OCMArg any]]);
  145. [_mockExtensionHelper exportDeliveryMetricsToBigQueryWithMessageInfo:fakeMessageInfo];
  146. OCMVerifyAll(_mockExtensionHelper);
  147. }
  148. - (void)testDeliveryMetricsLoggingWithInvalidMessageID {
  149. OCMStub([_mockUtilClass isAppExtension]).andReturn(YES);
  150. NSDictionary *fakeMessageInfo = @{
  151. @"aps" : @{@"badge" : @9, @"mutable-content" : @1},
  152. @"fcm_options" : @{@"image" : @"https://google.com"},
  153. @"google.c.fid" : @"fakeFIDForTest",
  154. @"google.c.sender.id" : @123456789
  155. };
  156. OCMReject([_mockExtensionHelper bundleIdentifierByRemovingLastPartFrom:[OCMArg any]]);
  157. [_mockExtensionHelper exportDeliveryMetricsToBigQueryWithMessageInfo:fakeMessageInfo];
  158. OCMVerifyAll(_mockExtensionHelper);
  159. }
  160. - (void)testDeliveryMetricsLoggingWithInvalidFID {
  161. OCMStub([_mockUtilClass isAppExtension]).andReturn(YES);
  162. NSDictionary *fakeMessageInfo = @{
  163. @"aps" : @{@"badge" : @9, @"mutable-content" : @1},
  164. @"fcm_options" : @{@"image" : @"https://google.com"},
  165. @"google.c.sender.id" : @123456789
  166. };
  167. OCMReject([_mockExtensionHelper bundleIdentifierByRemovingLastPartFrom:[OCMArg any]]);
  168. [_mockExtensionHelper exportDeliveryMetricsToBigQueryWithMessageInfo:fakeMessageInfo];
  169. OCMVerifyAll(_mockExtensionHelper);
  170. }
  171. - (void)testDeliveryMetricsLoggingWithDisplayPayload {
  172. OCMStub([_mockUtilClass isAppExtension]).andReturn(YES);
  173. NSDictionary *fakeMessageInfo = @{
  174. @"aps" : @{@"badge" : @9, @"mutable-content" : @1},
  175. @"fcm_options" : @{@"image" : @"https://google.com"},
  176. @"gcm.message_id" : @"1627428480762269",
  177. @"google.c.fid" : @"fakeFIDForTest",
  178. @"google.c.sender.id" : @123456789
  179. };
  180. OCMExpect([_mockExtensionHelper bundleIdentifierByRemovingLastPartFrom:[OCMArg any]]);
  181. [_mockExtensionHelper exportDeliveryMetricsToBigQueryWithMessageInfo:fakeMessageInfo];
  182. OCMVerifyAll(_mockExtensionHelper);
  183. }
  184. - (void)testDeliveryMetricsLoggingWithDataPayload {
  185. OCMStub([_mockUtilClass isAppExtension]).andReturn(NO);
  186. NSDictionary *fakeMessageInfo = @{
  187. @"aps" : @{@"badge" : @9, @"content-available" : @1},
  188. @"fcm_options" : @{@"image" : @"https://google.com"},
  189. @"gcm.message_id" : @"1627428480762269",
  190. @"google.c.fid" : @"fakeFIDForTest",
  191. @"google.c.sender.id" : @123456789
  192. };
  193. OCMReject([_mockExtensionHelper bundleIdentifierByRemovingLastPartFrom:[OCMArg any]]);
  194. [_mockExtensionHelper exportDeliveryMetricsToBigQueryWithMessageInfo:fakeMessageInfo];
  195. OCMVerifyAll(_mockExtensionHelper);
  196. }
  197. @end
  198. #endif // TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH