| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- /*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #import <OCMock/OCMock.h>
- #import <UserNotifications/UserNotifications.h>
- #import <XCTest/XCTest.h>
- #import "FirebaseMessaging/Sources/FIRMessagingContextManagerService.h"
- static NSString *const kBody = @"Save 20% off!";
- static NSString *const kTitle = @"Sparky WFH";
- static NSString *const kSoundName = @"default";
- static NSString *const kAction = @"open";
- static NSString *const kUserInfoKey1 = @"level";
- static NSString *const kUserInfoKey2 = @"isPayUser";
- static NSString *const kUserInfoValue1 = @"5";
- static NSString *const kUserInfoValue2 = @"Yes";
- static NSString *const kMessageIdentifierKey = @"gcm.message_id";
- static NSString *const kMessageIdentifierValue = @"1584748495200141";
- @interface FIRMessagingContextManagerService (ExposedForTest)
- + (void)scheduleiOS10LocalNotificationForMessage:(NSDictionary *)message atDate:(NSDate *)date;
- + (UNMutableNotificationContent *)contentFromContextualMessage:(NSDictionary *)message
- API_AVAILABLE(macos(10.14));
- @end
- API_AVAILABLE(macos(10.14))
- @interface FIRMessagingContextManagerServiceTest : XCTestCase
- @property(nonatomic, readwrite, strong) NSDateFormatter *dateFormatter;
- @property(nonatomic, readwrite, strong) NSMutableArray *scheduledLocalNotifications;
- @property(nonatomic, readwrite, strong) NSMutableArray<UNNotificationRequest *> *requests;
- @end
- @implementation FIRMessagingContextManagerServiceTest
- - (void)setUp {
- [super setUp];
- self.dateFormatter = [[NSDateFormatter alloc] init];
- self.dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
- [self.dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
- self.scheduledLocalNotifications = [[NSMutableArray alloc] init];
- if (@available(macOS 10.14, *)) {
- self.requests = [[NSMutableArray alloc] init];
- }
- [self mockSchedulingLocalNotifications];
- }
- - (void)tearDown {
- [super tearDown];
- }
- /**
- * Test invalid context manager message, missing lt_start string.
- */
- - (void)testInvalidContextManagerMessage_missingStartTime {
- NSDictionary *message = @{
- @"hello" : @"world",
- };
- XCTAssertFalse([FIRMessagingContextManagerService isContextManagerMessage:message]);
- }
- /**
- * Test valid context manager message.
- */
- - (void)testValidContextManagerMessage {
- NSDictionary *message = @{
- kFIRMessagingContextManagerLocalTimeStart : @"2015-12-12 00:00:00",
- @"hello" : @"world",
- };
- XCTAssertTrue([FIRMessagingContextManagerService isContextManagerMessage:message]);
- }
- /**
- * Context Manager message with future start date should be successfully scheduled.
- */
- - (void)testMessageWithFutureStartTime {
- // way into the future
- NSString *startTimeString = [self.dateFormatter stringFromDate:[NSDate distantFuture]];
- NSDictionary *message = @{
- kFIRMessagingContextManagerLocalTimeStart : startTimeString,
- kFIRMessagingContextManagerBodyKey : kBody,
- kMessageIdentifierKey : kMessageIdentifierValue,
- kUserInfoKey1 : kUserInfoValue1,
- kUserInfoKey2 : kUserInfoValue2
- };
- XCTAssertTrue([FIRMessagingContextManagerService handleContextManagerMessage:message]);
- if (@available(macOS 10.14, *)) {
- XCTAssertEqual(self.requests.count, 1);
- UNNotificationRequest *request = self.requests.firstObject;
- XCTAssertEqualObjects(request.identifier, kMessageIdentifierValue);
- #if !TARGET_OS_TV
- XCTAssertEqualObjects(request.content.body, kBody);
- XCTAssertEqualObjects(request.content.userInfo[kUserInfoKey1], kUserInfoValue1);
- XCTAssertEqualObjects(request.content.userInfo[kUserInfoKey2], kUserInfoValue2);
- #endif // TARGET_OS_TV
- return;
- }
- #if TARGET_OS_IOS
- XCTAssertEqual(self.scheduledLocalNotifications.count, 1);
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- UILocalNotification *notification = self.scheduledLocalNotifications.firstObject;
- #pragma clang diagnostic pop
- NSDate *date = [self.dateFormatter dateFromString:startTimeString];
- XCTAssertEqual([notification.fireDate compare:date], NSOrderedSame);
- XCTAssertEqualObjects(notification.alertBody, kBody);
- XCTAssertEqualObjects(notification.userInfo[kUserInfoKey1], kUserInfoValue1);
- XCTAssertEqualObjects(notification.userInfo[kUserInfoKey2], kUserInfoValue2);
- #endif // TARGET_OS_IOS
- }
- /**
- * Context Manager message with past end date should not be scheduled.
- */
- - (void)testMessageWithPastEndTime {
- #if TARGET_OS_IOS
- NSString *startTimeString = @"2010-01-12 12:00:00"; // way into the past
- NSString *endTimeString = @"2011-01-12 12:00:00"; // way into the past
- NSDictionary *message = @{
- kFIRMessagingContextManagerLocalTimeStart : startTimeString,
- kFIRMessagingContextManagerLocalTimeEnd : endTimeString,
- kFIRMessagingContextManagerBodyKey : kBody,
- kMessageIdentifierKey : kMessageIdentifierValue,
- @"hello" : @"world"
- };
- XCTAssertTrue([FIRMessagingContextManagerService handleContextManagerMessage:message]);
- if (@available(macOS 10.14, *)) {
- XCTAssertEqual(self.requests.count, 0);
- return;
- }
- XCTAssertEqual(self.scheduledLocalNotifications.count, 0);
- #endif
- }
- /**
- * Context Manager message with past start and future end date should be successfully
- * scheduled.
- */
- - (void)testMessageWithPastStartAndFutureEndTime {
- #if TARGET_OS_IOS
- NSDate *startDate = [NSDate dateWithTimeIntervalSinceNow:-1000]; // past
- NSDate *endDate = [NSDate dateWithTimeIntervalSinceNow:1000]; // future
- NSString *startTimeString = [self.dateFormatter stringFromDate:startDate];
- NSString *endTimeString = [self.dateFormatter stringFromDate:endDate];
- NSDictionary *message = @{
- kFIRMessagingContextManagerLocalTimeStart : startTimeString,
- kFIRMessagingContextManagerLocalTimeEnd : endTimeString,
- kFIRMessagingContextManagerBodyKey : kBody,
- kMessageIdentifierKey : kMessageIdentifierValue,
- kUserInfoKey1 : kUserInfoValue1,
- kUserInfoKey2 : kUserInfoValue2
- };
- XCTAssertTrue([FIRMessagingContextManagerService handleContextManagerMessage:message]);
- if (@available(macOS 10.14, *)) {
- XCTAssertEqual(self.requests.count, 1);
- UNNotificationRequest *request = self.requests.firstObject;
- XCTAssertEqualObjects(request.identifier, kMessageIdentifierValue);
- XCTAssertEqualObjects(request.content.body, kBody);
- XCTAssertEqualObjects(request.content.userInfo[kUserInfoKey1], kUserInfoValue1);
- XCTAssertEqualObjects(request.content.userInfo[kUserInfoKey2], kUserInfoValue2);
- return;
- }
- XCTAssertEqual(self.scheduledLocalNotifications.count, 1);
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- UILocalNotification *notification = [self.scheduledLocalNotifications firstObject];
- #pragma clang diagnostic pop
- // schedule notification after start date
- XCTAssertEqual([notification.fireDate compare:startDate], NSOrderedDescending);
- // schedule notification after end date
- XCTAssertEqual([notification.fireDate compare:endDate], NSOrderedAscending);
- XCTAssertEqualObjects(notification.userInfo[kUserInfoKey1], kUserInfoValue1);
- XCTAssertEqualObjects(notification.userInfo[kUserInfoKey2], kUserInfoValue2);
- #endif // TARGET_OS_IOS
- }
- /**
- * Test correctly parsing user data in local notifications.
- */
- - (void)testTimedNotificationsUserInfo {
- #if TARGET_OS_IOS
- // way into the future
- NSString *startTimeString = [self.dateFormatter stringFromDate:[NSDate distantFuture]];
- NSDictionary *message = @{
- kFIRMessagingContextManagerLocalTimeStart : startTimeString,
- kFIRMessagingContextManagerBodyKey : kBody,
- kMessageIdentifierKey : kMessageIdentifierValue,
- kUserInfoKey1 : kUserInfoValue1,
- kUserInfoKey2 : kUserInfoValue2
- };
- XCTAssertTrue([FIRMessagingContextManagerService handleContextManagerMessage:message]);
- if (@available(macOS 10.14, *)) {
- XCTAssertEqual(self.requests.count, 1);
- UNNotificationRequest *request = self.requests.firstObject;
- XCTAssertEqualObjects(request.identifier, kMessageIdentifierValue);
- XCTAssertEqualObjects(request.content.body, kBody);
- XCTAssertEqualObjects(request.content.userInfo[kUserInfoKey1], kUserInfoValue1);
- XCTAssertEqualObjects(request.content.userInfo[kUserInfoKey2], kUserInfoValue2);
- return;
- }
- XCTAssertEqual(self.scheduledLocalNotifications.count, 1);
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- UILocalNotification *notification = [self.scheduledLocalNotifications firstObject];
- #pragma clang diagnostic pop
- XCTAssertEqualObjects(notification.userInfo[kUserInfoKey1], kUserInfoValue1);
- XCTAssertEqualObjects(notification.userInfo[kUserInfoKey2], kUserInfoValue2);
- #endif // TARGET_OS_IOS
- }
- #pragma mark - Private Helpers
- - (void)mockSchedulingLocalNotifications {
- if (@available(macOS 10.14, iOS 10.0, watchOS 3.0, tvOS 10.0, *)) {
- id mockNotificationCenter =
- OCMPartialMock([UNUserNotificationCenter currentNotificationCenter]);
- __block UNNotificationRequest *request;
- [[[mockNotificationCenter stub] andDo:^(NSInvocation *invocation) {
- [self.requests addObject:request];
- }] addNotificationRequest:[OCMArg checkWithBlock:^BOOL(id obj) {
- if ([obj isKindOfClass:[UNNotificationRequest class]]) {
- request = obj;
- [self.requests addObject:request];
- return YES;
- }
- return NO;
- }]
- withCompletionHandler:^(NSError *_Nullable error){
- }];
- return;
- }
- #if TARGET_OS_IOS
- id mockApplication = OCMPartialMock([UIApplication sharedApplication]);
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- __block UILocalNotification *notificationToSchedule;
- [[[mockApplication stub] andDo:^(NSInvocation *invocation) {
- // Mock scheduling a notification
- if (notificationToSchedule) {
- [self.scheduledLocalNotifications addObject:notificationToSchedule];
- }
- }] scheduleLocalNotification:[OCMArg checkWithBlock:^BOOL(id obj) {
- if ([obj isKindOfClass:[UILocalNotification class]]) {
- notificationToSchedule = obj;
- return YES;
- }
- return NO;
- }]];
- #pragma clang diagnostic pop
- #endif // TARGET_OS_IOS
- }
- - (void)testScheduleiOS10LocalNotification {
- if (@available(macOS 10.14, *)) {
- id mockContextManagerService = OCMClassMock([FIRMessagingContextManagerService class]);
- NSDictionary *message = @{};
- [FIRMessagingContextManagerService scheduleiOS10LocalNotificationForMessage:message
- atDate:[NSDate date]];
- OCMVerify([mockContextManagerService contentFromContextualMessage:message]);
- [mockContextManagerService stopMocking];
- }
- }
- - (void)testContentFromConetxtualMessage {
- if (@available(macOS 10.14, *)) {
- NSDictionary *message = @{
- @"aps" : @{@"content-available" : @1},
- @"gcm.message_id" : @1623702615599207,
- @"gcm.n.e" : @1,
- @"gcm.notification.badge" : @1,
- @"gcm.notification.body" : kBody,
- @"gcm.notification.image" :
- @"https://firebasestorage.googleapis.com/v0/b/fir-ios-app-extensions.appspot.com/o/"
- @"sparkyWFH.png?alt=media&token=f4dc1533-4d80-4ed6-9870-8df528593157",
- @"gcm.notification.mutable_content" : @1,
- @"gcm.notification.sound" : kSoundName,
- @"gcm.notification.sound2" : kSoundName,
- @"gcm.notification.title" : kTitle,
- // This field is not popped out from console
- // Manual add here to test unit test
- @"gcm.notification.click_action" : kAction,
- @"gcms" : @"gcm.gmsproc.cm",
- @"google.c.a.c_id" : @2159728303499680621,
- @"google.c.a.c_l" : @"test local send with sound",
- @"google.c.a.e" : @1,
- @"google.c.a.ts" : @1623753000,
- @"google.c.a.udt" : @1,
- @"google.c.cm.lt_end" : @"2021-07-13 10:30:00",
- @"google.c.cm.lt_start" : @"2021-06-15 10:30:00",
- @"google.c.sender.id" : @449451107265,
- };
- UNMutableNotificationContent *content =
- [FIRMessagingContextManagerService contentFromContextualMessage:message];
- XCTAssertEqualObjects(content.badge, @1);
- #if TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH
- XCTAssertEqualObjects(content.body, kBody);
- XCTAssertEqualObjects(content.title, kTitle);
- #if !TARGET_OS_WATCH
- XCTAssertEqualObjects(content.sound, [UNNotificationSound soundNamed:kSoundName]);
- #else // !TARGET_OS_WATCH
- XCTAssertEqualObjects(content.sound, [UNNotificationSound defaultSound]);
- #endif // !TARGET_OS_WATCH
- XCTAssertEqualObjects(content.categoryIdentifier, kAction);
- NSDictionary *userInfo = @{
- @"gcm.message_id" : @1623702615599207,
- @"gcm.n.e" : @1,
- @"gcm.notification.badge" : @1,
- @"gcm.notification.body" : kBody,
- @"gcm.notification.image" :
- @"https://firebasestorage.googleapis.com/v0/b/fir-ios-app-extensions.appspot.com/o/"
- @"sparkyWFH.png?alt=media&token=f4dc1533-4d80-4ed6-9870-8df528593157",
- @"gcm.notification.mutable_content" : @1,
- @"gcm.notification.sound" : kSoundName,
- @"gcm.notification.sound2" : kSoundName,
- @"gcm.notification.title" : kTitle,
- // This field is not popped out from console
- // Manual add here to test unit test
- @"gcm.notification.click_action" : kAction,
- @"gcms" : @"gcm.gmsproc.cm",
- @"google.c.a.c_id" : @2159728303499680621,
- @"google.c.a.c_l" : @"test local send with sound",
- @"google.c.a.e" : @1,
- @"google.c.a.ts" : @1623753000,
- @"google.c.a.udt" : @1,
- @"google.c.sender.id" : @449451107265
- };
- XCTAssertEqualObjects(content.userInfo, userInfo);
- #endif // TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH
- }
- }
- @end
|