| Flutter iOS Embedder |

FlutterPlatformPluginTest.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 <OCMock/OCMock.h>
6 #import <XCTest/XCTest.h>
7
8 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h"
9 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
10 #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
11 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h"
12 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h"
13 #import "flutter/shell/platform/darwin/ios/platform_view_ios.h"
14
15 @interface FlutterPlatformPluginTest : XCTestCase
16 @end
17
18 @interface FlutterPlatformPlugin ()
19 - (BOOL)isLiveTextInputAvailable;
20 - (void)searchWeb:(NSString*)searchTerm;
21 - (void)showLookUpViewController:(NSString*)term;
22 - (void)showShareViewController:(NSString*)content;
23 @end
24
25 @interface UIViewController ()
26 - (void)presentViewController:(UIViewController*)viewControllerToPresent
27 animated:(BOOL)flag
28 completion:(void (^)(void))completion;
29 @end
30
31 @implementation FlutterPlatformPluginTest
32 - (void)testSearchWebInvokedWithEscapedTerm {
33 id mockApplication = OCMClassMock([UIApplication class]);
34 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
35
36 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
37 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
38 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
39 [engine runWithEntrypoint:nil];
40
41 XCTestExpectation* invokeExpectation =
42 [self expectationWithDescription:@"Web search launched with escaped search term"];
43
44 FlutterPlatformPlugin* plugin =
45 [[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
46 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
47
48 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke"
49 arguments:@"Testing Word!"];
50
51 FlutterResult result = ^(id result) {
52 OCMVerify([mockPlugin searchWeb:@"Testing Word!"]);
53 #if not APPLICATION_EXTENSION_API_ONLY
54 OCMVerify([mockApplication openURL:[NSURL URLWithString:@"x-web-search://?Testing%20Word!"]
55 options:@{}
56 completionHandler:nil]);
57 #endif
58 [invokeExpectation fulfill];
59 };
60
61 [mockPlugin handleMethodCall:methodCall result:result];
62 [self waitForExpectationsWithTimeout:1 handler:nil];
63 [mockApplication stopMocking];
64 }
65
66 - (void)testSearchWebInvokedWithNonEscapedTerm {
67 id mockApplication = OCMClassMock([UIApplication class]);
68 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
69
70 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
71 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
72 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
73 [engine runWithEntrypoint:nil];
74
75 XCTestExpectation* invokeExpectation =
76 [self expectationWithDescription:@"Web search launched with non escaped search term"];
77
78 FlutterPlatformPlugin* plugin =
79 [[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
80 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
81
82 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke"
83 arguments:@"Test"];
84
85 FlutterResult result = ^(id result) {
86 OCMVerify([mockPlugin searchWeb:@"Test"]);
87 #if not APPLICATION_EXTENSION_API_ONLY
88 OCMVerify([mockApplication openURL:[NSURL URLWithString:@"x-web-search://?Test"]
89 options:@{}
90 completionHandler:nil]);
91 #endif
92 [invokeExpectation fulfill];
93 };
94
95 [mockPlugin handleMethodCall:methodCall result:result];
96 [self waitForExpectationsWithTimeout:1 handler:nil];
97 [mockApplication stopMocking];
98 }
99
100 - (void)testLookUpCallInitiated {
101 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
102 [engine runWithEntrypoint:nil];
103 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
104 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
105
106 XCTestExpectation* presentExpectation =
107 [self expectationWithDescription:@"Look Up view controller presented"];
108
109 FlutterViewController* engineViewController =
110 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
111 FlutterViewController* mockEngineViewController = OCMPartialMock(engineViewController);
112
113 FlutterPlatformPlugin* plugin =
114 [[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
115 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
116
117 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"LookUp.invoke"
118 arguments:@"Test"];
119 FlutterResult result = ^(id result) {
120 OCMVerify([mockEngineViewController
121 presentViewController:[OCMArg isKindOfClass:[UIReferenceLibraryViewController class]]
122 animated:YES
123 completion:nil]);
124 [presentExpectation fulfill];
125 };
126 [mockPlugin handleMethodCall:methodCall result:result];
127 [self waitForExpectationsWithTimeout:2 handler:nil];
128 }
129
130 - (void)testShareScreenInvoked {
131 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
132 [engine runWithEntrypoint:nil];
133 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
134 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
135
136 XCTestExpectation* presentExpectation =
137 [self expectationWithDescription:@"Share view controller presented"];
138
139 FlutterViewController* engineViewController =
140 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
141 FlutterViewController* mockEngineViewController = OCMPartialMock(engineViewController);
142 OCMStub([mockEngineViewController
143 presentViewController:[OCMArg isKindOfClass:[UIActivityViewController class]]
144 animated:YES
145 completion:nil]);
146
147 FlutterPlatformPlugin* plugin =
148 [[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
149 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
150
151 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke"
152 arguments:@"Test"];
153 FlutterResult result = ^(id result) {
154 OCMVerify([mockEngineViewController
155 presentViewController:[OCMArg isKindOfClass:[UIActivityViewController class]]
156 animated:YES
157 completion:nil]);
158 [presentExpectation fulfill];
159 };
160 [mockPlugin handleMethodCall:methodCall result:result];
161 [self waitForExpectationsWithTimeout:1 handler:nil];
162 }
163
164 - (void)testShareScreenInvokedOnIPad {
165 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
166 [engine runWithEntrypoint:nil];
167 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
168 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
169
170 XCTestExpectation* presentExpectation =
171 [self expectationWithDescription:@"Share view controller presented on iPad"];
172
173 FlutterViewController* engineViewController =
174 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
175 FlutterViewController* mockEngineViewController = OCMPartialMock(engineViewController);
176 OCMStub([mockEngineViewController
177 presentViewController:[OCMArg isKindOfClass:[UIActivityViewController class]]
178 animated:YES
179 completion:nil]);
180
181 id mockTraitCollection = OCMClassMock([UITraitCollection class]);
182 OCMStub([mockTraitCollection userInterfaceIdiom]).andReturn(UIUserInterfaceIdiomPad);
183
184 FlutterPlatformPlugin* plugin =
185 [[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
186 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
187
188 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke"
189 arguments:@"Test"];
190 FlutterResult result = ^(id result) {
191 OCMVerify([mockEngineViewController
192 presentViewController:[OCMArg isKindOfClass:[UIActivityViewController class]]
193 animated:YES
194 completion:nil]);
195 [presentExpectation fulfill];
196 };
197 [mockPlugin handleMethodCall:methodCall result:result];
198 [self waitForExpectationsWithTimeout:1 handler:nil];
199 }
200
201 - (void)testClipboardHasCorrectStrings {
202 [UIPasteboard generalPasteboard].string = nil;
203 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
204 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
205 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
206 FlutterPlatformPlugin* plugin =
207 [[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
208
209 XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setString"];
210 FlutterResult resultSet = ^(id result) {
211 [setStringExpectation fulfill];
212 };
213 FlutterMethodCall* methodCallSet =
214 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.setData"
215 arguments:@{@"text" : @"some string"}];
216 [plugin handleMethodCall:methodCallSet result:resultSet];
217 [self waitForExpectationsWithTimeout:1 handler:nil];
218
219 XCTestExpectation* hasStringsExpectation = [self expectationWithDescription:@"hasStrings"];
220 FlutterResult result = ^(id result) {
221 XCTAssertTrue([result[@"value"] boolValue]);
222 [hasStringsExpectation fulfill];
223 };
224 FlutterMethodCall* methodCall =
225 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.hasStrings" arguments:nil];
226 [plugin handleMethodCall:methodCall result:result];
227 [self waitForExpectationsWithTimeout:1 handler:nil];
228
229 XCTestExpectation* getDataExpectation = [self expectationWithDescription:@"getData"];
230 FlutterResult getDataResult = ^(id result) {
231 XCTAssertEqualObjects(result[@"text"], @"some string");
232 [getDataExpectation fulfill];
233 };
234 FlutterMethodCall* methodCallGetData =
235 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.getData" arguments:@"text/plain"];
236 [plugin handleMethodCall:methodCallGetData result:getDataResult];
237 [self waitForExpectationsWithTimeout:1 handler:nil];
238 }
239
240 - (void)testClipboardSetDataToNullDoNotCrash {
241 [UIPasteboard generalPasteboard].string = nil;
242 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
243 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
244 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
245 FlutterPlatformPlugin* plugin =
246 [[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
247
248 XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setData"];
249 FlutterResult resultSet = ^(id result) {
250 [setStringExpectation fulfill];
251 };
252 FlutterMethodCall* methodCallSet =
253 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.setData"
254 arguments:@{@"text" : [NSNull null]}];
255 [plugin handleMethodCall:methodCallSet result:resultSet];
256
257 XCTestExpectation* getDataExpectation = [self expectationWithDescription:@"getData"];
258 FlutterResult result = ^(id result) {
259 XCTAssertEqualObjects(result[@"text"], @"null");
260 [getDataExpectation fulfill];
261 };
262 FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Clipboard.getData"
263 arguments:@"text/plain"];
264 [plugin handleMethodCall:methodCall result:result];
265 [self waitForExpectationsWithTimeout:1 handler:nil];
266 }
267
268 - (void)testPopSystemNavigator {
269 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
270 [engine runWithEntrypoint:nil];
271 FlutterViewController* flutterViewController =
272 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
273 UINavigationController* navigationController = [[[UINavigationController alloc]
274 initWithRootViewController:flutterViewController] autorelease];
275 UITabBarController* tabBarController = [[[UITabBarController alloc] init] autorelease];
276 tabBarController.viewControllers = @[ navigationController ];
277 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
278 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
279 FlutterPlatformPlugin* plugin =
280 [[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
281
282 id navigationControllerMock = OCMPartialMock(navigationController);
283 OCMStub([navigationControllerMock popViewControllerAnimated:YES]);
284 // Set some string to the pasteboard.
285 XCTestExpectation* navigationPopCalled = [self expectationWithDescription:@"SystemNavigator.pop"];
286 FlutterResult resultSet = ^(id result) {
287 [navigationPopCalled fulfill];
288 };
289 FlutterMethodCall* methodCallSet =
290 [FlutterMethodCall methodCallWithMethodName:@"SystemNavigator.pop" arguments:@(YES)];
291 [plugin handleMethodCall:methodCallSet result:resultSet];
292 [self waitForExpectationsWithTimeout:1 handler:nil];
293 OCMVerify([navigationControllerMock popViewControllerAnimated:YES]);
294
295 [flutterViewController deregisterNotifications];
296 [flutterViewController release];
297 }
298
299 - (void)testWhetherDeviceHasLiveTextInputInvokeCorrectly {
300 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
301 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
302 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
303 XCTestExpectation* invokeExpectation =
304 [self expectationWithDescription:@"isLiveTextInputAvailableInvoke"];
305 FlutterPlatformPlugin* plugin =
306 [[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
307 FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
308 FlutterMethodCall* methodCall =
309 [FlutterMethodCall methodCallWithMethodName:@"LiveText.isLiveTextInputAvailable"
310 arguments:nil];
311 FlutterResult result = ^(id result) {
312 OCMVerify([mockPlugin isLiveTextInputAvailable]);
313 [invokeExpectation fulfill];
314 };
315 [mockPlugin handleMethodCall:methodCall result:result];
316 [self waitForExpectationsWithTimeout:1 handler:nil];
317 }
318
319 - (void)testViewControllerBasedStatusBarHiddenUpdate {
320 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
321 OCMStub([bundleMock objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"])
322 .andReturn(@YES);
323 {
324 // Enabling system UI overlays to update status bar.
325 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
326 [engine runWithEntrypoint:nil];
327 FlutterViewController* flutterViewController =
328 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
329 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
330 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
331 XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
332
333 // Update to hidden.
334 FlutterPlatformPlugin* plugin = [engine platformPlugin];
335
336 XCTestExpectation* enableSystemUIOverlaysCalled =
337 [self expectationWithDescription:@"setEnabledSystemUIOverlays"];
338 FlutterResult resultSet = ^(id result) {
339 [enableSystemUIOverlaysCalled fulfill];
340 };
341 FlutterMethodCall* methodCallSet =
342 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays"
343 arguments:@[ @"SystemUiOverlay.bottom" ]];
344 [plugin handleMethodCall:methodCallSet result:resultSet];
345 [self waitForExpectationsWithTimeout:1 handler:nil];
346 XCTAssertTrue(flutterViewController.prefersStatusBarHidden);
347
348 // Update to shown.
349 XCTestExpectation* enableSystemUIOverlaysCalled2 =
350 [self expectationWithDescription:@"setEnabledSystemUIOverlays"];
351 FlutterResult resultSet2 = ^(id result) {
352 [enableSystemUIOverlaysCalled2 fulfill];
353 };
354 FlutterMethodCall* methodCallSet2 =
355 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays"
356 arguments:@[ @"SystemUiOverlay.top" ]];
357 [plugin handleMethodCall:methodCallSet2 result:resultSet2];
358 [self waitForExpectationsWithTimeout:1 handler:nil];
359 XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
360
361 [flutterViewController deregisterNotifications];
362 [flutterViewController release];
363 }
364 {
365 // Enable system UI mode to update status bar.
366 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
367 [engine runWithEntrypoint:nil];
368 FlutterViewController* flutterViewController =
369 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
370 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
371 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
372 XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
373
374 // Update to hidden.
375 FlutterPlatformPlugin* plugin = [engine platformPlugin];
376
377 XCTestExpectation* enableSystemUIModeCalled =
378 [self expectationWithDescription:@"setEnabledSystemUIMode"];
379 FlutterResult resultSet = ^(id result) {
380 [enableSystemUIModeCalled fulfill];
381 };
382 FlutterMethodCall* methodCallSet =
383 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIMode"
384 arguments:@"SystemUiMode.immersive"];
385 [plugin handleMethodCall:methodCallSet result:resultSet];
386 [self waitForExpectationsWithTimeout:1 handler:nil];
387 XCTAssertTrue(flutterViewController.prefersStatusBarHidden);
388
389 // Update to shown.
390 XCTestExpectation* enableSystemUIModeCalled2 =
391 [self expectationWithDescription:@"setEnabledSystemUIMode"];
392 FlutterResult resultSet2 = ^(id result) {
393 [enableSystemUIModeCalled2 fulfill];
394 };
395 FlutterMethodCall* methodCallSet2 =
396 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIMode"
397 arguments:@"SystemUiMode.edgeToEdge"];
398 [plugin handleMethodCall:methodCallSet2 result:resultSet2];
399 [self waitForExpectationsWithTimeout:1 handler:nil];
400 XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
401
402 [flutterViewController deregisterNotifications];
403 [flutterViewController release];
404 }
405 [bundleMock stopMocking];
406 }
407
408 - (void)testStatusBarHiddenUpdate {
409 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
410 OCMStub([bundleMock objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"])
411 .andReturn(@NO);
412 id mockApplication = OCMClassMock([UIApplication class]);
413 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
414
415 // Enabling system UI overlays to update status bar.
416 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
417 [engine runWithEntrypoint:nil];
418 FlutterViewController* flutterViewController =
419 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
420 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
421 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
422
423 // Update to hidden.
424 FlutterPlatformPlugin* plugin = [engine platformPlugin];
425
426 XCTestExpectation* enableSystemUIOverlaysCalled =
427 [self expectationWithDescription:@"setEnabledSystemUIOverlays"];
428 FlutterResult resultSet = ^(id result) {
429 [enableSystemUIOverlaysCalled fulfill];
430 };
431 FlutterMethodCall* methodCallSet =
432 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays"
433 arguments:@[ @"SystemUiOverlay.bottom" ]];
434 [plugin handleMethodCall:methodCallSet result:resultSet];
435 [self waitForExpectationsWithTimeout:1 handler:nil];
436 #if not APPLICATION_EXTENSION_API_ONLY
437 OCMVerify([mockApplication setStatusBarHidden:YES]);
438 #endif
439
440 // Update to shown.
441 XCTestExpectation* enableSystemUIOverlaysCalled2 =
442 [self expectationWithDescription:@"setEnabledSystemUIOverlays"];
443 FlutterResult resultSet2 = ^(id result) {
444 [enableSystemUIOverlaysCalled2 fulfill];
445 };
446 FlutterMethodCall* methodCallSet2 =
447 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays"
448 arguments:@[ @"SystemUiOverlay.top" ]];
449 [plugin handleMethodCall:methodCallSet2 result:resultSet2];
450 [self waitForExpectationsWithTimeout:1 handler:nil];
451 #if not APPLICATION_EXTENSION_API_ONLY
452 OCMVerify([mockApplication setStatusBarHidden:NO]);
453 #endif
454
455 [flutterViewController deregisterNotifications];
456 [mockApplication stopMocking];
457 [bundleMock stopMocking];
458 }
459
460 - (void)testStatusBarStyle {
461 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
462 OCMStub([bundleMock objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"])
463 .andReturn(@NO);
464 id mockApplication = OCMClassMock([UIApplication class]);
465 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
466
467 FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
468 [engine runWithEntrypoint:nil];
469 FlutterViewController* flutterViewController =
470 [[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
471 std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
472 std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
473 XCTAssertFalse(flutterViewController.prefersStatusBarHidden);
474
475 FlutterPlatformPlugin* plugin = [engine platformPlugin];
476
477 XCTestExpectation* enableSystemUIModeCalled =
478 [self expectationWithDescription:@"setSystemUIOverlayStyle"];
479 FlutterResult resultSet = ^(id result) {
480 [enableSystemUIModeCalled fulfill];
481 };
482 FlutterMethodCall* methodCallSet =
483 [FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setSystemUIOverlayStyle"
484 arguments:@{@"statusBarBrightness" : @"Brightness.dark"}];
485 [plugin handleMethodCall:methodCallSet result:resultSet];
486 [self waitForExpectationsWithTimeout:1 handler:nil];
487
488 #if not APPLICATION_EXTENSION_API_ONLY
489 OCMVerify([mockApplication setStatusBarStyle:UIStatusBarStyleLightContent]);
490 #endif
491
492 [flutterViewController deregisterNotifications];
493 [mockApplication stopMocking];
494 [bundleMock stopMocking];
495 }
496
497 @end
FlutterEngine
Definition: FlutterEngine.h:59
+[FlutterMethodCall methodCallWithMethodName:arguments:]
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
FlutterViewController
Definition: FlutterViewController.h:55
FlutterPlatformPluginTest
Definition: FlutterPlatformPluginTest.mm:15
-[FlutterEngine runWithEntrypoint:]
BOOL runWithEntrypoint:(nullable NSString *entrypoint)
FlutterEngine_Internal.h
-[FlutterPlatformPlugin handleMethodCall:result:]
void handleMethodCall:result:(FlutterMethodCall *call,[result] FlutterResult result)
Definition: FlutterPlatformPlugin.mm:103
FlutterMacros.h
FlutterMethodCall
Definition: FlutterCodecs.h:220
FlutterBinaryMessenger.h
FlutterResult
void(^ FlutterResult)(id _Nullable result)
Definition: FlutterChannels.h:196
FlutterPlatformPlugin.h
engine
id engine
Definition: FlutterTextInputPluginTest.mm:89
_weakFactory
std::unique_ptr< fml::WeakPtrFactory< FlutterDartVMServicePublisher > > _weakFactory
Definition: FlutterDartVMServicePublisher.mm:161
FlutterPlatformPlugin
Definition: FlutterPlatformPlugin.h:12
platform_view_ios.h
FlutterViewController.h