Flutter Engine
 
Loading...
Searching...
No Matches
FlutterSceneLifeCycleTest.mm
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import <Foundation/Foundation.h>
6#import <OCMock/OCMock.h>
7#import <UIKit/UIKit.h>
8#import <XCTest/XCTest.h>
9#include <objc/NSObject.h>
10
18
20
21// This class is meant to mimic the SceneDelegate class generated by SwiftUI that does not conform
22// FlutterSceneLifeCycleProvider but actually does.
23@interface FlutterSwiftUIAppSceneDelegate : NSObject
25@end
26
28
29@synthesize sceneLifeCycleDelegate = _sceneLifeCycleDelegate;
30
31- (instancetype)init {
32 if (self = [super init]) {
33 _sceneLifeCycleDelegate = [[FlutterPluginSceneLifeCycleDelegate alloc] init];
34 }
35 return self;
36}
37@end
38
39// This class is not referenced in test because it's a test itself. The implementation
40// verifies that sceneLifeCycleDelegate is a readonly property.
42@end
43@implementation TestSceneLifecycleProvider
44- (FlutterPluginSceneLifeCycleDelegate*)sceneLifeCycleDelegate {
45 return [[FlutterPluginSceneLifeCycleDelegate alloc] init];
46}
47@end
48
49@interface FlutterSceneLifecycleTest : XCTestCase
50@end
51
52@implementation FlutterSceneLifecycleTest
53- (void)setUp {
54}
55
56- (void)tearDown {
57}
58
59#pragma mark - FlutterPluginSceneLifeCycleDelegate
60
61- (void)testAddFlutterManagedEngine {
64
65 id mockEngine = OCMClassMock([FlutterEngine class]);
66 id mockLifecycleDelegate = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
67 OCMStub([mockEngine sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
68
69 [delegate addFlutterManagedEngine:mockEngine];
70 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
71}
72
73- (void)testAddDuplicateFlutterEngine {
76
77 id mockEngine = OCMClassMock([FlutterEngine class]);
78 id mockLifecycleDelegate = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
79 OCMStub([mockEngine sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
80
81 [delegate addFlutterManagedEngine:mockEngine];
82 [delegate addFlutterManagedEngine:mockEngine];
83 [delegate addFlutterManagedEngine:mockEngine];
84 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
85}
86
87- (void)testAddMultipleFlutterEngine {
90
91 id mockEngine = OCMClassMock([FlutterEngine class]);
92 id mockLifecycleDelegate = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
93 OCMStub([mockEngine sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
94 [delegate addFlutterManagedEngine:mockEngine];
95
96 id mockEngine2 = OCMClassMock([FlutterEngine class]);
97 id mockLifecycleDelegate2 = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
98 OCMStub([mockEngine2 sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate2);
99 [delegate addFlutterManagedEngine:mockEngine2];
100
101 XCTAssertEqual(delegate.flutterManagedEngines.count, 2.0);
102}
103
104- (void)testRemoveFlutterManagedEngine {
107
108 id mockEngine = OCMClassMock([FlutterEngine class]);
109 [delegate addFlutterManagedEngine:mockEngine];
110 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
111
112 [delegate removeFlutterManagedEngine:mockEngine];
113 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
114}
115
116- (void)testRemoveNotFoundFlutterEngine {
119
120 id mockEngine = OCMClassMock([FlutterEngine class]);
121 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
122
123 [delegate removeFlutterManagedEngine:mockEngine];
124 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
125}
126
127- (void)testupdateFlutterManagedEnginesInSceneRemovesDeallocatedEngine {
130
131 id mockWindowScene = OCMClassMock([UIWindowScene class]);
132
133 @autoreleasepool {
134 id mockEngine = OCMClassMock([FlutterEngine class]);
135 [delegate addFlutterManagedEngine:mockEngine];
136 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
137 }
138
139 [delegate updateFlutterManagedEnginesInScene:mockWindowScene];
140 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
141}
142
143- (void)testupdateFlutterManagedEnginesInSceneRemovesEngineNotInScene {
146
147 id mockEngine = OCMClassMock([FlutterEngine class]);
148 id mockViewController = OCMClassMock([UIViewController class]);
149 id mockView = OCMClassMock([UIView class]);
150 id mockWindow = OCMClassMock([UIWindow class]);
151 id mockWindowScene = OCMClassMock([UIWindowScene class]);
152 id mockLifecycleProvider = OCMProtocolMock(@protocol(FlutterSceneLifeCycleProvider));
153 id mockLifecycleDelegate = OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
154 OCMStub([mockEngine viewController]).andReturn(mockViewController);
155 OCMStub([mockViewController view]).andReturn(mockView);
156 OCMStub([mockView window]).andReturn(mockWindow);
157 OCMStub([mockWindow windowScene]).andReturn(mockWindowScene);
158 OCMStub([mockWindow windowScene]).andReturn(mockWindowScene);
159 OCMStub([mockWindowScene delegate]).andReturn(mockLifecycleProvider);
160 OCMStub([mockLifecycleProvider sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
161
162 [delegate addFlutterManagedEngine:mockEngine];
163 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
164
165 id mockWindowScene2 = OCMClassMock([UIWindowScene class]);
166
167 [delegate updateFlutterManagedEnginesInScene:mockWindowScene2];
168 OCMVerify(times(1), [mockLifecycleDelegate addFlutterManagedEngine:mockEngine]);
169 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
170}
171
172- (void)testupdateFlutterManagedEnginesInSceneDoesNotRemoveEngineWithNilScene {
175 id mockEngine = OCMClassMock([FlutterEngine class]);
176 id mockWindowScene = OCMClassMock([UIWindowScene class]);
177 [delegate addFlutterManagedEngine:mockEngine];
178 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
179
180 [delegate updateFlutterManagedEnginesInScene:mockWindowScene];
181 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
182}
183
184- (void)testManuallyRegisterSceneLifeCycleWithFlutterEngine {
187
188 id mockEngine = OCMClassMock([FlutterEngine class]);
189 id mockLifecycleDelegate = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
190 OCMStub([mockEngine sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
191
192 [delegate registerSceneLifeCycleWithFlutterEngine:mockEngine];
193 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
194 XCTAssertEqual(delegate.developerManagedEngines.count, 1.0);
195}
196
197- (void)testManuallyUnregisterSceneLifeCycleWithFlutterEngine {
200
201 id mockEngine = OCMClassMock([FlutterEngine class]);
202 id mockLifecycleDelegate = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
203 OCMStub([mockEngine sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
204
205 [delegate registerSceneLifeCycleWithFlutterEngine:mockEngine];
206 [delegate unregisterSceneLifeCycleWithFlutterEngine:mockEngine];
207 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
208 XCTAssertEqual(delegate.developerManagedEngines.count, 0.0);
209}
210
211- (void)testManuallyRegisterSceneLifeCycleWithFlutterEngineCannotBeAutoAdded {
214
215 FlutterEngine* engine = [[FlutterEngine alloc] init];
216 id mockEngine = OCMPartialMock(engine);
217 id mockLifecycleDelegate = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
218 OCMStub([mockEngine sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
219
220 [delegate registerSceneLifeCycleWithFlutterEngine:mockEngine];
221 [delegate addFlutterManagedEngine:mockEngine];
222 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
223 XCTAssertEqual(delegate.developerManagedEngines.count, 1.0);
224
225 [delegate unregisterSceneLifeCycleWithFlutterEngine:mockEngine];
226 [delegate addFlutterManagedEngine:mockEngine];
227 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
228 XCTAssertEqual(delegate.developerManagedEngines.count, 0.0);
229
230 [delegate registerSceneLifeCycleWithFlutterEngine:mockEngine];
231 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
232 XCTAssertEqual(delegate.developerManagedEngines.count, 1.0);
233}
234
235- (void)testManuallyRegisterSceneLifeCycleWithFlutterEngineCannotBeAutoRemoved {
238
239 id mockEngine = OCMClassMock([FlutterEngine class]);
240 id mockLifecycleDelegate = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
241 OCMStub([mockEngine sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
242
243 [delegate registerSceneLifeCycleWithFlutterEngine:mockEngine];
244 [delegate removeFlutterManagedEngine:mockEngine];
245 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
246 XCTAssertEqual(delegate.developerManagedEngines.count, 1.0);
247}
248
249- (void)testManuallyRegisterSceneLifeCycleWithFlutterEngineRemovesAutomatic {
252
253 id mockEngine = OCMClassMock([FlutterEngine class]);
254 id mockLifecycleDelegate = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
255 OCMStub([mockEngine sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
256
257 [delegate addFlutterManagedEngine:mockEngine];
258 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
259 [delegate registerSceneLifeCycleWithFlutterEngine:mockEngine];
260 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
261 XCTAssertEqual(delegate.developerManagedEngines.count, 1.0);
262}
263
264- (void)testAllEnginesContainsManualAndAutomatic {
267
268 id mockEngine = OCMClassMock([FlutterEngine class]);
269 id mockLifecycleDelegate = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
270 OCMStub([mockEngine sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
271
272 id mockEngine2 = OCMClassMock([FlutterEngine class]);
273
274 [delegate addFlutterManagedEngine:mockEngine];
275 [delegate registerSceneLifeCycleWithFlutterEngine:mockEngine2];
276
277 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
278 XCTAssertEqual(delegate.developerManagedEngines.count, 1.0);
279 XCTAssertEqual(delegate.allEngines.count, 2.0);
280 XCTAssertEqual([delegate.allEngines objectAtIndex:0], mockEngine);
281 XCTAssertEqual([delegate.allEngines objectAtIndex:1], mockEngine2);
282}
283
284- (void)testEngineReceivedConnectNotificationForSceneBeforeActualEvent {
287 FlutterPluginSceneLifeCycleDelegate* mockDelegate = OCMPartialMock(delegate);
288 id mocks = [self mocksForEvents];
289 id mockEngine = mocks[@"mockEngine"];
290 id mockScene = mocks[@"mockScene"];
291 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
292 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
293 OCMStub([mockLifecycleDelegate scene:[OCMArg any]
294 willConnectToSession:[OCMArg any]
295 options:[OCMArg any]])
296 .andReturn(YES);
297
298 id mocks2 = [self mocksForEvents];
299 id mockEngine2 = mocks2[@"mockEngine"];
300 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate2 =
301 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks2[@"mockLifecycleDelegate"];
302 OCMStub([mockLifecycleDelegate2 scene:[OCMArg any]
303 willConnectToSession:[OCMArg any]
304 options:[OCMArg any]])
305 .andReturn(YES);
306
307 // received notification
308 [mockDelegate engine:mockEngine receivedConnectNotificationFor:mockScene];
309 [mockDelegate engine:mockEngine2 receivedConnectNotificationFor:mockScene];
310 OCMVerify(times(1), [mockDelegate addFlutterManagedEngine:mockEngine]);
311 OCMVerify(times(1), [mockDelegate addFlutterManagedEngine:mockEngine2]);
312 XCTAssertEqual(delegate.flutterManagedEngines.count, 2.0);
313 OCMVerify(times(0), [mockDelegate scene:[OCMArg any]
314 willConnectToSession:[OCMArg any]
315 options:[OCMArg any]]);
316
317 // actual event
318 id session = OCMClassMock([UISceneSession class]);
319 id options = OCMClassMock([UISceneConnectionOptions class]);
320 [mockDelegate scene:mockScene willConnectToSession:session options:options];
321 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene
322 willConnectToSession:session
323 options:options]);
324 OCMVerify(times(1), [mockLifecycleDelegate2 scene:mockScene
325 willConnectToSession:session
326 options:nil]);
327 XCTAssertEqual(delegate.flutterManagedEngines.count, 2.0);
328}
329
330- (void)testEngineReceivedConnectNotificationForSceneAfterActualEvent {
333 FlutterPluginSceneLifeCycleDelegate* mockDelegate = OCMPartialMock(delegate);
334 id mocks = [self mocksForEvents];
335 id mockEngine = mocks[@"mockEngine"];
336 id mockScene = mocks[@"mockScene"];
337 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
338 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
339 OCMStub([mockLifecycleDelegate scene:[OCMArg any]
340 willConnectToSession:[OCMArg any]
341 options:[OCMArg any]])
342 .andReturn(YES);
343 id mocks2 = [self mocksForEvents];
344 id mockEngine2 = mocks2[@"mockEngine"];
345 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate2 =
346 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks2[@"mockLifecycleDelegate"];
347 OCMStub([mockLifecycleDelegate2 scene:[OCMArg any]
348 willConnectToSession:[OCMArg any]
349 options:[OCMArg any]])
350 .andReturn(YES);
351
352 // actual event
353 id session = OCMClassMock([UISceneSession class]);
354 id options = OCMClassMock([UISceneConnectionOptions class]);
355 OCMStub([mockScene session]).andReturn(session);
356 [mockDelegate scene:mockScene willConnectToSession:session options:options];
357 XCTAssertEqual(delegate.flutterManagedEngines.count, 0.0);
358 OCMVerify(times(0), [mockLifecycleDelegate scene:mockScene
359 willConnectToSession:session
360 options:options]);
361 OCMVerify(times(0), [mockLifecycleDelegate2 scene:mockScene
362 willConnectToSession:session
363 options:options]);
364 OCMStub([mockDelegate connectionOptions]).andReturn(options);
365
366 // received notification
367 [mockDelegate engine:mockEngine receivedConnectNotificationFor:mockScene];
368 [mockDelegate engine:mockEngine2 receivedConnectNotificationFor:mockScene];
369
370 OCMVerify(times(1), [mockDelegate addFlutterManagedEngine:mockEngine]);
371 OCMVerify(times(1), [mockDelegate addFlutterManagedEngine:mockEngine2]);
372 XCTAssertEqual(delegate.flutterManagedEngines.count, 2.0);
373 OCMVerify(times(1), [mockDelegate scene:mockScene willConnectToSession:session options:options]);
374 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene
375 willConnectToSession:session
376 options:options]);
377 OCMVerify(times(1), [mockLifecycleDelegate2 scene:mockScene
378 willConnectToSession:session
379 options:nil]);
380}
381
382- (void)testSceneWillConnectToSessionOptionsHandledByScenePlugin {
385
386 id mocks = [self mocksForEvents];
387 id mockEngine = mocks[@"mockEngine"];
388 id mockScene = mocks[@"mockScene"];
389 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
390 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
391 OCMStub([mockLifecycleDelegate scene:[OCMArg any]
392 willConnectToSession:[OCMArg any]
393 options:[OCMArg any]])
394 .andReturn(YES);
395 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
396 OCMStub([mockAppLifecycleDelegate sceneWillConnectFallback:[OCMArg any]]).andReturn(YES);
397
398 id session = OCMClassMock([UISceneSession class]);
399 id options = OCMClassMock([UISceneConnectionOptions class]);
400
401 [delegate addFlutterManagedEngine:mockEngine];
402 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
403
404 [delegate scene:mockScene willConnectToSession:session options:options];
405 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene
406 willConnectToSession:session
407 options:options]);
408 OCMVerify(times(0), [mockAppLifecycleDelegate sceneWillConnectFallback:options]);
409 OCMVerify(times(0), [mockEngine sendDeepLinkToFramework:[OCMArg any]
410 completionHandler:[OCMArg any]]);
411}
412
413- (void)testSceneWillConnectToSessionOptionsHandledByApplicationPlugin {
416
417 id mocks = [self mocksForEvents];
418 id mockEngine = mocks[@"mockEngine"];
419 id mockScene = mocks[@"mockScene"];
420 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
421 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
422 OCMStub([mockLifecycleDelegate scene:[OCMArg any]
423 willConnectToSession:[OCMArg any]
424 options:[OCMArg any]])
425 .andReturn(NO);
426 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
427 OCMStub([mockAppLifecycleDelegate sceneWillConnectFallback:[OCMArg any]]).andReturn(YES);
428
429 id session = OCMClassMock([UISceneSession class]);
430 id options = OCMClassMock([UISceneConnectionOptions class]);
431
432 [delegate addFlutterManagedEngine:mockEngine];
433 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
434
435 [delegate scene:mockScene willConnectToSession:session options:options];
436 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene
437 willConnectToSession:session
438 options:options]);
439 OCMVerify(times(1), [mockAppLifecycleDelegate sceneWillConnectFallback:options]);
440 OCMVerify(times(0), [mockEngine sendDeepLinkToFramework:[OCMArg any]
441 completionHandler:[OCMArg any]]);
442}
443
444- (void)testSceneWillConnectToSessionOptionsHandledByApplicationPluginMultipleEngines {
447
448 id mocks = [self mocksForEvents];
449 id mockEngine = mocks[@"mockEngine"];
450 id mockScene = mocks[@"mockScene"];
451 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
452 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
453 OCMStub([mockLifecycleDelegate scene:[OCMArg any]
454 willConnectToSession:[OCMArg any]
455 options:[OCMArg any]])
456 .andReturn(NO);
457
458 id mocks2 = [self mocksForEvents];
459 id mockEngine2 = mocks2[@"mockEngine"];
460 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate2 =
461 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks2[@"mockLifecycleDelegate"];
462 OCMStub([mockLifecycleDelegate2 scene:[OCMArg any]
463 willConnectToSession:[OCMArg any]
464 options:[OCMArg any]])
465 .andReturn(NO);
466
467 id mockAppLifecycleDelegate = mocks2[@"mockAppLifecycleDelegate"];
468 OCMStub([mockAppLifecycleDelegate sceneWillConnectFallback:[OCMArg any]]).andReturn(YES);
469 id session = OCMClassMock([UISceneSession class]);
470 id options = OCMClassMock([UISceneConnectionOptions class]);
471
472 [delegate addFlutterManagedEngine:mockEngine];
473 [delegate addFlutterManagedEngine:mockEngine2];
474 XCTAssertEqual(delegate.flutterManagedEngines.count, 2.0);
475
476 [delegate scene:mockScene willConnectToSession:session options:options];
477 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene
478 willConnectToSession:session
479 options:options]);
480 OCMVerify(times(1), [mockLifecycleDelegate2 scene:mockScene
481 willConnectToSession:session
482 options:nil]);
483 OCMVerify(times(1), [mockAppLifecycleDelegate sceneWillConnectFallback:options]);
484 OCMVerify(times(0), [mockEngine sendDeepLinkToFramework:[OCMArg any]
485 completionHandler:[OCMArg any]]);
486}
487
488- (void)testSceneWillConnectToSessionOptionsHandledByUniversalLinks {
491
492 id mocks = [self mocksForEvents];
493 id mockEngine = mocks[@"mockEngine"];
494 id mockScene = mocks[@"mockScene"];
495 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
496 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
497 OCMStub([mockLifecycleDelegate scene:[OCMArg any]
498 willConnectToSession:[OCMArg any]
499 options:[OCMArg any]])
500 .andReturn(NO);
501
502 id session = OCMClassMock([UISceneSession class]);
503 id options = OCMClassMock([UISceneConnectionOptions class]);
504 id userActivity = OCMClassMock([NSUserActivity class]);
505 id flutterApp = OCMClassMock([FlutterSharedApplication class]);
506 NSURL* url = [NSURL URLWithString:@"example.com"];
507 OCMStub([userActivity webpageURL]).andReturn(url);
508 NSSet<NSUserActivity*>* userActivities = [NSSet setWithObjects:userActivity, nil];
509 OCMStub([options userActivities]).andReturn(userActivities);
510 OCMStub([flutterApp isFlutterDeepLinkingEnabled]).andReturn(YES);
511
512 [delegate addFlutterManagedEngine:mockEngine];
513 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
514
515 [delegate scene:mockScene willConnectToSession:session options:options];
516 OCMVerify(times(1), [mockEngine sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
517}
518
519- (void)testSceneWillConnectToSessionOptionsHandledByDeepLinks {
522
523 id mocks = [self mocksForEvents];
524 id mockEngine = mocks[@"mockEngine"];
525 id mockScene = mocks[@"mockScene"];
526 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
527 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
528 OCMStub([mockLifecycleDelegate scene:[OCMArg any]
529 willConnectToSession:[OCMArg any]
530 options:[OCMArg any]])
531 .andReturn(NO);
532
533 id session = OCMClassMock([UISceneSession class]);
534 id options = OCMClassMock([UISceneConnectionOptions class]);
535 id flutterApp = OCMClassMock([FlutterSharedApplication class]);
536 NSURL* url = [NSURL URLWithString:@"example.com"];
537 OCMStub([flutterApp isFlutterDeepLinkingEnabled]).andReturn(YES);
538 id urlContext = OCMClassMock([UIOpenURLContext class]);
539 OCMStub([urlContext URL]).andReturn(url);
540 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
541 OCMStub([options URLContexts]).andReturn(urlContexts);
542
543 [delegate addFlutterManagedEngine:mockEngine];
544 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
545
546 [delegate scene:mockScene willConnectToSession:session options:options];
547 OCMVerify(times(1), [mockEngine sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
548}
549
550- (void)testSceneWillConnectToSessionOptionsHandledByNoPlugin {
553
554 id mocks = [self mocksForEvents];
555 id mockEngine = mocks[@"mockEngine"];
556 id mockScene = mocks[@"mockScene"];
557 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
558 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
559 OCMStub([mockLifecycleDelegate scene:[OCMArg any]
560 willConnectToSession:[OCMArg any]
561 options:[OCMArg any]])
562 .andReturn(NO);
563
564 id session = OCMClassMock([UISceneSession class]);
565 id options = OCMClassMock([UISceneConnectionOptions class]);
566 id userActivity = OCMClassMock([NSUserActivity class]);
567 id flutterApp = OCMClassMock([FlutterSharedApplication class]);
568 NSURL* url = [NSURL URLWithString:@"example.com"];
569 OCMStub([userActivity webpageURL]).andReturn(url);
570 NSSet<NSUserActivity*>* userActivities = [NSSet setWithObjects:userActivity, nil];
571 OCMStub([options userActivities]).andReturn(userActivities);
572 OCMStub([flutterApp isFlutterDeepLinkingEnabled]).andReturn(NO);
573
574 [delegate addFlutterManagedEngine:mockEngine];
575 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
576
577 [delegate scene:mockScene willConnectToSession:session options:options];
578 OCMVerify(times(0), [mockEngine sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
579}
580
581- (void)testSceneWillConnectToSessionAddsEngineFromRootViewController {
584 FlutterPluginSceneLifeCycleDelegate* mockDelegate = OCMPartialMock(delegate);
585
586 id mockScene = OCMClassMock([UIWindowScene class]);
587 id mockWindow = OCMClassMock([UIWindow class]);
588 id mockViewController = OCMClassMock([FlutterViewController class]);
589 id mockEngine = OCMClassMock([FlutterEngine class]);
590 id mockSceneDelegate = OCMProtocolMock(@protocol(UIWindowSceneDelegate));
591
592 OCMStub([mockScene delegate]).andReturn(mockSceneDelegate);
593 OCMStub([mockSceneDelegate window]).andReturn(mockWindow);
594 OCMStub([mockWindow rootViewController]).andReturn(mockViewController);
595 OCMStub([mockViewController engine]).andReturn(mockEngine);
596
597 id session = OCMClassMock([UISceneSession class]);
598 id options = OCMClassMock([UISceneConnectionOptions class]);
599
600 [mockDelegate scene:mockScene willConnectToSession:session options:options];
601
602 OCMVerify(times(1), [mockDelegate addFlutterManagedEngine:mockEngine]);
603 OCMVerify(times(1), [mockDelegate scene:mockScene
604 willConnectToSession:session
605 flutterEngine:mockEngine
606 options:options]);
607}
608
609- (void)testSceneWillConnectToSessionAddsEngineFromRootViewControllerAndNotNotification {
612 FlutterPluginSceneLifeCycleDelegate* mockDelegate = OCMPartialMock(delegate);
613
614 id mockScene = OCMClassMock([UIWindowScene class]);
615 id mockWindow = OCMClassMock([UIWindow class]);
616 id mockViewController = OCMClassMock([FlutterViewController class]);
617 id mockEngine = OCMClassMock([FlutterEngine class]);
618 id mockSceneDelegate = OCMProtocolMock(@protocol(UIWindowSceneDelegate));
619
620 OCMStub([mockScene delegate]).andReturn(mockSceneDelegate);
621 OCMStub([mockSceneDelegate window]).andReturn(mockWindow);
622 OCMStub([mockWindow rootViewController]).andReturn(mockViewController);
623 OCMStub([mockViewController engine]).andReturn(mockEngine);
624
625 id session = OCMClassMock([UISceneSession class]);
626 id options = OCMClassMock([UISceneConnectionOptions class]);
627
628 [mockDelegate scene:mockScene willConnectToSession:session options:options];
629 [mockDelegate engine:mockEngine receivedConnectNotificationFor:mockScene];
630
631 OCMVerify(times(2), [mockDelegate addFlutterManagedEngine:mockEngine]);
632 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
633 OCMVerify(times(1), [mockDelegate scene:mockScene
634 willConnectToSession:session
635 flutterEngine:mockEngine
636 options:options]);
637}
638
639- (void)testSceneDidDisconnect {
642
643 id mocks = [self mocksForEvents];
644 id mockEngine = mocks[@"mockEngine"];
645 id mockScene = mocks[@"mockScene"];
646 id mockLifecycleDelegate = mocks[@"mockLifecycleDelegate"];
647
648 [delegate addFlutterManagedEngine:mockEngine];
649 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
650
651 [delegate sceneDidDisconnect:mockScene];
652 OCMVerify(times(1), [mockLifecycleDelegate sceneDidDisconnect:mockScene]);
653}
654
655- (void)testSceneWillEnterForeground {
658
659 id mocks = [self mocksForEvents];
660 id mockEngine = mocks[@"mockEngine"];
661 id mockScene = mocks[@"mockScene"];
662 id mockLifecycleDelegate = mocks[@"mockLifecycleDelegate"];
663 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
664
665 [delegate addFlutterManagedEngine:mockEngine];
666 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
667
668 [delegate sceneWillEnterForeground:mockScene];
669 OCMVerify(times(1), [mockLifecycleDelegate sceneWillEnterForeground:mockScene]);
670 OCMVerify(times(1), [mockAppLifecycleDelegate sceneWillEnterForegroundFallback]);
671}
672
673- (void)testSceneDidBecomeActive {
676
677 id mocks = [self mocksForEvents];
678 id mockEngine = mocks[@"mockEngine"];
679 id mockScene = mocks[@"mockScene"];
680 id mockLifecycleDelegate = mocks[@"mockLifecycleDelegate"];
681 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
682
683 [delegate addFlutterManagedEngine:mockEngine];
684 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
685
686 [delegate sceneDidBecomeActive:mockScene];
687 OCMVerify(times(1), [mockLifecycleDelegate sceneDidBecomeActive:mockScene]);
688 OCMVerify(times(1), [mockAppLifecycleDelegate sceneDidBecomeActiveFallback]);
689}
690
691- (void)testSceneWillResignActive {
694
695 id mocks = [self mocksForEvents];
696 id mockEngine = mocks[@"mockEngine"];
697 id mockScene = mocks[@"mockScene"];
698 id mockLifecycleDelegate = mocks[@"mockLifecycleDelegate"];
699 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
700
701 [delegate addFlutterManagedEngine:mockEngine];
702 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
703
704 [delegate sceneWillResignActive:mockScene];
705 OCMVerify(times(1), [mockLifecycleDelegate sceneWillResignActive:mockScene]);
706 OCMVerify(times(1), [mockAppLifecycleDelegate sceneWillResignActiveFallback]);
707}
708
709- (void)testSceneDidEnterBackground {
712
713 id mocks = [self mocksForEvents];
714 id mockEngine = mocks[@"mockEngine"];
715 id mockScene = mocks[@"mockScene"];
716 id mockLifecycleDelegate = mocks[@"mockLifecycleDelegate"];
717 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
718
719 [delegate addFlutterManagedEngine:mockEngine];
720 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
721
722 [delegate sceneDidEnterBackground:mockScene];
723 OCMVerify(times(1), [mockLifecycleDelegate sceneDidEnterBackground:mockScene]);
724 OCMVerify(times(1), [mockAppLifecycleDelegate sceneDidEnterBackgroundFallback]);
725}
726
727- (void)testSceneOpenURLContextsHandledByScenePlugin {
730
731 id mocks = [self mocksForEvents];
732 id mockEngine = mocks[@"mockEngine"];
733 id mockScene = mocks[@"mockScene"];
734 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
735 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
736 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
737 OCMStub([mockLifecycleDelegate scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(YES);
738 OCMStub([mockAppLifecycleDelegate sceneFallbackOpenURLContexts:[OCMArg any]]).andReturn(YES);
739
740 id urlContext = OCMClassMock([UIOpenURLContext class]);
741 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
742
743 [delegate addFlutterManagedEngine:mockEngine];
744 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
745
746 [delegate scene:mockScene openURLContexts:urlContexts];
747 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene openURLContexts:urlContexts]);
748 OCMVerify(times(0), [mockAppLifecycleDelegate sceneFallbackOpenURLContexts:urlContexts]);
749}
750
751- (void)testSceneOpenURLContextsHandledByApplicationPlugin {
754
755 id mocks = [self mocksForEvents];
756 id mockEngine = mocks[@"mockEngine"];
757 id mockScene = mocks[@"mockScene"];
758 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
759 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
760 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
761 OCMStub([mockLifecycleDelegate scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(NO);
762 OCMStub([mockAppLifecycleDelegate sceneFallbackOpenURLContexts:[OCMArg any]]).andReturn(YES);
763
764 id urlContext = OCMClassMock([UIOpenURLContext class]);
765 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
766
767 [delegate addFlutterManagedEngine:mockEngine];
768 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
769
770 [delegate scene:mockScene openURLContexts:urlContexts];
771 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene openURLContexts:urlContexts]);
772 OCMVerify(times(1), [mockAppLifecycleDelegate sceneFallbackOpenURLContexts:urlContexts]);
773}
774
775- (void)testSceneOpenURLContextsHandledByDeeplink {
778
779 id mocks = [self mocksForEvents];
780 id mockEngine = mocks[@"mockEngine"];
781 id mockScene = mocks[@"mockScene"];
782 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
783 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
784 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
785 OCMStub([mockLifecycleDelegate scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(NO);
786 OCMStub([mockAppLifecycleDelegate sceneFallbackOpenURLContexts:[OCMArg any]]).andReturn(NO);
787 id flutterApp = OCMClassMock([FlutterSharedApplication class]);
788 OCMStub([flutterApp isFlutterDeepLinkingEnabled]).andReturn(YES);
789
790 NSURL* url = [NSURL URLWithString:@"example.com"];
791 id urlContext = OCMClassMock([UIOpenURLContext class]);
792 OCMStub([urlContext URL]).andReturn(url);
793 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
794
795 [delegate addFlutterManagedEngine:mockEngine];
796 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
797
798 [delegate scene:mockScene openURLContexts:urlContexts];
799 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene openURLContexts:urlContexts]);
800 OCMVerify(times(1), [mockAppLifecycleDelegate sceneFallbackOpenURLContexts:urlContexts]);
801 OCMVerify(times(1), [mockEngine sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
802}
803
804- (void)testSceneOpenURLContextsHandledByNoPlugin {
807
808 id mocks = [self mocksForEvents];
809 id mockEngine = mocks[@"mockEngine"];
810 id mockScene = mocks[@"mockScene"];
811 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
812 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
813 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
814 OCMStub([mockLifecycleDelegate scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(NO);
815 OCMStub([mockAppLifecycleDelegate sceneFallbackOpenURLContexts:[OCMArg any]]).andReturn(NO);
816 id flutterApp = OCMClassMock([FlutterSharedApplication class]);
817 OCMStub([flutterApp isFlutterDeepLinkingEnabled]).andReturn(NO);
818
819 id urlContext = OCMClassMock([UIOpenURLContext class]);
820 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
821
822 [delegate addFlutterManagedEngine:mockEngine];
823 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
824
825 [delegate scene:mockScene openURLContexts:urlContexts];
826 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene openURLContexts:urlContexts]);
827 OCMVerify(times(1), [mockAppLifecycleDelegate sceneFallbackOpenURLContexts:urlContexts]);
828}
829
830- (void)testSceneOpenURLContextsWithMultipleEnginesSomeHandledByPlugin {
833
834 id mocks = [self mocksForEvents];
835 id mockScene = mocks[@"mockScene"];
836 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
837
838 id mockEngine1 = OCMClassMock([FlutterEngine class]);
839 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate1 =
840 OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
841 OCMStub([mockEngine1 sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate1);
842 OCMStub([mockLifecycleDelegate1 scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(YES);
843
844 id mockEngine2 = OCMClassMock([FlutterEngine class]);
845 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate2 =
846 OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
847 OCMStub([mockEngine2 sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate2);
848 OCMStub([mockLifecycleDelegate2 scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(NO);
849
850 id flutterApp = OCMClassMock([FlutterSharedApplication class]);
851 OCMStub([flutterApp isFlutterDeepLinkingEnabled]).andReturn(YES);
852
853 NSURL* url = [NSURL URLWithString:@"example.com"];
854 id urlContext = OCMClassMock([UIOpenURLContext class]);
855 OCMStub([urlContext URL]).andReturn(url);
856 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
857
858 [delegate addFlutterManagedEngine:mockEngine1];
859 [delegate addFlutterManagedEngine:mockEngine2];
860
861 [delegate scene:mockScene openURLContexts:urlContexts];
862
863 OCMVerify(times(1), [mockLifecycleDelegate1 scene:mockScene openURLContexts:urlContexts]);
864 OCMVerify(times(1), [mockLifecycleDelegate2 scene:mockScene openURLContexts:urlContexts]);
865 OCMVerify(times(0), [mockAppLifecycleDelegate sceneFallbackOpenURLContexts:urlContexts]);
866 OCMVerify(times(0), [mockEngine1 sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
867 OCMVerify(times(1), [mockEngine2 sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
868}
869
870- (void)testSceneOpenURLContextsWithMultipleEnginesHandledByApplication {
873
874 id mocks = [self mocksForEvents];
875 id mockScene = mocks[@"mockScene"];
876 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
877 OCMStub([mockAppLifecycleDelegate sceneFallbackOpenURLContexts:[OCMArg any]]).andReturn(YES);
878
879 id mockEngine1 = OCMClassMock([FlutterEngine class]);
880 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate1 =
881 OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
882 OCMStub([mockEngine1 sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate1);
883 OCMStub([mockLifecycleDelegate1 scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(NO);
884
885 id mockEngine2 = OCMClassMock([FlutterEngine class]);
886 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate2 =
887 OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
888 OCMStub([mockEngine2 sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate2);
889 OCMStub([mockLifecycleDelegate2 scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(NO);
890
891 id flutterApp = OCMClassMock([FlutterSharedApplication class]);
892 OCMStub([flutterApp isFlutterDeepLinkingEnabled]).andReturn(YES);
893
894 NSURL* url = [NSURL URLWithString:@"example.com"];
895 id urlContext = OCMClassMock([UIOpenURLContext class]);
896 OCMStub([urlContext URL]).andReturn(url);
897 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
898
899 [delegate addFlutterManagedEngine:mockEngine1];
900 [delegate addFlutterManagedEngine:mockEngine2];
901
902 [delegate scene:mockScene openURLContexts:urlContexts];
903
904 OCMVerify(times(1), [mockLifecycleDelegate1 scene:mockScene openURLContexts:urlContexts]);
905 OCMVerify(times(1), [mockLifecycleDelegate2 scene:mockScene openURLContexts:urlContexts]);
906 OCMVerify(times(1), [mockAppLifecycleDelegate sceneFallbackOpenURLContexts:urlContexts]);
907 OCMVerify(times(0), [mockEngine1 sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
908 OCMVerify(times(0), [mockEngine2 sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
909}
910
911- (void)testSceneOpenURLContextsWithMultipleEnginesHandledByDeeplink {
914
915 id mocks = [self mocksForEvents];
916 id mockScene = mocks[@"mockScene"];
917 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
918 OCMStub([mockAppLifecycleDelegate sceneFallbackOpenURLContexts:[OCMArg any]]).andReturn(NO);
919
920 id mockEngine1 = OCMClassMock([FlutterEngine class]);
921 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate1 =
922 OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
923 OCMStub([mockEngine1 sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate1);
924 OCMStub([mockLifecycleDelegate1 scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(NO);
925
926 id mockEngine2 = OCMClassMock([FlutterEngine class]);
927 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate2 =
928 OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
929 OCMStub([mockEngine2 sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate2);
930 OCMStub([mockLifecycleDelegate2 scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(NO);
931
932 id flutterApp = OCMClassMock([FlutterSharedApplication class]);
933 OCMStub([flutterApp isFlutterDeepLinkingEnabled]).andReturn(YES);
934
935 NSURL* url = [NSURL URLWithString:@"example.com"];
936 id urlContext = OCMClassMock([UIOpenURLContext class]);
937 OCMStub([urlContext URL]).andReturn(url);
938 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
939
940 [delegate addFlutterManagedEngine:mockEngine1];
941 [delegate addFlutterManagedEngine:mockEngine2];
942
943 [delegate scene:mockScene openURLContexts:urlContexts];
944
945 OCMVerify(times(1), [mockLifecycleDelegate1 scene:mockScene openURLContexts:urlContexts]);
946 OCMVerify(times(1), [mockLifecycleDelegate2 scene:mockScene openURLContexts:urlContexts]);
947 OCMVerify(times(1), [mockAppLifecycleDelegate sceneFallbackOpenURLContexts:urlContexts]);
948 OCMVerify(times(1), [mockEngine1 sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
949 OCMVerify(times(1), [mockEngine2 sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
950}
951
952- (void)testSceneContinueUserActivityHandledByScenePlugin {
955
956 id mocks = [self mocksForEvents];
957 id mockEngine = mocks[@"mockEngine"];
958 id mockScene = mocks[@"mockScene"];
959 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
960 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
961 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
962 OCMStub([mockLifecycleDelegate scene:[OCMArg any] continueUserActivity:[OCMArg any]])
963 .andReturn(YES);
964 OCMStub([mockAppLifecycleDelegate sceneFallbackContinueUserActivity:[OCMArg any]]).andReturn(YES);
965
966 id userActivity = OCMClassMock([NSUserActivity class]);
967
968 [delegate addFlutterManagedEngine:mockEngine];
969 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
970
971 [delegate scene:mockScene continueUserActivity:userActivity];
972 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene continueUserActivity:userActivity]);
973 OCMVerify(times(0), [mockAppLifecycleDelegate sceneFallbackContinueUserActivity:userActivity]);
974}
975
976- (void)testSceneContinueUserActivityHandledByApplicationPlugin {
979
980 id mocks = [self mocksForEvents];
981 id mockEngine = mocks[@"mockEngine"];
982 id mockScene = mocks[@"mockScene"];
983 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
984 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
985 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
986 OCMStub([mockLifecycleDelegate scene:[OCMArg any] continueUserActivity:[OCMArg any]])
987 .andReturn(NO);
988 OCMStub([mockAppLifecycleDelegate sceneFallbackContinueUserActivity:[OCMArg any]]).andReturn(YES);
989
990 id userActivity = OCMClassMock([NSUserActivity class]);
991
992 [delegate addFlutterManagedEngine:mockEngine];
993 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
994
995 [delegate scene:mockScene continueUserActivity:userActivity];
996 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene continueUserActivity:userActivity]);
997 OCMVerify(times(1), [mockAppLifecycleDelegate sceneFallbackContinueUserActivity:userActivity]);
998}
999
1000- (void)testSceneContinueUserActivityHandledByUniversalLinks {
1003
1004 id mocks = [self mocksForEvents];
1005 id mockEngine = mocks[@"mockEngine"];
1006 id mockScene = mocks[@"mockScene"];
1007 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
1008 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
1009 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
1010 OCMStub([mockLifecycleDelegate scene:[OCMArg any] continueUserActivity:[OCMArg any]])
1011 .andReturn(NO);
1012 OCMStub([mockAppLifecycleDelegate sceneFallbackContinueUserActivity:[OCMArg any]]).andReturn(NO);
1013 id flutterApp = OCMClassMock([FlutterSharedApplication class]);
1014 OCMStub([flutterApp isFlutterDeepLinkingEnabled]).andReturn(YES);
1015
1016 NSURL* url = [NSURL URLWithString:@"example.com"];
1017 id userActivity = OCMClassMock([NSUserActivity class]);
1018 OCMStub([userActivity webpageURL]).andReturn(url);
1019
1020 [delegate addFlutterManagedEngine:mockEngine];
1021 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
1022
1023 [delegate scene:mockScene continueUserActivity:userActivity];
1024 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene continueUserActivity:userActivity]);
1025 OCMVerify(times(1), [mockAppLifecycleDelegate sceneFallbackContinueUserActivity:userActivity]);
1026 OCMVerify(times(1), [mockEngine sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
1027}
1028
1029- (void)testStateRestorationActivityForScene {
1032
1033 id mocks = [self mocksForEvents];
1034 id mockEngine = mocks[@"mockEngine"];
1035 id mockViewController = OCMClassMock([FlutterViewController class]);
1036 id mockRestorationPlugin = OCMClassMock([FlutterRestorationPlugin class]);
1037 OCMStub([mockEngine viewController]).andReturn(mockViewController);
1038 OCMStub([mockEngine restorationPlugin]).andReturn(mockRestorationPlugin);
1039
1040 NSString* restorationId = @"restorationId";
1041 NSString* mockDataString = @"mockData";
1042 NSString* configName = @"ConfigurationName";
1043 NSData* mockData = [mockDataString dataUsingEncoding:NSUTF8StringEncoding];
1044 OCMStub([mockViewController restorationIdentifier]).andReturn(restorationId);
1045 OCMStub([mockRestorationPlugin restorationData]).andReturn(mockData);
1046
1047 id mockScene = mocks[@"mockScene"];
1048 id mockSession = OCMClassMock([UISceneSession class]);
1049 id mockConfiguration = OCMClassMock([UISceneConfiguration class]);
1050 OCMStub([mockScene session]).andReturn(mockSession);
1051 OCMStub([mockSession configuration]).andReturn(mockConfiguration);
1052 OCMStub([mockConfiguration name]).andReturn(configName);
1053
1054 [delegate addFlutterManagedEngine:mockEngine];
1055 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
1056 NSUserActivity* state = [delegate stateRestorationActivityForScene:mockScene];
1057 XCTAssertEqual(state.userInfo[restorationId], mockData);
1058 XCTAssertEqual(state.activityType, configName);
1059}
1060
1061- (void)testSceneRestoreInteractionStateWithUserActivity {
1064 id mockBundle = OCMPartialMock([NSBundle mainBundle]);
1065 id mockURL = OCMClassMock([NSURL class]);
1066 id mockFileDate = OCMClassMock([NSDate class]);
1067 int64_t mockBundleDateNum = 1;
1068
1069 OCMStub([mockBundle executableURL]).andReturn(mockURL);
1070 OCMStub([mockURL getResourceValue:[OCMArg setTo:mockFileDate]
1071 forKey:NSURLContentModificationDateKey
1072 error:[OCMArg setTo:nil]]);
1073 OCMStub([mockFileDate timeIntervalSince1970]).andReturn(mockBundleDateNum);
1074
1075 id mocks = [self mocksForEvents];
1076 id mockEngine = mocks[@"mockEngine"];
1077 id mockViewController = OCMClassMock([FlutterViewController class]);
1078 id mockRestorationPlugin = OCMClassMock([FlutterRestorationPlugin class]);
1079 OCMStub([mockEngine viewController]).andReturn(mockViewController);
1080 OCMStub([mockEngine restorationPlugin]).andReturn(mockRestorationPlugin);
1081
1082 NSString* restorationId = @"restorationId";
1083 NSString* mockDataString = @"teststring";
1084 NSNumber* mockBundleStateDateNum = @1.0;
1085 NSData* mockData = [mockDataString dataUsingEncoding:NSUTF8StringEncoding];
1086 OCMStub([mockViewController restorationIdentifier]).andReturn(restorationId);
1087 OCMStub([mockRestorationPlugin restorationData]).andReturn(mockData);
1088
1089 id mockScene = mocks[@"mockScene"];
1090
1091 id userActivity = OCMClassMock([NSUserActivity class]);
1092 NSDictionary* mockUserInfo = @{
1093 @"mod-date" : mockBundleStateDateNum,
1094 restorationId : mockData,
1095 };
1096 OCMStub([userActivity userInfo]).andReturn(mockUserInfo);
1097
1098 [delegate addFlutterManagedEngine:mockEngine];
1099 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
1100 [delegate scene:mockScene restoreInteractionStateWithUserActivity:userActivity];
1101 OCMVerify(times(1), [mockRestorationPlugin setRestorationData:mockData]);
1102 [mockBundle stopMocking];
1103}
1104
1105- (void)testSceneDoesNotRestoreInteractionStateWithUserActivity {
1108 id mockBundle = OCMPartialMock([NSBundle mainBundle]);
1109 id mockURL = OCMClassMock([NSURL class]);
1110 id mockFileDate = OCMClassMock([NSDate class]);
1111 int64_t mockBundleDateNum = 1;
1112
1113 OCMStub([mockBundle executableURL]).andReturn(mockURL);
1114 OCMStub([mockURL getResourceValue:[OCMArg setTo:mockFileDate]
1115 forKey:NSURLContentModificationDateKey
1116 error:[OCMArg setTo:nil]]);
1117 OCMStub([mockFileDate timeIntervalSince1970]).andReturn(mockBundleDateNum);
1118
1119 id mocks = [self mocksForEvents];
1120 id mockEngine = mocks[@"mockEngine"];
1121 id mockViewController = OCMClassMock([FlutterViewController class]);
1122 id mockRestorationPlugin = OCMClassMock([FlutterRestorationPlugin class]);
1123 OCMStub([mockEngine viewController]).andReturn(mockViewController);
1124 OCMStub([mockEngine restorationPlugin]).andReturn(mockRestorationPlugin);
1125
1126 NSString* restorationId = @"restorationId";
1127 NSString* mockDataString = @"teststring";
1128 NSNumber* mockBundleStateDateNum = @2.0;
1129 NSData* mockData = [mockDataString dataUsingEncoding:NSUTF8StringEncoding];
1130 OCMStub([mockViewController restorationIdentifier]).andReturn(restorationId);
1131 OCMStub([mockRestorationPlugin restorationData]).andReturn(mockData);
1132
1133 id mockScene = mocks[@"mockScene"];
1134
1135 id userActivity = OCMClassMock([NSUserActivity class]);
1136 NSDictionary* mockUserInfo = @{
1137 @"mod-date" : mockBundleStateDateNum,
1138 restorationId : mockData,
1139 };
1140 OCMStub([userActivity userInfo]).andReturn(mockUserInfo);
1141
1142 [delegate addFlutterManagedEngine:mockEngine];
1143 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
1144 [delegate scene:mockScene restoreInteractionStateWithUserActivity:userActivity];
1145 OCMVerify(times(0), [mockRestorationPlugin setRestorationData:mockData]);
1146 [mockBundle stopMocking];
1147}
1148
1149- (void)testSceneContinueUserActivityHandledByNoPlugin {
1152
1153 id mocks = [self mocksForEvents];
1154 id mockEngine = mocks[@"mockEngine"];
1155 id mockScene = mocks[@"mockScene"];
1156 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
1157 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
1158 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
1159 OCMStub([mockLifecycleDelegate scene:[OCMArg any] continueUserActivity:[OCMArg any]])
1160 .andReturn(NO);
1161 OCMStub([mockAppLifecycleDelegate sceneFallbackContinueUserActivity:[OCMArg any]]).andReturn(NO);
1162 id flutterApp = OCMClassMock([FlutterSharedApplication class]);
1163 OCMStub([flutterApp isFlutterDeepLinkingEnabled]).andReturn(NO);
1164
1165 NSURL* url = [NSURL URLWithString:@"example.com"];
1166 id userActivity = OCMClassMock([NSUserActivity class]);
1167 OCMStub([userActivity webpageURL]).andReturn(url);
1168
1169 [delegate addFlutterManagedEngine:mockEngine];
1170 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
1171
1172 [delegate scene:mockScene continueUserActivity:userActivity];
1173 OCMVerify(times(1), [mockLifecycleDelegate scene:mockScene continueUserActivity:userActivity]);
1174 OCMVerify(times(1), [mockAppLifecycleDelegate sceneFallbackContinueUserActivity:userActivity]);
1175 OCMVerify(times(0), [mockEngine sendDeepLinkToFramework:url completionHandler:[OCMArg any]]);
1176}
1177
1178- (void)testWindowScenePerformActionForShortcutItemHandledByScenePlugin {
1181
1182 id mocks = [self mocksForEvents];
1183 id mockEngine = mocks[@"mockEngine"];
1184 id mockScene = mocks[@"mockScene"];
1185 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
1186 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
1187 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
1188 OCMStub([mockLifecycleDelegate windowScene:[OCMArg any]
1189 performActionForShortcutItem:[OCMArg any]
1190 completionHandler:[OCMArg any]])
1191 .andReturn(YES);
1192 OCMStub([mockAppLifecycleDelegate sceneFallbackPerformActionForShortcutItem:[OCMArg any]
1193 completionHandler:[OCMArg any]])
1194 .andReturn(YES);
1195
1196 id shortcutItem = OCMClassMock([UIApplicationShortcutItem class]);
1197 id handler = ^(BOOL succeeded) {
1198 };
1199
1200 [delegate addFlutterManagedEngine:mockEngine];
1201 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
1202
1203 [delegate windowScene:mockScene
1204 performActionForShortcutItem:shortcutItem
1205 completionHandler:handler];
1206 OCMVerify(times(1), [mockLifecycleDelegate windowScene:mockScene
1207 performActionForShortcutItem:shortcutItem
1208 completionHandler:handler]);
1209 OCMVerify(times(0),
1210 [mockAppLifecycleDelegate sceneFallbackPerformActionForShortcutItem:shortcutItem
1211 completionHandler:handler]);
1212}
1213
1214- (void)testWindowScenePerformActionForShortcutItemHandledByApplicationPlugin {
1217
1218 id mocks = [self mocksForEvents];
1219 id mockEngine = mocks[@"mockEngine"];
1220 id mockScene = mocks[@"mockScene"];
1221 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
1222 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
1223 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
1224 OCMStub([mockLifecycleDelegate windowScene:[OCMArg any]
1225 performActionForShortcutItem:[OCMArg any]
1226 completionHandler:[OCMArg any]])
1227 .andReturn(NO);
1228 OCMStub([mockAppLifecycleDelegate sceneFallbackPerformActionForShortcutItem:[OCMArg any]
1229 completionHandler:[OCMArg any]])
1230 .andReturn(YES);
1231
1232 id shortcutItem = OCMClassMock([UIApplicationShortcutItem class]);
1233 id handler = ^(BOOL succeeded) {
1234 };
1235
1236 [delegate addFlutterManagedEngine:mockEngine];
1237 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
1238
1239 [delegate windowScene:mockScene
1240 performActionForShortcutItem:shortcutItem
1241 completionHandler:handler];
1242 OCMVerify(times(1), [mockLifecycleDelegate windowScene:mockScene
1243 performActionForShortcutItem:shortcutItem
1244 completionHandler:handler]);
1245 OCMVerify(times(1),
1246 [mockAppLifecycleDelegate sceneFallbackPerformActionForShortcutItem:shortcutItem
1247 completionHandler:handler]);
1248}
1249
1250- (void)testWindowScenePerformActionForShortcutItemHandledByNoPlugin {
1253
1254 id mocks = [self mocksForEvents];
1255 id mockEngine = mocks[@"mockEngine"];
1256 id mockScene = mocks[@"mockScene"];
1257 FlutterEnginePluginSceneLifeCycleDelegate* mockLifecycleDelegate =
1258 (FlutterEnginePluginSceneLifeCycleDelegate*)mocks[@"mockLifecycleDelegate"];
1259 id mockAppLifecycleDelegate = mocks[@"mockAppLifecycleDelegate"];
1260 OCMStub([mockLifecycleDelegate windowScene:[OCMArg any]
1261 performActionForShortcutItem:[OCMArg any]
1262 completionHandler:[OCMArg any]])
1263 .andReturn(NO);
1264 OCMStub([mockAppLifecycleDelegate sceneFallbackPerformActionForShortcutItem:[OCMArg any]
1265 completionHandler:[OCMArg any]])
1266 .andReturn(NO);
1267
1268 id shortcutItem = OCMClassMock([UIApplicationShortcutItem class]);
1269 id handler = ^(BOOL succeeded) {
1270 };
1271
1272 [delegate addFlutterManagedEngine:mockEngine];
1273 XCTAssertEqual(delegate.flutterManagedEngines.count, 1.0);
1274
1275 [delegate windowScene:mockScene
1276 performActionForShortcutItem:shortcutItem
1277 completionHandler:handler];
1278 OCMVerify(times(1), [mockLifecycleDelegate windowScene:mockScene
1279 performActionForShortcutItem:shortcutItem
1280 completionHandler:handler]);
1281 OCMVerify(times(1),
1282 [mockAppLifecycleDelegate sceneFallbackPerformActionForShortcutItem:shortcutItem
1283 completionHandler:handler]);
1284}
1285
1286- (NSDictionary*)mocksForEvents {
1287 id mockEngine = OCMClassMock([FlutterEngine class]);
1288 id mockLifecycleDelegate = OCMClassMock([FlutterEnginePluginSceneLifeCycleDelegate class]);
1289 OCMStub([mockEngine sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
1290
1291 id mockApplication = OCMClassMock([UIApplication class]);
1292 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
1293
1294 id mockAppDelegate = OCMClassMock([FlutterAppDelegate class]);
1295 OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
1296
1297 id mockAppLifecycleDelegate = OCMClassMock([FlutterPluginAppLifeCycleDelegate class]);
1298 OCMStub([mockAppDelegate lifeCycleDelegate]).andReturn(mockAppLifecycleDelegate);
1299
1300 id mockScene = OCMClassMock([UIWindowScene class]);
1301
1302 return @{
1303 @"mockEngine" : mockEngine,
1304 @"mockScene" : mockScene,
1305 @"mockLifecycleDelegate" : mockLifecycleDelegate,
1306 @"mockAppLifecycleDelegate" : mockAppLifecycleDelegate,
1307 };
1308}
1309
1310#pragma mark - FlutterEnginePluginSceneLifeCycleDelegate
1311
1312- (void)testEngineSceneWillConnectToSession {
1315
1316 NSObject<FlutterSceneLifeCycleDelegate>* mockPlugin =
1317 OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1318 OCMStub([mockPlugin scene:[OCMArg any] willConnectToSession:[OCMArg any] options:[OCMArg any]])
1319 .andReturn(YES);
1320 NSObject<FlutterSceneLifeCycleDelegate>* mockPlugin2 =
1321 OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1322 OCMStub([mockPlugin2 scene:[OCMArg any] willConnectToSession:[OCMArg any] options:[OCMArg any]])
1323 .andReturn(YES);
1324
1325 [delegate addDelegate:mockPlugin];
1326 [delegate addDelegate:mockPlugin2];
1327
1328 id mockScene = OCMClassMock([UIWindowScene class]);
1329 id mockSession = OCMClassMock([UISceneSession class]);
1330 id mockOptions = OCMClassMock([UISceneConnectionOptions class]);
1331
1332 XCTAssertTrue([delegate scene:mockScene willConnectToSession:mockSession options:mockOptions]);
1333 OCMVerify(times(1), [mockPlugin scene:mockScene
1334 willConnectToSession:mockSession
1335 options:mockOptions]);
1336 OCMVerify(times(1), [mockPlugin2 scene:mockScene willConnectToSession:mockSession options:nil]);
1337}
1338
1339- (void)testEngineSceneDidDisconnect {
1342
1343 id mockPlugin = OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1344 [delegate addDelegate:mockPlugin];
1345 id mockScene = OCMClassMock([UIWindowScene class]);
1346 [delegate sceneDidDisconnect:mockScene];
1347 OCMVerify([mockPlugin sceneDidDisconnect:mockScene]);
1348}
1349
1350- (void)testEngineSceneWillEnterForeground {
1353
1354 id mockPlugin = OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1355 [delegate addDelegate:mockPlugin];
1356 id mockScene = OCMClassMock([UIWindowScene class]);
1357 [delegate sceneWillEnterForeground:mockScene];
1358 OCMVerify([mockPlugin sceneWillEnterForeground:mockScene]);
1359}
1360
1361- (void)testEngineSceneDidBecomeActive {
1364
1365 id mockPlugin = OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1366 [delegate addDelegate:mockPlugin];
1367 id mockScene = OCMClassMock([UIWindowScene class]);
1368 [delegate sceneDidBecomeActive:mockScene];
1369 OCMVerify([mockPlugin sceneDidBecomeActive:mockScene]);
1370}
1371
1372- (void)testEngineSceneWillResignActive {
1375
1376 id mockPlugin = OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1377 [delegate addDelegate:mockPlugin];
1378 id mockScene = OCMClassMock([UIWindowScene class]);
1379 [delegate sceneWillResignActive:mockScene];
1380 OCMVerify([mockPlugin sceneWillResignActive:mockScene]);
1381}
1382
1383- (void)testEngineSceneDidEnterBackground {
1386
1387 id mockPlugin = OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1388 [delegate addDelegate:mockPlugin];
1389 id mockScene = OCMClassMock([UIWindowScene class]);
1390 [delegate sceneDidEnterBackground:mockScene];
1391 OCMVerify([mockPlugin sceneDidEnterBackground:mockScene]);
1392}
1393
1394- (void)testEngineSceneOpenURLContexts {
1397
1398 NSObject<FlutterSceneLifeCycleDelegate>* mockPlugin =
1399 OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1400 OCMStub([mockPlugin scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(YES);
1401 NSObject<FlutterSceneLifeCycleDelegate>* mockPlugin2 =
1402 OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1403 OCMStub([mockPlugin2 scene:[OCMArg any] openURLContexts:[OCMArg any]]).andReturn(YES);
1404
1405 [delegate addDelegate:mockPlugin];
1406 [delegate addDelegate:mockPlugin2];
1407
1408 id mockScene = OCMClassMock([UIWindowScene class]);
1409 id urlContext = OCMClassMock([UIOpenURLContext class]);
1410 NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
1411
1412 XCTAssertTrue([delegate scene:mockScene openURLContexts:urlContexts]);
1413 OCMVerify(times(1), [mockPlugin scene:mockScene openURLContexts:urlContexts]);
1414 OCMVerify(times(0), [mockPlugin2 scene:mockScene openURLContexts:urlContexts]);
1415}
1416
1417- (void)testEngineSceneContinueUserActivity {
1420
1421 NSObject<FlutterSceneLifeCycleDelegate>* mockPlugin =
1422 OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1423 OCMStub([mockPlugin scene:[OCMArg any] continueUserActivity:[OCMArg any]]).andReturn(YES);
1424 NSObject<FlutterSceneLifeCycleDelegate>* mockPlugin2 =
1425 OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1426 OCMStub([mockPlugin2 scene:[OCMArg any] continueUserActivity:[OCMArg any]]).andReturn(YES);
1427
1428 [delegate addDelegate:mockPlugin];
1429 [delegate addDelegate:mockPlugin2];
1430
1431 id mockScene = OCMClassMock([UIWindowScene class]);
1432 id userActivity = OCMClassMock([NSUserActivity class]);
1433
1434 XCTAssertTrue([delegate scene:mockScene continueUserActivity:userActivity]);
1435 OCMVerify(times(1), [mockPlugin scene:mockScene continueUserActivity:userActivity]);
1436 OCMVerify(times(0), [mockPlugin2 scene:mockScene continueUserActivity:userActivity]);
1437}
1438
1439- (void)testEngineWindowScenePerformActionForShortcutItem {
1442
1443 NSObject<FlutterSceneLifeCycleDelegate>* mockPlugin =
1444 OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1445 OCMStub([mockPlugin windowScene:[OCMArg any]
1446 performActionForShortcutItem:[OCMArg any]
1447 completionHandler:[OCMArg any]])
1448 .andReturn(YES);
1449 NSObject<FlutterSceneLifeCycleDelegate>* mockPlugin2 =
1450 OCMProtocolMock(@protocol(FlutterSceneLifeCycleDelegate));
1451 OCMStub([mockPlugin2 windowScene:[OCMArg any]
1452 performActionForShortcutItem:[OCMArg any]
1453 completionHandler:[OCMArg any]])
1454 .andReturn(YES);
1455
1456 [delegate addDelegate:mockPlugin];
1457 [delegate addDelegate:mockPlugin2];
1458
1459 id mockScene = OCMClassMock([UIWindowScene class]);
1460 id shortcutItem = OCMClassMock([UIApplicationShortcutItem class]);
1461 id handler = ^(BOOL succeeded) {
1462 };
1463
1464 XCTAssertTrue([delegate windowScene:mockScene
1465 performActionForShortcutItem:shortcutItem
1466 completionHandler:handler]);
1467 OCMVerify(times(1), [mockPlugin windowScene:mockScene
1468 performActionForShortcutItem:shortcutItem
1469 completionHandler:handler]);
1470 OCMVerify(times(0), [mockPlugin2 windowScene:mockScene
1471 performActionForShortcutItem:shortcutItem
1472 completionHandler:handler]);
1473}
1474
1475- (void)testFlutterPluginSceneLifeCycleDelegateFromScene {
1476 id mockScene = OCMClassMock([UIWindowScene class]);
1477 id mockSceneDelegate = OCMClassMock([FlutterSwiftUIAppSceneDelegate class]);
1478 id mockSceneLifeCycleDelegate = OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
1479
1480 OCMStub([mockScene delegate]).andReturn(mockSceneDelegate);
1481 OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockSceneLifeCycleDelegate);
1482
1483 XCTAssertEqual([FlutterPluginSceneLifeCycleDelegate fromScene:mockScene],
1484 mockSceneLifeCycleDelegate);
1485}
1486@end
void addDelegate:(NSObject< FlutterSceneLifeCycleDelegate > *delegate)
GLFWwindow * window
Definition main.cc:60
FlutterEngine engine
Definition main.cc:84
FlView * view
const gchar FlBinaryMessengerMessageHandler handler
const uint8_t uint32_t uint32_t GError ** error
const char * name
Definition fuchsia.cc:49
void scene:openURLContexts:(UIScene *scene,[openURLContexts] NSSet< UIOpenURLContext * > *URLContexts)
void updateFlutterManagedEnginesInScene:(UIScene *scene)
void scene:willConnectToSession:options:(UIScene *scene,[willConnectToSession] UISceneSession *session,[options] UISceneConnectionOptions *connectionOptions)
void windowScene:performActionForShortcutItem:completionHandler:(UIWindowScene *windowScene,[performActionForShortcutItem] UIApplicationShortcutItem *shortcutItem,[completionHandler] void(^ completionHandler)(BOOL succeeded))
void scene:continueUserActivity:(UIScene *scene,[continueUserActivity] NSUserActivity *userActivity)
FlutterPluginSceneLifeCycleDelegate * sceneLifeCycleDelegate
FlutterViewController * viewController
BOOL unregisterSceneLifeCycleWithFlutterEngine:(FlutterEngine *engine)
BOOL registerSceneLifeCycleWithFlutterEngine:(FlutterEngine *engine)
int BOOL