@@ -30,6 +30,98 @@ -(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotif
3030}
3131@end
3232
33+ @interface UNUserNotificationCenterDelegateForwardingTargetForSelectorTest : UIResponder <UNUserNotificationCenterDelegate >
34+ @end
35+ @implementation UNUserNotificationCenterDelegateForwardingTargetForSelectorTest {
36+ id forwardingInstance;
37+ }
38+ - (instancetype )initForwardingTarget : (id )forwardingTarget {
39+ self = [super init ];
40+ forwardingInstance = forwardingTarget;
41+ return self;
42+ }
43+
44+ - (id )forwardingTargetForSelector : (SEL )selector {
45+ return forwardingInstance;
46+ }
47+ @end
48+
49+ @interface UNUserNotificationCenterDelegateForwardReceiver : UIResponder <UNUserNotificationCenterDelegate > {
50+ @public NSMutableDictionary *selectorCallsDict;
51+ }
52+ @end
53+ @implementation UNUserNotificationCenterDelegateForwardReceiver
54+
55+ - (instancetype )init {
56+ self = [super init ];
57+ selectorCallsDict = [NSMutableDictionary new ];
58+ return self;
59+ }
60+ - (void )userNotificationCenter : (UNUserNotificationCenter *)center willPresentNotification : (UNNotification *)notification withCompletionHandler : (void (^)(UNNotificationPresentationOptions ))completionHandler {
61+ SEL thisSelector = @selector (userNotificationCenter:willPresentNotification:withCompletionHandler: );
62+ [selectorCallsDict
63+ setObject: @(true )
64+ forKey: NSStringFromSelector (thisSelector)
65+ ];
66+ }
67+
68+ - (void )userNotificationCenter : (UNUserNotificationCenter *)center didReceiveNotificationResponse : (UNNotificationResponse *)response withCompletionHandler : (void (^)(void ))completionHandler {
69+ SEL thisSelector = @selector (userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: );
70+ [selectorCallsDict
71+ setObject: @(true )
72+ forKey: NSStringFromSelector (thisSelector)
73+ ];
74+ }
75+
76+ - (void )userNotificationCenter : (UNUserNotificationCenter *)center openSettingsForNotification : (UNNotification *)notification {
77+ SEL thisSelector = @selector (userNotificationCenter:openSettingsForNotification: );
78+ [selectorCallsDict
79+ setObject: @(true )
80+ forKey: NSStringFromSelector (thisSelector)
81+ ];
82+ }
83+ @end
84+
85+ @interface UNUserNotificationCenterDelegateForExistingSelectorsTest : UIResponder <UNUserNotificationCenterDelegate > {
86+ @public NSMutableDictionary *selectorCallsDict;
87+ }
88+ @end
89+ @implementation UNUserNotificationCenterDelegateForExistingSelectorsTest
90+
91+ - (instancetype )init {
92+ self = [super init ];
93+ selectorCallsDict = [NSMutableDictionary new ];
94+ return self;
95+ }
96+ - (void )userNotificationCenter : (UNUserNotificationCenter *)center willPresentNotification : (UNNotification *)notification withCompletionHandler : (void (^)(UNNotificationPresentationOptions ))completionHandler {
97+ SEL thisSelector = @selector (userNotificationCenter:willPresentNotification:withCompletionHandler: );
98+ [selectorCallsDict
99+ setObject: @(true )
100+ forKey: NSStringFromSelector (thisSelector)
101+ ];
102+ }
103+
104+ - (void )userNotificationCenter : (UNUserNotificationCenter *)center didReceiveNotificationResponse : (UNNotificationResponse *)response withCompletionHandler : (void (^)(void ))completionHandler {
105+ SEL thisSelector = @selector (userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: );
106+ [selectorCallsDict
107+ setObject: @(true )
108+ forKey: NSStringFromSelector (thisSelector)
109+ ];
110+ }
111+
112+ - (void )userNotificationCenter : (UNUserNotificationCenter *)center openSettingsForNotification : (UNNotification *)notification {
113+ SEL thisSelector = @selector (userNotificationCenter:openSettingsForNotification: );
114+ [selectorCallsDict
115+ setObject: @(true )
116+ forKey: NSStringFromSelector (thisSelector)
117+ ];
118+ }
119+ @end
120+
121+ @interface UNUserNotificationCenterDelegateForInfiniteLoopTest : UIResponder <UNUserNotificationCenterDelegate >
122+ @end
123+ @implementation UNUserNotificationCenterDelegateForInfiniteLoopTest
124+ @end
33125
34126@interface OneSignalUNUserNotificationCenterSwizzlingTest : XCTestCase
35127@end
@@ -50,6 +142,37 @@ - (void)tearDown {
50142 [OneSignalUNUserNotificationCenterHelper restoreDelegateAsOneSignal ];
51143}
52144
145+ - (UNNotificationResponse *)createBasiciOSNotificationResponse {
146+ id userInfo = @{@" custom" :
147+ @{ @" i" : @" b2f7f966-d8cc-11e4-bed1-df8f05be55ba" }
148+ };
149+
150+ return [UnitTestCommonMethods createBasiciOSNotificationResponseWithPayload: userInfo];
151+ }
152+
153+ - (UNNotification *)createNonOneSignaliOSNotification {
154+ id userInfo = @{@" aps" : @{
155+ @" mutable-content" : @1 ,
156+ @" alert" : @" Message Body"
157+ }
158+ };
159+
160+ return [UnitTestCommonMethods createBasiciOSNotificationWithPayload: userInfo];
161+ }
162+
163+ - (UNNotification *)createBasiciOSNotification {
164+ id userInfo = @{@" aps" : @{
165+ @" mutable-content" : @1 ,
166+ @" alert" : @" Message Body"
167+ },
168+ @" os_data" : @{
169+ @" i" : @" b2f7f966-d8cc-11e4-bed1-df8f05be55ba" ,
170+ @" buttons" : @[@{@" i" : @" id1" , @" n" : @" text1" }],
171+ }};
172+
173+ return [UnitTestCommonMethods createBasiciOSNotificationWithPayload: userInfo];
174+ }
175+
53176// Tests to make sure that UNNotificationCenter setDelegate: duplicate calls don't double-swizzle for the same object
54177- (void )testAUNUserNotificationCenterDelegateAssigningDoesSwizzle {
55178 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter ];
@@ -93,4 +216,102 @@ - (void)testUNUserNotificationCenterDelegateAssignedBeforeOneSignal {
93216 XCTAssertNotEqual (originalDummyImp, swizzledDummyImp);
94217}
95218
219+ - (void )testForwardingTargetForSelector {
220+ UNUserNotificationCenterDelegateForwardReceiver *receiver = [UNUserNotificationCenterDelegateForwardReceiver new ];
221+ id myNotifCenterDelegate = [[UNUserNotificationCenterDelegateForwardingTargetForSelectorTest alloc ]
222+ initForwardingTarget: receiver];
223+ UNUserNotificationCenter .currentNotificationCenter .delegate = myNotifCenterDelegate;
224+ id <UNUserNotificationCenterDelegate > notifCenterDelegate = UNUserNotificationCenter .currentNotificationCenter .delegate ;
225+
226+ [notifCenterDelegate userNotificationCenter: UNUserNotificationCenter .currentNotificationCenter
227+ willPresentNotification: [self createBasiciOSNotification ]
228+ withCompletionHandler: ^(UNNotificationPresentationOptions options) {}];
229+ XCTAssertTrue ([receiver->selectorCallsDict
230+ objectForKey: NSStringFromSelector (
231+ @selector (userNotificationCenter:willPresentNotification:withCompletionHandler: )
232+ )
233+ ]);
234+ [notifCenterDelegate userNotificationCenter: UNUserNotificationCenter .currentNotificationCenter
235+ didReceiveNotificationResponse: [self createBasiciOSNotificationResponse ]
236+ withCompletionHandler: ^{}];
237+ XCTAssertTrue ([receiver->selectorCallsDict
238+ objectForKey: NSStringFromSelector (
239+ @selector (userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: )
240+ )
241+ ]);
242+ if (@available (iOS 12.0 , *)) {
243+ [notifCenterDelegate userNotificationCenter: UNUserNotificationCenter .currentNotificationCenter
244+ openSettingsForNotification: [self createBasiciOSNotification ]];
245+ }
246+ XCTAssertTrue ([receiver->selectorCallsDict
247+ objectForKey: NSStringFromSelector (
248+ @selector (userNotificationCenter:openSettingsForNotification: )
249+ )
250+ ]);
251+ }
252+
253+ - (void )testForwardingTargetForNonOneSignalNotification {
254+ UNUserNotificationCenterDelegateForwardReceiver *receiver = [UNUserNotificationCenterDelegateForwardReceiver new ];
255+ id myNotifCenterDelegate = [[UNUserNotificationCenterDelegateForwardingTargetForSelectorTest alloc ]
256+ initForwardingTarget: receiver];
257+ UNUserNotificationCenter .currentNotificationCenter .delegate = myNotifCenterDelegate;
258+ id <UNUserNotificationCenterDelegate > notifCenterDelegate = UNUserNotificationCenter .currentNotificationCenter .delegate ;
259+
260+ [notifCenterDelegate userNotificationCenter: UNUserNotificationCenter .currentNotificationCenter
261+ willPresentNotification: [self createNonOneSignaliOSNotification ]
262+ withCompletionHandler: ^(UNNotificationPresentationOptions options) {}];
263+ XCTAssertTrue ([receiver->selectorCallsDict
264+ objectForKey: NSStringFromSelector (
265+ @selector (userNotificationCenter:willPresentNotification:withCompletionHandler: )
266+ )
267+ ]);
268+ }
269+
270+ - (void )testDoubleSwizzleInfiniteLoop {
271+ // 1. Save original delegate
272+ id <UNUserNotificationCenterDelegate > localOrignalDelegate = UNUserNotificationCenter .currentNotificationCenter .delegate ;
273+
274+ // 2. Create a new delegate and assign it
275+ id myDelegate = [UNUserNotificationCenterDelegateForInfiniteLoopTest new ];
276+ UNUserNotificationCenter .currentNotificationCenter .delegate = myDelegate;
277+
278+ // 3. Put the original delegate back
279+ UNUserNotificationCenter .currentNotificationCenter .delegate = localOrignalDelegate;
280+
281+ // 4. Call something to confirm we don't get stuck in an infinite call loop
282+ [localOrignalDelegate userNotificationCenter: UNUserNotificationCenter .currentNotificationCenter willPresentNotification: [self createBasiciOSNotification ] withCompletionHandler: ^(UNNotificationPresentationOptions options) {}];
283+ }
284+
285+ - (void )testSwizzleExistingSelectors {
286+ UNUserNotificationCenterDelegateForExistingSelectorsTest* myNotifCenterDelegate = [UNUserNotificationCenterDelegateForExistingSelectorsTest new ];
287+ UNUserNotificationCenter .currentNotificationCenter .delegate = myNotifCenterDelegate;
288+ id <UNUserNotificationCenterDelegate > notifCenterDelegate = UNUserNotificationCenter .currentNotificationCenter .delegate ;
289+
290+ [notifCenterDelegate userNotificationCenter: UNUserNotificationCenter .currentNotificationCenter
291+ willPresentNotification: [self createBasiciOSNotification ]
292+ withCompletionHandler: ^(UNNotificationPresentationOptions options) {}];
293+ XCTAssertTrue ([myNotifCenterDelegate->selectorCallsDict
294+ objectForKey: NSStringFromSelector (
295+ @selector (userNotificationCenter:willPresentNotification:withCompletionHandler: )
296+ )
297+ ]);
298+ [notifCenterDelegate userNotificationCenter: UNUserNotificationCenter .currentNotificationCenter
299+ didReceiveNotificationResponse: [self createBasiciOSNotificationResponse ]
300+ withCompletionHandler: ^{}];
301+ XCTAssertTrue ([myNotifCenterDelegate->selectorCallsDict
302+ objectForKey: NSStringFromSelector (
303+ @selector (userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: )
304+ )
305+ ]);
306+ if (@available (iOS 12.0 , *)) {
307+ [notifCenterDelegate userNotificationCenter: UNUserNotificationCenter .currentNotificationCenter
308+ openSettingsForNotification: [self createBasiciOSNotification ]];
309+ }
310+ XCTAssertTrue ([myNotifCenterDelegate->selectorCallsDict
311+ objectForKey: NSStringFromSelector (
312+ @selector (userNotificationCenter:openSettingsForNotification: )
313+ )
314+ ]);
315+ }
316+
96317@end
0 commit comments