Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: ios/chrome/app/application_delegate/app_state_unittest.mm

Issue 2580363002: Upstream Chrome on iOS source code [1/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium 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 "ios/chrome/app/application_delegate/app_state.h"
6
7 #import <QuartzCore/QuartzCore.h>
8
9 #include "base/ios/block_types.h"
10 #include "base/mac/scoped_block.h"
11 #import "base/mac/scoped_nsobject.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/synchronization/lock.h"
14 #import "ios/chrome/app/application_delegate/app_navigation.h"
15 #import "ios/chrome/app/application_delegate/app_state_testing.h"
16 #import "ios/chrome/app/application_delegate/browser_launcher.h"
17 #import "ios/chrome/app/application_delegate/fake_startup_information.h"
18 #import "ios/chrome/app/application_delegate/memory_warning_helper.h"
19 #import "ios/chrome/app/application_delegate/metrics_mediator.h"
20 #import "ios/chrome/app/application_delegate/mock_tab_opener.h"
21 #import "ios/chrome/app/application_delegate/startup_information.h"
22 #import "ios/chrome/app/application_delegate/tab_switching.h"
23 #import "ios/chrome/app/application_delegate/user_activity_handler.h"
24 #import "ios/chrome/app/main_application_delegate.h"
25 #import "ios/chrome/app/safe_mode/safe_mode_coordinator.h"
26 #import "ios/chrome/app/safe_mode_crashing_modules_config.h"
27 #import "ios/chrome/browser/app_startup_parameters.h"
28 #include "ios/chrome/browser/chrome_url_constants.h"
29 #import "ios/chrome/browser/device_sharing/device_sharing_manager.h"
30 #import "ios/chrome/browser/geolocation/omnibox_geolocation_config.h"
31 #import "ios/chrome/browser/tabs/tab_model.h"
32 #import "ios/chrome/browser/ui/browser_view_controller.h"
33 #import "ios/chrome/browser/ui/main/browser_view_information.h"
34 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
35 #import "ios/chrome/test/base/scoped_block_swizzler.h"
36 #include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.h"
37 #include "ios/public/provider/chrome/browser/distribution/app_distribution_provi der.h"
38 #include "ios/public/provider/chrome/browser/test_chrome_browser_provider.h"
39 #include "ios/public/provider/chrome/browser/user_feedback/test_user_feedback_pr ovider.h"
40 #import "ios/testing/ocmock_complex_type_helper.h"
41 #include "ios/web/net/request_tracker_impl.h"
42 #import "ios/web/public/test/test_web_thread_bundle.h"
43 #include "testing/platform_test.h"
44 #import "third_party/ocmock/OCMock/OCMock.h"
45 #include "third_party/ocmock/gtest_support.h"
46
47 #pragma mark - Class definition.
48
49 namespace {
50
51 // A block that takes self as argument and return a BOOL.
52 typedef BOOL (^DecisionBlock)(id self);
53 // A block that takes the arguments of UserActivityHandler's
54 // +handleStartupParametersWithTabOpener.
55 typedef void (^HandleStartupParam)(
56 id self,
57 id<TabOpening> tabOpener,
58 id<StartupInformation> startupInformation,
59 id<BrowserViewInformation> browserViewInformation);
60
61 class FakeAppDistributionProvider : public AppDistributionProvider {
62 public:
63 FakeAppDistributionProvider() : cancel_called_(false) {}
64 ~FakeAppDistributionProvider() override {}
65
66 void CancelDistributionNotifications() override { cancel_called_ = true; }
67 bool cancel_called() { return cancel_called_; }
68
69 private:
70 bool cancel_called_;
71 DISALLOW_COPY_AND_ASSIGN(FakeAppDistributionProvider);
72 };
73
74 class FakeUserFeedbackProvider : public TestUserFeedbackProvider {
75 public:
76 FakeUserFeedbackProvider() : synchronize_called_(false) {}
77 ~FakeUserFeedbackProvider() override {}
78 void Synchronize() override { synchronize_called_ = true; }
79 bool synchronize_called() { return synchronize_called_; }
80
81 private:
82 bool synchronize_called_;
83 DISALLOW_COPY_AND_ASSIGN(FakeUserFeedbackProvider);
84 };
85
86 class FakeChromeBrowserProvider : public ios::TestChromeBrowserProvider {
87 public:
88 FakeChromeBrowserProvider()
89 : app_distribution_provider_(
90 base::MakeUnique<FakeAppDistributionProvider>()),
91 user_feedback_provider_(base::MakeUnique<FakeUserFeedbackProvider>()) {}
92 ~FakeChromeBrowserProvider() override {}
93
94 AppDistributionProvider* GetAppDistributionProvider() const override {
95 return app_distribution_provider_.get();
96 }
97
98 UserFeedbackProvider* GetUserFeedbackProvider() const override {
99 return user_feedback_provider_.get();
100 }
101
102 private:
103 std::unique_ptr<FakeAppDistributionProvider> app_distribution_provider_;
104 std::unique_ptr<FakeUserFeedbackProvider> user_feedback_provider_;
105 DISALLOW_COPY_AND_ASSIGN(FakeChromeBrowserProvider);
106 };
107
108 } // namespace
109
110 class AppStateTest : public PlatformTest {
111 protected:
112 AppStateTest() {
113 browser_launcher_mock_ =
114 [OCMockObject mockForProtocol:@protocol(BrowserLauncher)];
115 startup_information_mock_ =
116 [OCMockObject mockForProtocol:@protocol(StartupInformation)];
117 main_application_delegate_ =
118 [OCMockObject mockForClass:[MainApplicationDelegate class]];
119 window_ = [OCMockObject mockForClass:[UIWindow class]];
120 browser_view_information_ =
121 [OCMockObject mockForProtocol:@protocol(BrowserViewInformation)];
122 }
123
124 void initializeIncognitoBlocker(UIWindow* window) {
125 id application = [OCMockObject niceMockForClass:[UIApplication class]];
126 id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
127 id browserViewInformation =
128 [OCMockObject mockForProtocol:@protocol(BrowserViewInformation)];
129 id tabModel = [OCMockObject mockForClass:[TabModel class]];
130
131 [[startup_information_mock_ stub] expireFirstUserActionRecorder];
132 [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
133 [[[tabModel stub] andReturnValue:@NO] isEmpty];
134 [[[browser_view_information_ stub] andReturn:tabModel] otrTabModel];
135 stubNullCurrentBrowserState(browserViewInformation);
136 [[[browser_view_information_ stub] andReturn:nil] currentBVC];
137
138 swizzleMetricsMediatorDisableReporting();
139
140 [app_state_ applicationDidEnterBackground:application
141 memoryHelper:memoryHelper
142 tabSwitcherIsActive:YES];
143
144 metrics_mediator_called_ = NO;
145 }
146
147 void stubNullCurrentBrowserState(id browserViewInformation) {
148 [[[browserViewInformation stub] andDo:^(NSInvocation* invocation) {
149 ios::ChromeBrowserState* browserState = nullptr;
150 [invocation setReturnValue:&browserState];
151 }] currentBrowserState];
152 }
153
154 void stubNullBrowserState(id BVC) {
155 [[[BVC stub] andDo:^(NSInvocation* invocation) {
156 ios::ChromeBrowserState* browserState = nullptr;
157 [invocation setReturnValue:&browserState];
158 }] browserState];
159 }
160
161 void swizzleSafeModeShouldStart(BOOL shouldStart) {
162 safe_mode_swizzle_block_.reset([^BOOL(id self) {
163 return shouldStart;
164 } copy]);
165 safe_mode_swizzler_.reset(new ScopedBlockSwizzler(
166 [SafeModeCoordinator class], @selector(shouldStart),
167 safe_mode_swizzle_block_));
168 }
169
170 void swizzleMetricsMediatorDisableReporting() {
171 metrics_mediator_called_ = NO;
172
173 metrics_mediator_swizzle_block_.reset([^(id self) {
174 metrics_mediator_called_ = YES;
175 } copy]);
176
177 metrics_mediator_swizzler_.reset(new ScopedBlockSwizzler(
178 [MetricsMediator class], @selector(disableReporting),
179 metrics_mediator_swizzle_block_));
180 }
181
182 void swizzleHandleStartupParameters(
183 id<TabOpening> expectedTabOpener,
184 id<BrowserViewInformation> expectedBrowserViewInformation) {
185 handle_startup_swizzle_block_.reset(
186 ^(id self, id<TabOpening> tabOpener,
187 id<StartupInformation> startupInformation,
188 id<BrowserViewInformation> browserViewInformation) {
189 ASSERT_EQ(startup_information_mock_, startupInformation);
190 ASSERT_EQ(expectedTabOpener, tabOpener);
191 ASSERT_EQ(expectedBrowserViewInformation, browserViewInformation);
192 },
193 base::scoped_policy::RETAIN);
194
195 handle_startup_swizzler_.reset(new ScopedBlockSwizzler(
196 [UserActivityHandler class],
197 @selector(handleStartupParametersWithTabOpener:
198 startupInformation:
199 browserViewInformation:),
200 handle_startup_swizzle_block_));
201 }
202
203 AppState* getAppStateWithOpenNTPAndIncognitoBlock(BOOL shouldOpenNTP,
204 UIWindow* window) {
205 AppState* appState = getAppStateWithRealWindow(window);
206
207 id application = [OCMockObject mockForClass:[UIApplication class]];
208 id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
209 id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
210 id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
211 id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
212 id tabModel = [OCMockObject mockForClass:[TabModel class]];
213
214 [[[browser_view_information_ stub] andReturn:tabModel] currentTabModel];
215 [[metricsMediator stub] updateMetricsStateBasedOnPrefsUserTriggered:NO];
216 [[memoryHelper stub] resetForegroundMemoryWarningCount];
217 [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
218 [[[tabOpener stub] andReturnValue:@(shouldOpenNTP)]
219 shouldOpenNTPTabOnActivationOfTabModel:tabModel];
220
221 stubNullCurrentBrowserState(browser_view_information_);
222
223 void (^swizzleBlock)() = ^() {
224 };
225
226 ScopedBlockSwizzler swizzler(
227 [MetricsMediator class],
228 @selector(logLaunchMetricsWithStartupInformation:
229 browserViewInformation:),
230 swizzleBlock);
231
232 [appState applicationWillEnterForeground:application
233 metricsMediator:metricsMediator
234 memoryHelper:memoryHelper
235 tabOpener:tabOpener
236 appNavigation:appNavigation];
237
238 initializeIncognitoBlocker(window);
239
240 return appState;
241 }
242
243 AppState* getAppStateWithMock() {
244 if (!app_state_) {
245 app_state_.reset([[AppState alloc]
246 initWithBrowserLauncher:browser_launcher_mock_
247 startupInformation:startup_information_mock_
248 applicationDelegate:main_application_delegate_]);
249 [app_state_ setWindow:window_];
250 }
251 return app_state_;
252 }
253
254 AppState* getAppStateWithRealWindow(UIWindow* window) {
255 if (!app_state_) {
256 app_state_.reset([[AppState alloc]
257 initWithBrowserLauncher:browser_launcher_mock_
258 startupInformation:startup_information_mock_
259 applicationDelegate:main_application_delegate_]);
260 [app_state_ setWindow:window];
261 }
262 return app_state_;
263 }
264
265 id getBrowserLauncherMock() { return browser_launcher_mock_; }
266 id getStartupInformationMock() { return startup_information_mock_; }
267 id getApplicationDelegateMock() { return main_application_delegate_; }
268 id getWindowMock() { return window_; }
269 id getBrowserViewInformationMock() { return browser_view_information_; }
270
271 BOOL metricsMediatorHasBeenCalled() { return metrics_mediator_called_; }
272
273 private:
274 base::scoped_nsobject<AppState> app_state_;
275 id browser_launcher_mock_;
276 id startup_information_mock_;
277 id main_application_delegate_;
278 id window_;
279 id browser_view_information_;
280 base::mac::ScopedBlock<DecisionBlock> safe_mode_swizzle_block_;
281 base::mac::ScopedBlock<HandleStartupParam> handle_startup_swizzle_block_;
282 base::mac::ScopedBlock<ProceduralBlock> metrics_mediator_swizzle_block_;
283 std::unique_ptr<ScopedBlockSwizzler> safe_mode_swizzler_;
284 std::unique_ptr<ScopedBlockSwizzler> handle_startup_swizzler_;
285 std::unique_ptr<ScopedBlockSwizzler> metrics_mediator_swizzler_;
286 __block BOOL metrics_mediator_called_;
287 };
288
289 // TODO(crbug.com/585700): remove this.
290 // Creates a requestTracker, needed for teardown.
291 void createTracker(BOOL* created, base::Lock* lock) {
292 web::RequestTrackerImpl::GetTrackerForRequestGroupID(@"test");
293 base::AutoLock scoped_lock(*lock);
294 *created = YES;
295 }
296
297 // Used to have a thread handling the closing of the IO threads.
298 class AppStateWithThreadTest : public PlatformTest {
299 protected:
300 AppStateWithThreadTest()
301 : thread_bundle_(web::TestWebThreadBundle::REAL_IO_THREAD) {
302 BOOL created = NO;
303 base::Lock* lock = new base::Lock;
304
305 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE,
306 base::Bind(&createTracker, &created, lock));
307
308 CFTimeInterval start = CACurrentMediaTime();
309
310 // Poll for at most 1s, waiting for the Tracker creation.
311 while (1) {
312 base::AutoLock scoped_lock(*lock);
313 if (created)
314 return;
315 if (CACurrentMediaTime() - start > 1.0) {
316 trackerCreationFailed();
317 return;
318 }
319 // Ensure that other threads have a chance to run even on a single-core
320 // devices.
321 pthread_yield_np();
322 }
323 }
324
325 void trackerCreationFailed() {
326 FAIL() << "Tracker creation took too much time.";
327 }
328
329 private:
330 web::TestWebThreadBundle thread_bundle_;
331 };
332
333 #pragma mark - Tests.
334
335 // Tests -isInSafeMode returns true if there is a SafeModeController.
336 TEST_F(AppStateTest, isInSafeModeTest) {
337 // Setup.
338 id safeModeContollerMock =
339 [OCMockObject mockForClass:[SafeModeCoordinator class]];
340
341 AppState* appState = getAppStateWithMock();
342
343 appState.safeModeCoordinator = nil;
344 ASSERT_FALSE([appState isInSafeMode]);
345 [appState setSafeModeCoordinator:safeModeContollerMock];
346
347 // Action.
348 BOOL result = [appState isInSafeMode];
349
350 // Test.
351 EXPECT_TRUE(result);
352 }
353
354 // Tests that if the application is in background
355 // -requiresHandlingAfterLaunchWithOptions saves the launchOptions and returns
356 // YES (to handle the launch options later).
357 TEST_F(AppStateTest, requiresHandlingAfterLaunchWithOptionsBackground) {
358 // Setup.
359 NSString* sourceApplication = @"com.apple.mobilesafari";
360 NSDictionary* launchOptions =
361 @{UIApplicationLaunchOptionsSourceApplicationKey : sourceApplication};
362
363 AppState* appState = getAppStateWithMock();
364
365 id browserLauncherMock = getBrowserLauncherMock();
366 BrowserInitializationStageType stageBasic = INITIALIZATION_STAGE_BASIC;
367 [[browserLauncherMock expect] startUpBrowserToStage:stageBasic];
368 [[browserLauncherMock expect] setLaunchOptions:launchOptions];
369
370 // Action.
371 BOOL result = [appState requiresHandlingAfterLaunchWithOptions:launchOptions
372 stateBackground:YES];
373
374 // Test.
375 EXPECT_TRUE(result);
376 EXPECT_OCMOCK_VERIFY(browserLauncherMock);
377 }
378
379 // Tests that if the application is active and Safe Mode should be activated
380 // -requiresHandlingAfterLaunchWithOptions save the launch options and activate
381 // the Safe Mode.
382 TEST_F(AppStateTest, requiresHandlingAfterLaunchWithOptionsForegroundSafeMode) {
383 // Setup.
384 NSString* sourceApplication = @"com.apple.mobilesafari";
385 NSDictionary* launchOptions =
386 @{UIApplicationLaunchOptionsSourceApplicationKey : sourceApplication};
387
388 id windowMock = getWindowMock();
389 [[[windowMock stub] andReturn:nil] rootViewController];
390 [[windowMock expect] setRootViewController:[OCMArg any]];
391 [[windowMock expect] makeKeyAndVisible];
392
393 AppState* appState = getAppStateWithMock();
394
395 id browserLauncherMock = getBrowserLauncherMock();
396 BrowserInitializationStageType stageBasic = INITIALIZATION_STAGE_BASIC;
397 [[browserLauncherMock expect] startUpBrowserToStage:stageBasic];
398 [[browserLauncherMock expect] setLaunchOptions:launchOptions];
399
400 swizzleSafeModeShouldStart(YES);
401
402 ASSERT_FALSE([appState isInSafeMode]);
403
404 // Action.
405 BOOL result = [appState requiresHandlingAfterLaunchWithOptions:launchOptions
406 stateBackground:NO];
407
408 // Test.
409 EXPECT_TRUE(result);
410 EXPECT_TRUE([appState isInSafeMode]);
411 EXPECT_OCMOCK_VERIFY(browserLauncherMock);
412 EXPECT_OCMOCK_VERIFY(windowMock);
413 }
414
415 // Tests that if the application is active
416 // -requiresHandlingAfterLaunchWithOptions saves the launchOptions and start the
417 // application in foreground.
418 TEST_F(AppStateTest, requiresHandlingAfterLaunchWithOptionsForeground) {
419 // Setup.
420 NSString* sourceApplication = @"com.apple.mobilesafari";
421 NSDictionary* launchOptions =
422 @{UIApplicationLaunchOptionsSourceApplicationKey : sourceApplication};
423
424 [[[getStartupInformationMock() stub] andReturnValue:@YES] isColdStart];
425
426 [[[getWindowMock() stub] andReturn:nil] rootViewController];
427
428 AppState* appState = getAppStateWithMock();
429
430 id browserLauncherMock = getBrowserLauncherMock();
431 BrowserInitializationStageType stageBasic = INITIALIZATION_STAGE_BASIC;
432 [[browserLauncherMock expect] startUpBrowserToStage:stageBasic];
433 BrowserInitializationStageType stageForeground =
434 INITIALIZATION_STAGE_FOREGROUND;
435 [[browserLauncherMock expect] startUpBrowserToStage:stageForeground];
436 [[browserLauncherMock expect] setLaunchOptions:launchOptions];
437
438 swizzleSafeModeShouldStart(NO);
439
440 // Action.
441 BOOL result = [appState requiresHandlingAfterLaunchWithOptions:launchOptions
442 stateBackground:NO];
443
444 // Test.
445 EXPECT_TRUE(result);
446 EXPECT_OCMOCK_VERIFY(browserLauncherMock);
447 }
448
449 // Test that -willResignActive set cold start to NO and launch record.
450 TEST(AppStateNoFixtureTest, willResignActive) {
451 // Setup.
452 id tabModel = [OCMockObject mockForClass:[TabModel class]];
453 [[tabModel expect] recordSessionMetrics];
454
455 id browserViewInformation =
456 [OCMockObject mockForProtocol:@protocol(BrowserViewInformation)];
457
458 [[[browserViewInformation stub] andReturn:tabModel] mainTabModel];
459
460 id browserLauncher =
461 [OCMockObject mockForProtocol:@protocol(BrowserLauncher)];
462 [[[browserLauncher stub] andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
463 browserInitializationStage];
464 [[[browserLauncher stub] andReturn:browserViewInformation]
465 browserViewInformation];
466
467 id applicationDelegate =
468 [OCMockObject mockForClass:[MainApplicationDelegate class]];
469 id window = [OCMockObject mockForClass:[UIWindow class]];
470
471 base::scoped_nsobject<FakeStartupInformation> startupInformation(
472 [[FakeStartupInformation alloc] init]);
473 [startupInformation setIsColdStart:YES];
474
475 base::scoped_nsobject<AppState> appState([[AppState alloc]
476 initWithBrowserLauncher:browserLauncher
477 startupInformation:startupInformation
478 applicationDelegate:applicationDelegate]);
479 [appState setWindow:window];
480
481 ASSERT_TRUE([startupInformation isColdStart]);
482
483 // Action.
484 [appState willResignActiveTabModel];
485
486 // Test.
487 EXPECT_FALSE([startupInformation isColdStart]);
488 EXPECT_OCMOCK_VERIFY(tabModel);
489 }
490
491 // Test that -applicationWillTerminate clears everything.
492 TEST_F(AppStateWithThreadTest, willTerminate) {
493 // Setup.
494 IOSChromeScopedTestingChromeBrowserProvider provider_(
495 base::MakeUnique<FakeChromeBrowserProvider>());
496
497 id browserLauncher =
498 [OCMockObject mockForProtocol:@protocol(BrowserLauncher)];
499 id applicationDelegate =
500 [OCMockObject mockForClass:[MainApplicationDelegate class]];
501 id window = [OCMockObject mockForClass:[UIWindow class]];
502 id browserViewInformation =
503 [OCMockObject mockForProtocol:@protocol(BrowserViewInformation)];
504 [[[browserLauncher stub] andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
505 browserInitializationStage];
506 [[[browserLauncher stub] andReturn:browserViewInformation]
507 browserViewInformation];
508
509 id settingsNavigationController =
510 [OCMockObject mockForClass:[SettingsNavigationController class]];
511
512 id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
513 [[[appNavigation stub] andReturn:settingsNavigationController]
514 settingsNavigationController];
515 [[appNavigation expect] closeSettingsAnimated:NO completion:nil];
516
517 [[browserViewInformation expect] cleanDeviceSharingManager];
518 [[browserViewInformation expect] haltAllTabs];
519
520 id startupInformation =
521 [OCMockObject mockForProtocol:@protocol(StartupInformation)];
522 [[startupInformation expect] stopChromeMain];
523
524 base::scoped_nsobject<AppState> appState([[AppState alloc]
525 initWithBrowserLauncher:browserLauncher
526 startupInformation:startupInformation
527 applicationDelegate:applicationDelegate]);
528 [appState setWindow:window];
529
530 id application = [OCMockObject mockForClass:[UIApplication class]];
531 [[application expect] setMinimumBackgroundFetchInterval:
532 UIApplicationBackgroundFetchIntervalNever];
533
534 // Action.
535 [appState applicationWillTerminate:application
536 applicationNavigation:appNavigation];
537
538 // Test.
539 EXPECT_OCMOCK_VERIFY(startupInformation);
540 EXPECT_OCMOCK_VERIFY(appNavigation);
541 EXPECT_OCMOCK_VERIFY(browserViewInformation);
542 EXPECT_OCMOCK_VERIFY(application);
543 FakeAppDistributionProvider* provider =
544 static_cast<FakeAppDistributionProvider*>(
545 ios::GetChromeBrowserProvider()->GetAppDistributionProvider());
546 EXPECT_TRUE(provider->cancel_called());
547 }
548
549 // Test that -resumeSessionWithTabOpener removes incognito blocker,
550 // restart metrics and launchs from StartupParameters if they exist.
551 TEST_F(AppStateTest, resumeSessionWithStartupParameters) {
552 // Setup.
553
554 // BrowserLauncher.
555 id browserViewInformation = getBrowserViewInformationMock();
556 [[[getBrowserLauncherMock() stub]
557 andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
558 browserInitializationStage];
559 [[[getBrowserLauncherMock() stub] andReturn:browserViewInformation]
560 browserViewInformation];
561
562 // StartupInformation.
563 id appStartupParameters =
564 [OCMockObject mockForClass:[AppStartupParameters class]];
565 [[[getStartupInformationMock() stub] andReturn:appStartupParameters]
566 startupParameters];
567 [[[getStartupInformationMock() stub] andReturnValue:@NO] isColdStart];
568
569 // TabOpening.
570 id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
571 // TabSwitcher.
572 id tabSwitcher = [OCMockObject mockForProtocol:@protocol(TabSwitching)];
573
574 // BrowserViewInformation.
575 id mainTabModel = [OCMockObject mockForClass:[TabModel class]];
576 [[mainTabModel expect] resetSessionMetrics];
577 [[[browserViewInformation stub] andReturn:mainTabModel] mainTabModel];
578
579 // Swizzle Startup Parameters.
580 swizzleHandleStartupParameters(tabOpener, browserViewInformation);
581
582 UIWindow* window = [[[UIWindow alloc] init] autorelease];
583 AppState* appState = getAppStateWithOpenNTPAndIncognitoBlock(NO, window);
584
585 ASSERT_EQ(NSUInteger(1), [window subviews].count);
586
587 // Action.
588 [appState resumeSessionWithTabOpener:tabOpener tabSwitcher:tabSwitcher];
589
590 // Test.
591 EXPECT_EQ(NSUInteger(0), [window subviews].count);
592 EXPECT_OCMOCK_VERIFY(mainTabModel);
593 }
594
595 // Test that -resumeSessionWithTabOpener removes incognito blocker,
596 // restart metrics and creates a new tab from tab switcher if shouldOpenNTP is
597 // YES.
598 TEST_F(AppStateTest, resumeSessionShouldOpenNTPTabSwitcher) {
599 // Setup.
600 // BrowserLauncher.
601 id browserViewInformation = getBrowserViewInformationMock();
602 [[[getBrowserLauncherMock() stub]
603 andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
604 browserInitializationStage];
605 [[[getBrowserLauncherMock() stub] andReturn:browserViewInformation]
606 browserViewInformation];
607
608 // StartupInformation.
609 [[[getStartupInformationMock() stub] andReturn:nil] startupParameters];
610 [[[getStartupInformationMock() stub] andReturnValue:@NO] isColdStart];
611
612 // TabOpening.
613 id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
614
615 // BrowserViewInformation.
616 id mainTabModel = [OCMockObject mockForClass:[TabModel class]];
617 [[mainTabModel expect] resetSessionMetrics];
618 [[[browserViewInformation stub] andReturn:mainTabModel] mainTabModel];
619
620 // TabSwitcher.
621 id tabSwitcher = [OCMockObject mockForProtocol:@protocol(TabSwitching)];
622 [[[tabSwitcher stub] andReturnValue:@YES] openNewTabFromTabSwitcher];
623
624 UIWindow* window = [[[UIWindow alloc] init] autorelease];
625 AppState* appState = getAppStateWithOpenNTPAndIncognitoBlock(YES, window);
626
627 ASSERT_EQ(NSUInteger(1), [window subviews].count);
628
629 // Action.
630 [appState resumeSessionWithTabOpener:tabOpener tabSwitcher:tabSwitcher];
631
632 // Test.
633 EXPECT_EQ(NSUInteger(0), [window subviews].count);
634 EXPECT_OCMOCK_VERIFY(mainTabModel);
635 }
636
637 // Test that -resumeSessionWithTabOpener removes incognito blocker,
638 // restart metrics and creates a new tab if shouldOpenNTP is YES.
639 TEST_F(AppStateTest, resumeSessionShouldOpenNTPNoTabSwitcher) {
640 // Setup.
641 // BrowserLauncher.
642 id browserViewInformation = getBrowserViewInformationMock();
643 [[[getBrowserLauncherMock() stub]
644 andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
645 browserInitializationStage];
646 [[[getBrowserLauncherMock() stub] andReturn:browserViewInformation]
647 browserViewInformation];
648
649 // StartupInformation.
650 [[[getStartupInformationMock() stub] andReturn:nil] startupParameters];
651 [[[getStartupInformationMock() stub] andReturnValue:@NO] isColdStart];
652
653 // TabOpening.
654 id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
655
656 // BrowserViewInformation.
657 id mainTabModel = [OCMockObject mockForClass:[TabModel class]];
658 [[mainTabModel expect] resetSessionMetrics];
659
660 id currentBVC = [OCMockObject mockForClass:[BrowserViewController class]];
661 [[currentBVC expect] newTab:nil];
662 stubNullBrowserState(currentBVC);
663
664 [[[browserViewInformation stub] andReturn:mainTabModel] mainTabModel];
665 [[[browserViewInformation stub] andReturn:currentBVC] currentBVC];
666
667 // TabSwitcher.
668 id tabSwitcher = [OCMockObject mockForProtocol:@protocol(TabSwitching)];
669 [[[tabSwitcher stub] andReturnValue:@NO] openNewTabFromTabSwitcher];
670
671 UIWindow* window = [[[UIWindow alloc] init] autorelease];
672 AppState* appState = getAppStateWithOpenNTPAndIncognitoBlock(YES, window);
673
674 // incognitoBlocker.
675 ASSERT_EQ(NSUInteger(1), [window subviews].count);
676
677 // Action.
678 [appState resumeSessionWithTabOpener:tabOpener tabSwitcher:tabSwitcher];
679
680 // Test.
681 EXPECT_EQ(NSUInteger(0), [window subviews].count);
682 EXPECT_OCMOCK_VERIFY(mainTabModel);
683 EXPECT_OCMOCK_VERIFY(currentBVC);
684 }
685
686 // Tests that -applicationWillEnterForeground resets components as needed.
687 TEST_F(AppStateTest, applicationWillEnterForeground) {
688 // Setup.
689 IOSChromeScopedTestingChromeBrowserProvider provider_(
690 base::MakeUnique<FakeChromeBrowserProvider>());
691 id application = [OCMockObject mockForClass:[UIApplication class]];
692 id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
693 id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
694 id browserViewInformation = getBrowserViewInformationMock();
695 id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
696 id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
697 id tabModel = [OCMockObject mockForClass:[TabModel class]];
698
699 BrowserInitializationStageType stage = INITIALIZATION_STAGE_FOREGROUND;
700 [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
701 browserInitializationStage];
702 [[[getBrowserLauncherMock() stub] andReturn:browserViewInformation]
703 browserViewInformation];
704 [[[browserViewInformation stub] andReturn:tabModel] currentTabModel];
705 [[metricsMediator expect] updateMetricsStateBasedOnPrefsUserTriggered:NO];
706 [[memoryHelper expect] resetForegroundMemoryWarningCount];
707 [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
708 [[[tabOpener stub] andReturnValue:@YES]
709 shouldOpenNTPTabOnActivationOfTabModel:tabModel];
710
711 stubNullCurrentBrowserState(browserViewInformation);
712
713 void (^swizzleBlock)() = ^() {
714 };
715
716 ScopedBlockSwizzler swizzler(
717 [MetricsMediator class],
718 @selector(logLaunchMetricsWithStartupInformation:browserViewInformation:),
719 swizzleBlock);
720
721 // Actions.
722 [getAppStateWithMock() applicationWillEnterForeground:application
723 metricsMediator:metricsMediator
724 memoryHelper:memoryHelper
725 tabOpener:tabOpener
726 appNavigation:appNavigation];
727
728 // Tests.
729 EXPECT_OCMOCK_VERIFY(metricsMediator);
730 EXPECT_OCMOCK_VERIFY(memoryHelper);
731 FakeUserFeedbackProvider* user_feedback_provider =
732 static_cast<FakeUserFeedbackProvider*>(
733 ios::GetChromeBrowserProvider()->GetUserFeedbackProvider());
734 EXPECT_TRUE(user_feedback_provider->synchronize_called());
735 }
736
737 // Tests that -applicationWillEnterForeground starts the browser if the
738 // application is in background.
739 TEST_F(AppStateTest, applicationWillEnterForegroundFromBackground) {
740 // Setup.
741 id application = [OCMockObject mockForClass:[UIApplication class]];
742 id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
743 id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
744 id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
745 id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
746
747 BrowserInitializationStageType stage = INITIALIZATION_STAGE_BACKGROUND;
748 [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
749 browserInitializationStage];
750
751 [[[getWindowMock() stub] andReturn:nil] rootViewController];
752 swizzleSafeModeShouldStart(NO);
753
754 [[[getStartupInformationMock() stub] andReturnValue:@YES] isColdStart];
755 [[getBrowserLauncherMock() expect]
756 startUpBrowserToStage:INITIALIZATION_STAGE_FOREGROUND];
757
758 // Actions.
759 [getAppStateWithMock() applicationWillEnterForeground:application
760 metricsMediator:metricsMediator
761 memoryHelper:memoryHelper
762 tabOpener:tabOpener
763 appNavigation:appNavigation];
764
765 // Tests.
766 EXPECT_OCMOCK_VERIFY(getBrowserLauncherMock());
767 }
768
769 // Tests that -applicationWillEnterForeground starts the safe mode if the
770 // application is in background.
771 TEST_F(AppStateTest,
772 applicationWillEnterForegroundFromBackgroundShouldStartSafeMode) {
773 // Setup.
774 id application = [OCMockObject mockForClass:[UIApplication class]];
775 id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
776 id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
777 id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
778 id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
779
780 id window = getWindowMock();
781
782 BrowserInitializationStageType stage = INITIALIZATION_STAGE_BACKGROUND;
783 [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
784 browserInitializationStage];
785
786 [[[window stub] andReturn:nil] rootViewController];
787 [[window expect] makeKeyAndVisible];
788 [[window stub] setRootViewController:[OCMArg any]];
789 swizzleSafeModeShouldStart(YES);
790
791 // Actions.
792 [getAppStateWithMock() applicationWillEnterForeground:application
793 metricsMediator:metricsMediator
794 memoryHelper:memoryHelper
795 tabOpener:tabOpener
796 appNavigation:appNavigation];
797
798 // Tests.
799 EXPECT_OCMOCK_VERIFY(window);
800 EXPECT_TRUE([getAppStateWithMock() isInSafeMode]);
801 }
802
803 // Tests that -applicationWillEnterForeground returns directly if the
804 // application is in safe mode and in foreground
805 TEST_F(AppStateTest, applicationWillEnterForegroundFromForegroundSafeMode) {
806 // Setup.
807 id application = [OCMockObject mockForClass:[UIApplication class]];
808 id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
809 id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
810 id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
811 id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
812
813 BrowserInitializationStageType stage = INITIALIZATION_STAGE_FOREGROUND;
814 [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
815 browserInitializationStage];
816
817 AppState* appState = getAppStateWithMock();
818
819 UIWindow* window = [[[UIWindow alloc] init] autorelease];
820 appState.safeModeCoordinator =
821 [[[SafeModeCoordinator alloc] initWithWindow:window] autorelease];
822
823 ASSERT_TRUE([appState isInSafeMode]);
824
825 // Actions.
826 [appState applicationWillEnterForeground:application
827 metricsMediator:metricsMediator
828 memoryHelper:memoryHelper
829 tabOpener:tabOpener
830 appNavigation:appNavigation];
831 }
832
833 // Tests that -applicationDidEnterBackground creates an incognito blocker.
834 TEST_F(AppStateTest, applicationDidEnterBackgroundIncognito) {
835 // Setup.
836 UIWindow* window = [[[UIWindow alloc] init] autorelease];
837 id application = [OCMockObject niceMockForClass:[UIApplication class]];
838 id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
839 id browserViewInformation = getBrowserViewInformationMock();
840 id tabModel = [OCMockObject mockForClass:[TabModel class]];
841 id startupInformation = getStartupInformationMock();
842 id browserLauncher = getBrowserLauncherMock();
843 BrowserInitializationStageType stage = INITIALIZATION_STAGE_FOREGROUND;
844
845 AppState* appState = getAppStateWithRealWindow(window);
846
847 [[startupInformation expect] expireFirstUserActionRecorder];
848 [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
849 [[[tabModel stub] andReturnValue:@NO] isEmpty];
850 [[[browserViewInformation stub] andReturn:tabModel] otrTabModel];
851 [[[browserViewInformation stub] andReturn:nil] currentBVC];
852 stubNullCurrentBrowserState(browserViewInformation);
853 [[[browserLauncher stub] andReturnValue:@(stage)] browserInitializationStage];
854 [[[browserLauncher stub] andReturn:browserViewInformation]
855 browserViewInformation];
856
857 swizzleMetricsMediatorDisableReporting();
858
859 ASSERT_EQ(NSUInteger(0), [window subviews].count);
860
861 // Action.
862 [appState applicationDidEnterBackground:application
863 memoryHelper:memoryHelper
864 tabSwitcherIsActive:YES];
865
866 // Tests.
867 EXPECT_OCMOCK_VERIFY(startupInformation);
868 EXPECT_TRUE(metricsMediatorHasBeenCalled());
869 EXPECT_EQ(NSUInteger(1), [window subviews].count);
870 }
871
872 // Tests that -applicationDidEnterBackground do nothing if the application has
873 // never been in a Foreground stage.
874 TEST_F(AppStateTest, applicationDidEnterBackgroundStageBackground) {
875 // Setup.
876 UIWindow* window = [[[UIWindow alloc] init] autorelease];
877 id application = [OCMockObject mockForClass:[UIApplication class]];
878 id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
879 id browserLauncher = getBrowserLauncherMock();
880 BrowserInitializationStageType stage = INITIALIZATION_STAGE_BACKGROUND;
881
882 [[[browserLauncher stub] andReturnValue:@(stage)] browserInitializationStage];
883
884 ASSERT_EQ(NSUInteger(0), [window subviews].count);
885
886 // Action.
887 [getAppStateWithRealWindow(window) applicationDidEnterBackground:application
888 memoryHelper:memoryHelper
889 tabSwitcherIsActive:YES];
890
891 // Tests.
892 EXPECT_EQ(NSUInteger(0), [window subviews].count);
893 }
894
895 // Tests that -applicationDidEnterBackground does not create an incognito
896 // blocker if there is no incognito tab.
897 TEST_F(AppStateTest, applicationDidEnterBackgroundNoIncognitoBlocker) {
898 // Setup.
899 UIWindow* window = [[[UIWindow alloc] init] autorelease];
900 id application = [OCMockObject niceMockForClass:[UIApplication class]];
901 id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
902 id browserViewInformation = getBrowserViewInformationMock();
903 id tabModel = [OCMockObject mockForClass:[TabModel class]];
904 id startupInformation = getStartupInformationMock();
905 id browserLauncher = getBrowserLauncherMock();
906 BrowserInitializationStageType stage = INITIALIZATION_STAGE_FOREGROUND;
907
908 AppState* appState = getAppStateWithRealWindow(window);
909
910 [[startupInformation expect] expireFirstUserActionRecorder];
911 [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
912 [[[tabModel stub] andReturnValue:@YES] isEmpty];
913 [[[browserViewInformation stub] andReturn:tabModel] otrTabModel];
914 [[[browserViewInformation stub] andReturn:nil] currentBVC];
915 stubNullCurrentBrowserState(browserViewInformation);
916 [[[browserLauncher stub] andReturnValue:@(stage)] browserInitializationStage];
917 [[[browserLauncher stub] andReturn:browserViewInformation]
918 browserViewInformation];
919
920 swizzleMetricsMediatorDisableReporting();
921
922 ASSERT_EQ(NSUInteger(0), [window subviews].count);
923
924 // Action.
925 [appState applicationDidEnterBackground:application
926 memoryHelper:memoryHelper
927 tabSwitcherIsActive:YES];
928
929 // Tests.
930 EXPECT_OCMOCK_VERIFY(startupInformation);
931 EXPECT_TRUE(metricsMediatorHasBeenCalled());
932 EXPECT_EQ(NSUInteger(0), [window subviews].count);
933 }
OLDNEW
« no previous file with comments | « ios/chrome/app/application_delegate/app_state_testing.h ('k') | ios/chrome/app/application_delegate/background_activity.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698