1313 * See the License for the specific language governing permissions and
1414 * limitations under the License.
1515 */
16-
16+ #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 || \
17+ __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_14 || __TV_OS_VERSION_MAX_ALLOWED >= __TV_10_0 || \
18+ __WATCH_OS_VERSION_MAX_ALLOWED >= __WATCHOS_3_0 || TARGET_OS_MACCATALYST
19+ #import < UserNotifications/UserNotifications.h>
20+ #endif
1721#import < OCMock/OCMock.h>
1822#import < XCTest/XCTest.h>
1923
2024#import " FirebaseMessaging/Sources/FIRMessagingContextManagerService.h"
2125
26+ static NSString *const kBody = @" Save 20% o ff!" ;
27+ static NSString *const kUserInfoKey1 = @" level" ;
28+ static NSString *const kUserInfoKey2 = @" isPayUser" ;
29+ static NSString *const kUserInfoValue1 = @" 5" ;
30+ static NSString *const kUserInfoValue2 = @" Yes" ;
31+ static NSString *const kMessageIdentifierKey = @" gcm.message_id" ;
32+ static NSString *const kMessageIdentifierValue = @" 1584748495200141" ;
33+
2234@interface FIRMessagingContextManagerServiceTest : XCTestCase
2335
2436@property (nonatomic , readwrite , strong ) NSDateFormatter *dateFormatter;
2537@property (nonatomic , readwrite , strong ) NSMutableArray *scheduledLocalNotifications;
38+ @property (nonatomic , readwrite , strong )
39+ NSMutableArray <UNNotificationRequest *> *requests API_AVAILABLE (ios(10.0 ));
2640
2741@end
2842
@@ -33,7 +47,11 @@ - (void)setUp {
3347 self.dateFormatter = [[NSDateFormatter alloc ] init ];
3448 self.dateFormatter .locale = [NSLocale localeWithLocaleIdentifier: @" en_US_POSIX" ];
3549 [self .dateFormatter setDateFormat: @" yyyy-MM-dd HH:mm:ss" ];
36- self.scheduledLocalNotifications = [NSMutableArray array ];
50+ self.scheduledLocalNotifications = [[NSMutableArray alloc ] init ];
51+ if (@available (macOS 10.14 , iOS 10.0 , watchOS 3.0 , tvOS 10.0 , *)) {
52+ self.requests = [[NSMutableArray alloc ] init ];
53+ }
54+
3755 [self mockSchedulingLocalNotifications ];
3856}
3957
@@ -62,34 +80,44 @@ - (void)testValidContextManagerMessage {
6280 XCTAssertTrue ([FIRMessagingContextManagerService isContextManagerMessage: message]);
6381}
6482
65- // TODO: Enable these tests. They fail because we cannot schedule local
66- // notifications on OSX without permission. It's better to mock AppDelegate's
67- // scheduleLocalNotification to mock scheduling behavior.
68-
6983/* *
7084 * Context Manager message with future start date should be successfully scheduled.
7185 */
7286- (void )testMessageWithFutureStartTime {
73- #if TARGET_OS_IOS
74- NSString *messageIdentifier = @" fcm-cm-test1" ;
7587 // way into the future
7688 NSString *startTimeString = [self .dateFormatter stringFromDate: [NSDate distantFuture ]];
7789 NSDictionary *message = @{
7890 kFIRMessagingContextManagerLocalTimeStart : startTimeString,
79- kFIRMessagingContextManagerBodyKey : @" Hello world!" ,
80- @" id" : messageIdentifier,
81- @" hello" : @" world"
91+ kFIRMessagingContextManagerBodyKey : kBody ,
92+ kMessageIdentifierKey : kMessageIdentifierValue ,
93+ kUserInfoKey1 : kUserInfoValue1 ,
94+ kUserInfoKey2 : kUserInfoValue2
8295 };
83-
8496 XCTAssertTrue ([FIRMessagingContextManagerService handleContextManagerMessage: message]);
8597
98+ if (@available (macOS 10.14 , iOS 10.0 , watchOS 3.0 , tvOS 10.0 , *)) {
99+ XCTAssertEqual (self.requests .count , 1 );
100+ UNNotificationRequest *request = self.requests .firstObject ;
101+ XCTAssertEqualObjects (request.identifier , kMessageIdentifierValue );
102+ #if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_OSX
103+ XCTAssertEqualObjects (request.content .body , kBody );
104+ XCTAssertEqualObjects (request.content .userInfo [kUserInfoKey1 ], kUserInfoValue1 );
105+ XCTAssertEqualObjects (request.content .userInfo [kUserInfoKey2 ], kUserInfoValue2 );
106+ #endif
107+ return ;
108+ }
109+
110+ #if TARGET_OS_IOS
86111 XCTAssertEqual (self.scheduledLocalNotifications .count , 1 );
87112#pragma clang diagnostic push
88113#pragma clang diagnostic ignored "-Wdeprecated-declarations"
89- UILocalNotification *notification = [ self .scheduledLocalNotifications firstObject ] ;
114+ UILocalNotification *notification = self.scheduledLocalNotifications . firstObject ;
90115#pragma clang diagnostic pop
91116 NSDate *date = [self .dateFormatter dateFromString: startTimeString];
92117 XCTAssertEqual ([notification.fireDate compare: date], NSOrderedSame);
118+ XCTAssertEqualObjects (notification.alertBody , kBody );
119+ XCTAssertEqualObjects (notification.userInfo [kUserInfoKey1 ], kUserInfoValue1 );
120+ XCTAssertEqualObjects (notification.userInfo [kUserInfoKey2 ], kUserInfoValue2 );
93121#endif
94122}
95123
@@ -98,18 +126,21 @@ - (void)testMessageWithFutureStartTime {
98126 */
99127- (void )testMessageWithPastEndTime {
100128#if TARGET_OS_IOS
101- NSString *messageIdentifier = @" fcm-cm-test1" ;
102129 NSString *startTimeString = @" 2010-01-12 12:00:00" ; // way into the past
103130 NSString *endTimeString = @" 2011-01-12 12:00:00" ; // way into the past
104131 NSDictionary *message = @{
105132 kFIRMessagingContextManagerLocalTimeStart : startTimeString,
106133 kFIRMessagingContextManagerLocalTimeEnd : endTimeString,
107- kFIRMessagingContextManagerBodyKey : @" Hello world! " ,
108- @" id " : messageIdentifier ,
134+ kFIRMessagingContextManagerBodyKey : kBody ,
135+ kMessageIdentifierKey : kMessageIdentifierValue ,
109136 @" hello" : @" world"
110137 };
111138
112139 XCTAssertTrue ([FIRMessagingContextManagerService handleContextManagerMessage: message]);
140+ if (@available (macOS 10.14 , iOS 10.0 , watchOS 3.0 , tvOS 10.0 , *)) {
141+ XCTAssertEqual (self.requests .count , 0 );
142+ return ;
143+ }
113144 XCTAssertEqual (self.scheduledLocalNotifications .count , 0 );
114145#endif
115146}
@@ -120,7 +151,6 @@ - (void)testMessageWithPastEndTime {
120151 */
121152- (void )testMessageWithPastStartAndFutureEndTime {
122153#if TARGET_OS_IOS
123- NSString *messageIdentifier = @" fcm-cm-test1" ;
124154 NSDate *startDate = [NSDate dateWithTimeIntervalSinceNow: -1000 ]; // past
125155 NSDate *endDate = [NSDate dateWithTimeIntervalSinceNow: 1000 ]; // future
126156 NSString *startTimeString = [self .dateFormatter stringFromDate: startDate];
@@ -129,13 +159,23 @@ - (void)testMessageWithPastStartAndFutureEndTime {
129159 NSDictionary *message = @{
130160 kFIRMessagingContextManagerLocalTimeStart : startTimeString,
131161 kFIRMessagingContextManagerLocalTimeEnd : endTimeString,
132- kFIRMessagingContextManagerBodyKey : @" Hello world!" ,
133- @" id" : messageIdentifier,
134- @" hello" : @" world"
162+ kFIRMessagingContextManagerBodyKey : kBody ,
163+ kMessageIdentifierKey : kMessageIdentifierValue ,
164+ kUserInfoKey1 : kUserInfoValue1 ,
165+ kUserInfoKey2 : kUserInfoValue2
135166 };
136167
137168 XCTAssertTrue ([FIRMessagingContextManagerService handleContextManagerMessage: message]);
138169
170+ if (@available (macOS 10.14 , iOS 10.0 , watchOS 3.0 , tvOS 10.0 , *)) {
171+ XCTAssertEqual (self.requests .count , 1 );
172+ UNNotificationRequest *request = self.requests .firstObject ;
173+ XCTAssertEqualObjects (request.identifier , kMessageIdentifierValue );
174+ XCTAssertEqualObjects (request.content .body , kBody );
175+ XCTAssertEqualObjects (request.content .userInfo [kUserInfoKey1 ], kUserInfoValue1 );
176+ XCTAssertEqualObjects (request.content .userInfo [kUserInfoKey2 ], kUserInfoValue2 );
177+ return ;
178+ }
139179 XCTAssertEqual (self.scheduledLocalNotifications .count , 1 );
140180#pragma clang diagnostic push
141181#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@@ -145,6 +185,8 @@ - (void)testMessageWithPastStartAndFutureEndTime {
145185 XCTAssertEqual ([notification.fireDate compare: startDate], NSOrderedDescending);
146186 // schedule notification after end date
147187 XCTAssertEqual ([notification.fireDate compare: endDate], NSOrderedAscending);
188+ XCTAssertEqualObjects (notification.userInfo [kUserInfoKey1 ], kUserInfoValue1 );
189+ XCTAssertEqualObjects (notification.userInfo [kUserInfoKey2 ], kUserInfoValue2 );
148190#endif
149191}
150192
@@ -153,35 +195,58 @@ - (void)testMessageWithPastStartAndFutureEndTime {
153195 */
154196- (void )testTimedNotificationsUserInfo {
155197#if TARGET_OS_IOS
156- NSString *messageIdentifierKey = @" message.id" ;
157- NSString *messageIdentifier = @" fcm-cm-test1" ;
158198 // way into the future
159199 NSString *startTimeString = [self .dateFormatter stringFromDate: [NSDate distantFuture ]];
160200
161- NSString *customDataKey = @" hello" ;
162- NSString *customData = @" world" ;
163201 NSDictionary *message = @{
164202 kFIRMessagingContextManagerLocalTimeStart : startTimeString,
165- kFIRMessagingContextManagerBodyKey : @" Hello world!" ,
166- messageIdentifierKey : messageIdentifier,
167- customDataKey : customData,
203+ kFIRMessagingContextManagerBodyKey : kBody ,
204+ kMessageIdentifierKey : kMessageIdentifierValue ,
205+ kUserInfoKey1 : kUserInfoValue1 ,
206+ kUserInfoKey2 : kUserInfoValue2
168207 };
169208
170209 XCTAssertTrue ([FIRMessagingContextManagerService handleContextManagerMessage: message]);
171-
210+ if (@available (macOS 10.14 , iOS 10.0 , watchOS 3.0 , tvOS 10.0 , *)) {
211+ XCTAssertEqual (self.requests .count , 1 );
212+ UNNotificationRequest *request = self.requests .firstObject ;
213+ XCTAssertEqualObjects (request.identifier , kMessageIdentifierValue );
214+ XCTAssertEqualObjects (request.content .body , kBody );
215+ XCTAssertEqualObjects (request.content .userInfo [kUserInfoKey1 ], kUserInfoValue1 );
216+ XCTAssertEqualObjects (request.content .userInfo [kUserInfoKey2 ], kUserInfoValue2 );
217+ return ;
218+ }
172219 XCTAssertEqual (self.scheduledLocalNotifications .count , 1 );
173220#pragma clang diagnostic push
174221#pragma clang diagnostic ignored "-Wdeprecated-declarations"
175222 UILocalNotification *notification = [self .scheduledLocalNotifications firstObject ];
176223#pragma clang diagnostic pop
177- XCTAssertEqualObjects (notification.userInfo [messageIdentifierKey ], messageIdentifier );
178- XCTAssertEqualObjects (notification.userInfo [customDataKey ], customData );
224+ XCTAssertEqualObjects (notification.userInfo [kUserInfoKey1 ], kUserInfoValue1 );
225+ XCTAssertEqualObjects (notification.userInfo [kUserInfoKey2 ], kUserInfoValue2 );
179226#endif
180227}
181228
182229#pragma mark - Private Helpers
183230
184231- (void )mockSchedulingLocalNotifications {
232+ if (@available (macOS 10.14 , iOS 10.0 , watchOS 3.0 , tvOS 10.0 , *)) {
233+ id mockNotificationCenter =
234+ OCMPartialMock ([UNUserNotificationCenter currentNotificationCenter ]);
235+ __block UNNotificationRequest *request;
236+ [[[mockNotificationCenter stub ] andDo: ^(NSInvocation *invocation) {
237+ [self .requests addObject: request];
238+ }] addNotificationRequest: [OCMArg checkWithBlock: ^BOOL (id obj) {
239+ if ([obj isKindOfClass: [UNNotificationRequest class ]]) {
240+ request = obj;
241+ [self .requests addObject: request];
242+ return YES ;
243+ }
244+ return NO ;
245+ }]
246+ withCompletionHandler: ^(NSError *_Nullable error){
247+ }];
248+ return ;
249+ }
185250#if TARGET_OS_IOS
186251 id mockApplication = OCMPartialMock ([UIApplication sharedApplication ]);
187252#pragma clang diagnostic push
0 commit comments