Flutter iOS Embedder
FlutterSceneDelegateTest.m
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 <XCTest/XCTest.h>
8 
15 
16 @interface FlutterSceneDelegateTest : XCTestCase
17 @end
18 
19 @implementation TestAppDelegate
20 @end
21 
22 @implementation FlutterSceneDelegateTest
23 
24 - (void)setUp {
25 }
26 
27 - (void)tearDown {
28 }
29 
30 - (void)testMoveRootViewControllerWhenWindow {
31  id mockApplication = OCMClassMock([UIApplication class]);
32  OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
33 
34  id mockAppDelegate = OCMClassMock([FlutterAppDelegate class]);
35  OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
36 
37  id mockWindow = OCMClassMock([UIWindow class]);
38  OCMStub([mockAppDelegate window]).andReturn(mockWindow);
39 
40  id mockRootViewController = OCMClassMock([UIViewController class]);
41  OCMStub([mockWindow rootViewController]).andReturn(mockRootViewController);
42 
43  id scene = OCMClassMock([UIWindowScene class]);
44  id session = OCMClassMock([UISceneSession class]);
45  id connectionOptions = OCMClassMock([UISceneConnectionOptions class]);
46 
47  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
48  FlutterSceneDelegate* mockSceneDelegate = OCMPartialMock(sceneDelegate);
49  OCMStub([mockSceneDelegate moveRootViewControllerFrom:[OCMArg any] to:[OCMArg any]]);
50 
51  [mockSceneDelegate scene:scene willConnectToSession:session options:connectionOptions];
52 
53  OCMVerify(times(1), [mockSceneDelegate moveRootViewControllerFrom:mockAppDelegate to:scene]);
54 }
55 
56 - (void)testMoveRootViewControllerWhenNoWindow {
57  id mockApplication = OCMClassMock([UIApplication class]);
58  OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
59 
60  id testAppDelegate = [[TestAppDelegate alloc] init];
61  OCMStub([mockApplication delegate]).andReturn(testAppDelegate);
62 
63  id scene = OCMClassMock([UIWindowScene class]);
64  id session = OCMClassMock([UISceneSession class]);
65  id connectionOptions = OCMClassMock([UISceneConnectionOptions class]);
66 
67  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
68  FlutterSceneDelegate* mockSceneDelegate = OCMPartialMock(sceneDelegate);
69  OCMStub([mockSceneDelegate moveRootViewControllerFrom:[OCMArg any] to:[OCMArg any]]);
70 
71  [mockSceneDelegate scene:scene willConnectToSession:session options:connectionOptions];
72 
73  OCMReject([mockSceneDelegate moveRootViewControllerFrom:[OCMArg any] to:[OCMArg any]]);
74 }
75 
76 - (void)testSceneWillConnectToSessionOptions {
77  [self setupMockApplication];
78 
79  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
80  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
81 
82  id mockLifecycleDelegate = OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
83  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
84 
85  id scene = OCMClassMock([UIWindowScene class]);
86  id session = OCMClassMock([UISceneSession class]);
87  id connectionOptions = OCMClassMock([UISceneConnectionOptions class]);
88 
90  willConnectToSession:session
91  options:connectionOptions];
92 
93  OCMVerify(times(1), [(FlutterSceneDelegate*)mockLifecycleDelegate scene:scene
94  willConnectToSession:session
95  options:connectionOptions]);
96 }
97 
98 - (void)testSceneDidDisconnect {
99  [self setupMockApplication];
100 
101  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
102  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
103 
104  id mockLifecycleDelegate = OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
105  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
106 
107  id scene = OCMClassMock([UIWindowScene class]);
108 
109  [mockSceneDelegate sceneDidDisconnect:scene];
110 
111  OCMVerify(times(1), [mockLifecycleDelegate sceneDidDisconnect:scene]);
112 }
113 
114 - (void)testSceneWillEnterForeground {
115  [self setupMockApplication];
116 
117  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
118  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
119 
120  id mockLifecycleDelegate = OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
121  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
122 
123  id scene = OCMClassMock([UIWindowScene class]);
124 
125  [mockSceneDelegate sceneWillEnterForeground:scene];
126 
127  OCMVerify(times(1), [mockLifecycleDelegate sceneWillEnterForeground:scene]);
128 }
129 
130 - (void)testSceneDidBecomeActive {
131  [self setupMockApplication];
132 
133  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
134  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
135 
136  id mockLifecycleDelegate = OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
137  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
138 
139  id scene = OCMClassMock([UIWindowScene class]);
140 
141  [mockSceneDelegate sceneDidBecomeActive:scene];
142 
143  OCMVerify(times(1), [mockLifecycleDelegate sceneDidBecomeActive:scene]);
144 }
145 
146 - (void)testSceneWillResignActive {
147  [self setupMockApplication];
148 
149  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
150  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
151 
152  id mockLifecycleDelegate = OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
153  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
154 
155  id scene = OCMClassMock([UIWindowScene class]);
156 
157  [mockSceneDelegate sceneWillResignActive:scene];
158 
159  OCMVerify(times(1), [mockLifecycleDelegate sceneWillResignActive:scene]);
160 }
161 
162 - (void)testSceneDidEnterBackground {
163  [self setupMockApplication];
164 
165  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
166  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
167 
168  id mockLifecycleDelegate = OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
169  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
170 
171  id scene = OCMClassMock([UIWindowScene class]);
172 
173  [mockSceneDelegate sceneDidEnterBackground:scene];
174 
175  OCMVerify(times(1), [mockLifecycleDelegate sceneDidEnterBackground:scene]);
176 }
177 
178 - (void)testSceneOpenURLContexts {
179  [self setupMockApplication];
180 
181  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
182  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
183 
184  FlutterPluginSceneLifeCycleDelegate* mockLifecycleDelegate =
185  OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
186  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
187 
188  id scene = OCMClassMock([UIWindowScene class]);
189  id urlContext = OCMClassMock([UIOpenURLContext class]);
190  NSSet<UIOpenURLContext*>* urlContexts = [NSSet setWithObjects:urlContext, nil];
191 
192  [((FlutterSceneDelegate*)mockSceneDelegate) scene:scene openURLContexts:urlContexts];
193 
194  OCMVerify(times(1), [mockLifecycleDelegate scene:scene openURLContexts:urlContexts]);
195 }
196 
197 - (void)testSceneContinueUserActivity {
198  [self setupMockApplication];
199 
200  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
201  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
202 
203  FlutterPluginSceneLifeCycleDelegate* mockLifecycleDelegate =
204  OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
205  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
206 
207  id scene = OCMClassMock([UIWindowScene class]);
208  id userActivity = OCMClassMock([NSUserActivity class]);
209 
210  [((FlutterSceneDelegate*)mockSceneDelegate) scene:scene continueUserActivity:userActivity];
211 
212  OCMVerify(times(1), [mockLifecycleDelegate scene:scene continueUserActivity:userActivity]);
213 }
214 
215 - (void)testStateRestorationActivityForScene {
216  [self setupMockApplication];
217 
218  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
219  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
220 
221  FlutterPluginSceneLifeCycleDelegate* mockLifecycleDelegate =
222  OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
223  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
224 
225  id scene = OCMClassMock([UIWindowScene class]);
226 
228 
229  OCMVerify(times(1), [mockLifecycleDelegate stateRestorationActivityForScene:scene]);
230 }
231 
232 - (void)testSceneRestoreInteractionStateWithUserActivity {
233  [self setupMockApplication];
234 
235  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
236  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
237 
238  FlutterPluginSceneLifeCycleDelegate* mockLifecycleDelegate =
239  OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
240  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
241 
242  id scene = OCMClassMock([UIWindowScene class]);
243  id userActivity = OCMClassMock([NSUserActivity class]);
244 
246  restoreInteractionStateWithUserActivity:userActivity];
247 
248  OCMVerify(times(1), [mockLifecycleDelegate scene:scene
249  restoreInteractionStateWithUserActivity:userActivity]);
250 }
251 
252 - (void)testWindowScenePerformActionForShortcutItem {
253  [self setupMockApplication];
254 
255  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
256  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
257 
258  FlutterPluginSceneLifeCycleDelegate* mockLifecycleDelegate =
259  OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
260  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
261 
262  id scene = OCMClassMock([UIWindowScene class]);
263  id shortcutItem = OCMClassMock([UIApplicationShortcutItem class]);
264 
266  performActionForShortcutItem:shortcutItem
267  completionHandler:^(BOOL succeeded){
268  }];
269 
270  OCMVerify(times(1), [mockLifecycleDelegate windowScene:scene
271  performActionForShortcutItem:shortcutItem
272  completionHandler:[OCMArg any]]);
273 }
274 
275 - (void)testRegisterSceneLifeCycleWithFlutterEngine {
276  [self setupMockApplication];
277 
278  id mockEngine = OCMClassMock([FlutterEngine class]);
279  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
280  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
281 
282  id mockLifecycleDelegate = OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
283  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
284 
285  [mockSceneDelegate registerSceneLifeCycleWithFlutterEngine:mockEngine];
286 
287  OCMVerify(times(1), [mockLifecycleDelegate registerSceneLifeCycleWithFlutterEngine:mockEngine]);
288 }
289 
290 - (void)testUnregisterSceneLifeCycleWithFlutterEngine {
291  [self setupMockApplication];
292 
293  id mockEngine = OCMClassMock([FlutterEngine class]);
294  FlutterSceneDelegate* sceneDelegate = [[FlutterSceneDelegate alloc] init];
295  id mockSceneDelegate = OCMPartialMock(sceneDelegate);
296 
297  id mockLifecycleDelegate = OCMClassMock([FlutterPluginSceneLifeCycleDelegate class]);
298  OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
299 
300  [mockSceneDelegate unregisterSceneLifeCycleWithFlutterEngine:mockEngine];
301 
302  OCMVerify(times(1), [mockLifecycleDelegate unregisterSceneLifeCycleWithFlutterEngine:mockEngine]);
303 }
304 
305 - (NSDictionary*)setupMockApplication {
306  id mockApplication = OCMClassMock([UIApplication class]);
307  OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
308 
309  id testAppDelegate = [[TestAppDelegate alloc] init];
310  OCMStub([mockApplication delegate]).andReturn(testAppDelegate);
311 
312  return @{
313  @"mockApplication" : mockApplication,
314  @"testAppDelegate" : testAppDelegate,
315  };
316 }
317 
318 @end