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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: ios/chrome/app/application_delegate/app_state_unittest.mm
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm
new file mode 100644
index 0000000000000000000000000000000000000000..f04cc588137e0ef8890252c621423eb19885557a
--- /dev/null
+++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -0,0 +1,933 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/app/application_delegate/app_state.h"
+
+#import <QuartzCore/QuartzCore.h>
+
+#include "base/ios/block_types.h"
+#include "base/mac/scoped_block.h"
+#import "base/mac/scoped_nsobject.h"
+#include "base/memory/ptr_util.h"
+#include "base/synchronization/lock.h"
+#import "ios/chrome/app/application_delegate/app_navigation.h"
+#import "ios/chrome/app/application_delegate/app_state_testing.h"
+#import "ios/chrome/app/application_delegate/browser_launcher.h"
+#import "ios/chrome/app/application_delegate/fake_startup_information.h"
+#import "ios/chrome/app/application_delegate/memory_warning_helper.h"
+#import "ios/chrome/app/application_delegate/metrics_mediator.h"
+#import "ios/chrome/app/application_delegate/mock_tab_opener.h"
+#import "ios/chrome/app/application_delegate/startup_information.h"
+#import "ios/chrome/app/application_delegate/tab_switching.h"
+#import "ios/chrome/app/application_delegate/user_activity_handler.h"
+#import "ios/chrome/app/main_application_delegate.h"
+#import "ios/chrome/app/safe_mode/safe_mode_coordinator.h"
+#import "ios/chrome/app/safe_mode_crashing_modules_config.h"
+#import "ios/chrome/browser/app_startup_parameters.h"
+#include "ios/chrome/browser/chrome_url_constants.h"
+#import "ios/chrome/browser/device_sharing/device_sharing_manager.h"
+#import "ios/chrome/browser/geolocation/omnibox_geolocation_config.h"
+#import "ios/chrome/browser/tabs/tab_model.h"
+#import "ios/chrome/browser/ui/browser_view_controller.h"
+#import "ios/chrome/browser/ui/main/browser_view_information.h"
+#import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
+#import "ios/chrome/test/base/scoped_block_swizzler.h"
+#include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.h"
+#include "ios/public/provider/chrome/browser/distribution/app_distribution_provider.h"
+#include "ios/public/provider/chrome/browser/test_chrome_browser_provider.h"
+#include "ios/public/provider/chrome/browser/user_feedback/test_user_feedback_provider.h"
+#import "ios/testing/ocmock_complex_type_helper.h"
+#include "ios/web/net/request_tracker_impl.h"
+#import "ios/web/public/test/test_web_thread_bundle.h"
+#include "testing/platform_test.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+#include "third_party/ocmock/gtest_support.h"
+
+#pragma mark - Class definition.
+
+namespace {
+
+// A block that takes self as argument and return a BOOL.
+typedef BOOL (^DecisionBlock)(id self);
+// A block that takes the arguments of UserActivityHandler's
+// +handleStartupParametersWithTabOpener.
+typedef void (^HandleStartupParam)(
+ id self,
+ id<TabOpening> tabOpener,
+ id<StartupInformation> startupInformation,
+ id<BrowserViewInformation> browserViewInformation);
+
+class FakeAppDistributionProvider : public AppDistributionProvider {
+ public:
+ FakeAppDistributionProvider() : cancel_called_(false) {}
+ ~FakeAppDistributionProvider() override {}
+
+ void CancelDistributionNotifications() override { cancel_called_ = true; }
+ bool cancel_called() { return cancel_called_; }
+
+ private:
+ bool cancel_called_;
+ DISALLOW_COPY_AND_ASSIGN(FakeAppDistributionProvider);
+};
+
+class FakeUserFeedbackProvider : public TestUserFeedbackProvider {
+ public:
+ FakeUserFeedbackProvider() : synchronize_called_(false) {}
+ ~FakeUserFeedbackProvider() override {}
+ void Synchronize() override { synchronize_called_ = true; }
+ bool synchronize_called() { return synchronize_called_; }
+
+ private:
+ bool synchronize_called_;
+ DISALLOW_COPY_AND_ASSIGN(FakeUserFeedbackProvider);
+};
+
+class FakeChromeBrowserProvider : public ios::TestChromeBrowserProvider {
+ public:
+ FakeChromeBrowserProvider()
+ : app_distribution_provider_(
+ base::MakeUnique<FakeAppDistributionProvider>()),
+ user_feedback_provider_(base::MakeUnique<FakeUserFeedbackProvider>()) {}
+ ~FakeChromeBrowserProvider() override {}
+
+ AppDistributionProvider* GetAppDistributionProvider() const override {
+ return app_distribution_provider_.get();
+ }
+
+ UserFeedbackProvider* GetUserFeedbackProvider() const override {
+ return user_feedback_provider_.get();
+ }
+
+ private:
+ std::unique_ptr<FakeAppDistributionProvider> app_distribution_provider_;
+ std::unique_ptr<FakeUserFeedbackProvider> user_feedback_provider_;
+ DISALLOW_COPY_AND_ASSIGN(FakeChromeBrowserProvider);
+};
+
+} // namespace
+
+class AppStateTest : public PlatformTest {
+ protected:
+ AppStateTest() {
+ browser_launcher_mock_ =
+ [OCMockObject mockForProtocol:@protocol(BrowserLauncher)];
+ startup_information_mock_ =
+ [OCMockObject mockForProtocol:@protocol(StartupInformation)];
+ main_application_delegate_ =
+ [OCMockObject mockForClass:[MainApplicationDelegate class]];
+ window_ = [OCMockObject mockForClass:[UIWindow class]];
+ browser_view_information_ =
+ [OCMockObject mockForProtocol:@protocol(BrowserViewInformation)];
+ }
+
+ void initializeIncognitoBlocker(UIWindow* window) {
+ id application = [OCMockObject niceMockForClass:[UIApplication class]];
+ id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
+ id browserViewInformation =
+ [OCMockObject mockForProtocol:@protocol(BrowserViewInformation)];
+ id tabModel = [OCMockObject mockForClass:[TabModel class]];
+
+ [[startup_information_mock_ stub] expireFirstUserActionRecorder];
+ [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
+ [[[tabModel stub] andReturnValue:@NO] isEmpty];
+ [[[browser_view_information_ stub] andReturn:tabModel] otrTabModel];
+ stubNullCurrentBrowserState(browserViewInformation);
+ [[[browser_view_information_ stub] andReturn:nil] currentBVC];
+
+ swizzleMetricsMediatorDisableReporting();
+
+ [app_state_ applicationDidEnterBackground:application
+ memoryHelper:memoryHelper
+ tabSwitcherIsActive:YES];
+
+ metrics_mediator_called_ = NO;
+ }
+
+ void stubNullCurrentBrowserState(id browserViewInformation) {
+ [[[browserViewInformation stub] andDo:^(NSInvocation* invocation) {
+ ios::ChromeBrowserState* browserState = nullptr;
+ [invocation setReturnValue:&browserState];
+ }] currentBrowserState];
+ }
+
+ void stubNullBrowserState(id BVC) {
+ [[[BVC stub] andDo:^(NSInvocation* invocation) {
+ ios::ChromeBrowserState* browserState = nullptr;
+ [invocation setReturnValue:&browserState];
+ }] browserState];
+ }
+
+ void swizzleSafeModeShouldStart(BOOL shouldStart) {
+ safe_mode_swizzle_block_.reset([^BOOL(id self) {
+ return shouldStart;
+ } copy]);
+ safe_mode_swizzler_.reset(new ScopedBlockSwizzler(
+ [SafeModeCoordinator class], @selector(shouldStart),
+ safe_mode_swizzle_block_));
+ }
+
+ void swizzleMetricsMediatorDisableReporting() {
+ metrics_mediator_called_ = NO;
+
+ metrics_mediator_swizzle_block_.reset([^(id self) {
+ metrics_mediator_called_ = YES;
+ } copy]);
+
+ metrics_mediator_swizzler_.reset(new ScopedBlockSwizzler(
+ [MetricsMediator class], @selector(disableReporting),
+ metrics_mediator_swizzle_block_));
+ }
+
+ void swizzleHandleStartupParameters(
+ id<TabOpening> expectedTabOpener,
+ id<BrowserViewInformation> expectedBrowserViewInformation) {
+ handle_startup_swizzle_block_.reset(
+ ^(id self, id<TabOpening> tabOpener,
+ id<StartupInformation> startupInformation,
+ id<BrowserViewInformation> browserViewInformation) {
+ ASSERT_EQ(startup_information_mock_, startupInformation);
+ ASSERT_EQ(expectedTabOpener, tabOpener);
+ ASSERT_EQ(expectedBrowserViewInformation, browserViewInformation);
+ },
+ base::scoped_policy::RETAIN);
+
+ handle_startup_swizzler_.reset(new ScopedBlockSwizzler(
+ [UserActivityHandler class],
+ @selector(handleStartupParametersWithTabOpener:
+ startupInformation:
+ browserViewInformation:),
+ handle_startup_swizzle_block_));
+ }
+
+ AppState* getAppStateWithOpenNTPAndIncognitoBlock(BOOL shouldOpenNTP,
+ UIWindow* window) {
+ AppState* appState = getAppStateWithRealWindow(window);
+
+ id application = [OCMockObject mockForClass:[UIApplication class]];
+ id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
+ id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
+ id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
+ id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
+ id tabModel = [OCMockObject mockForClass:[TabModel class]];
+
+ [[[browser_view_information_ stub] andReturn:tabModel] currentTabModel];
+ [[metricsMediator stub] updateMetricsStateBasedOnPrefsUserTriggered:NO];
+ [[memoryHelper stub] resetForegroundMemoryWarningCount];
+ [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
+ [[[tabOpener stub] andReturnValue:@(shouldOpenNTP)]
+ shouldOpenNTPTabOnActivationOfTabModel:tabModel];
+
+ stubNullCurrentBrowserState(browser_view_information_);
+
+ void (^swizzleBlock)() = ^() {
+ };
+
+ ScopedBlockSwizzler swizzler(
+ [MetricsMediator class],
+ @selector(logLaunchMetricsWithStartupInformation:
+ browserViewInformation:),
+ swizzleBlock);
+
+ [appState applicationWillEnterForeground:application
+ metricsMediator:metricsMediator
+ memoryHelper:memoryHelper
+ tabOpener:tabOpener
+ appNavigation:appNavigation];
+
+ initializeIncognitoBlocker(window);
+
+ return appState;
+ }
+
+ AppState* getAppStateWithMock() {
+ if (!app_state_) {
+ app_state_.reset([[AppState alloc]
+ initWithBrowserLauncher:browser_launcher_mock_
+ startupInformation:startup_information_mock_
+ applicationDelegate:main_application_delegate_]);
+ [app_state_ setWindow:window_];
+ }
+ return app_state_;
+ }
+
+ AppState* getAppStateWithRealWindow(UIWindow* window) {
+ if (!app_state_) {
+ app_state_.reset([[AppState alloc]
+ initWithBrowserLauncher:browser_launcher_mock_
+ startupInformation:startup_information_mock_
+ applicationDelegate:main_application_delegate_]);
+ [app_state_ setWindow:window];
+ }
+ return app_state_;
+ }
+
+ id getBrowserLauncherMock() { return browser_launcher_mock_; }
+ id getStartupInformationMock() { return startup_information_mock_; }
+ id getApplicationDelegateMock() { return main_application_delegate_; }
+ id getWindowMock() { return window_; }
+ id getBrowserViewInformationMock() { return browser_view_information_; }
+
+ BOOL metricsMediatorHasBeenCalled() { return metrics_mediator_called_; }
+
+ private:
+ base::scoped_nsobject<AppState> app_state_;
+ id browser_launcher_mock_;
+ id startup_information_mock_;
+ id main_application_delegate_;
+ id window_;
+ id browser_view_information_;
+ base::mac::ScopedBlock<DecisionBlock> safe_mode_swizzle_block_;
+ base::mac::ScopedBlock<HandleStartupParam> handle_startup_swizzle_block_;
+ base::mac::ScopedBlock<ProceduralBlock> metrics_mediator_swizzle_block_;
+ std::unique_ptr<ScopedBlockSwizzler> safe_mode_swizzler_;
+ std::unique_ptr<ScopedBlockSwizzler> handle_startup_swizzler_;
+ std::unique_ptr<ScopedBlockSwizzler> metrics_mediator_swizzler_;
+ __block BOOL metrics_mediator_called_;
+};
+
+// TODO(crbug.com/585700): remove this.
+// Creates a requestTracker, needed for teardown.
+void createTracker(BOOL* created, base::Lock* lock) {
+ web::RequestTrackerImpl::GetTrackerForRequestGroupID(@"test");
+ base::AutoLock scoped_lock(*lock);
+ *created = YES;
+}
+
+// Used to have a thread handling the closing of the IO threads.
+class AppStateWithThreadTest : public PlatformTest {
+ protected:
+ AppStateWithThreadTest()
+ : thread_bundle_(web::TestWebThreadBundle::REAL_IO_THREAD) {
+ BOOL created = NO;
+ base::Lock* lock = new base::Lock;
+
+ web::WebThread::PostTask(web::WebThread::IO, FROM_HERE,
+ base::Bind(&createTracker, &created, lock));
+
+ CFTimeInterval start = CACurrentMediaTime();
+
+ // Poll for at most 1s, waiting for the Tracker creation.
+ while (1) {
+ base::AutoLock scoped_lock(*lock);
+ if (created)
+ return;
+ if (CACurrentMediaTime() - start > 1.0) {
+ trackerCreationFailed();
+ return;
+ }
+ // Ensure that other threads have a chance to run even on a single-core
+ // devices.
+ pthread_yield_np();
+ }
+ }
+
+ void trackerCreationFailed() {
+ FAIL() << "Tracker creation took too much time.";
+ }
+
+ private:
+ web::TestWebThreadBundle thread_bundle_;
+};
+
+#pragma mark - Tests.
+
+// Tests -isInSafeMode returns true if there is a SafeModeController.
+TEST_F(AppStateTest, isInSafeModeTest) {
+ // Setup.
+ id safeModeContollerMock =
+ [OCMockObject mockForClass:[SafeModeCoordinator class]];
+
+ AppState* appState = getAppStateWithMock();
+
+ appState.safeModeCoordinator = nil;
+ ASSERT_FALSE([appState isInSafeMode]);
+ [appState setSafeModeCoordinator:safeModeContollerMock];
+
+ // Action.
+ BOOL result = [appState isInSafeMode];
+
+ // Test.
+ EXPECT_TRUE(result);
+}
+
+// Tests that if the application is in background
+// -requiresHandlingAfterLaunchWithOptions saves the launchOptions and returns
+// YES (to handle the launch options later).
+TEST_F(AppStateTest, requiresHandlingAfterLaunchWithOptionsBackground) {
+ // Setup.
+ NSString* sourceApplication = @"com.apple.mobilesafari";
+ NSDictionary* launchOptions =
+ @{UIApplicationLaunchOptionsSourceApplicationKey : sourceApplication};
+
+ AppState* appState = getAppStateWithMock();
+
+ id browserLauncherMock = getBrowserLauncherMock();
+ BrowserInitializationStageType stageBasic = INITIALIZATION_STAGE_BASIC;
+ [[browserLauncherMock expect] startUpBrowserToStage:stageBasic];
+ [[browserLauncherMock expect] setLaunchOptions:launchOptions];
+
+ // Action.
+ BOOL result = [appState requiresHandlingAfterLaunchWithOptions:launchOptions
+ stateBackground:YES];
+
+ // Test.
+ EXPECT_TRUE(result);
+ EXPECT_OCMOCK_VERIFY(browserLauncherMock);
+}
+
+// Tests that if the application is active and Safe Mode should be activated
+// -requiresHandlingAfterLaunchWithOptions save the launch options and activate
+// the Safe Mode.
+TEST_F(AppStateTest, requiresHandlingAfterLaunchWithOptionsForegroundSafeMode) {
+ // Setup.
+ NSString* sourceApplication = @"com.apple.mobilesafari";
+ NSDictionary* launchOptions =
+ @{UIApplicationLaunchOptionsSourceApplicationKey : sourceApplication};
+
+ id windowMock = getWindowMock();
+ [[[windowMock stub] andReturn:nil] rootViewController];
+ [[windowMock expect] setRootViewController:[OCMArg any]];
+ [[windowMock expect] makeKeyAndVisible];
+
+ AppState* appState = getAppStateWithMock();
+
+ id browserLauncherMock = getBrowserLauncherMock();
+ BrowserInitializationStageType stageBasic = INITIALIZATION_STAGE_BASIC;
+ [[browserLauncherMock expect] startUpBrowserToStage:stageBasic];
+ [[browserLauncherMock expect] setLaunchOptions:launchOptions];
+
+ swizzleSafeModeShouldStart(YES);
+
+ ASSERT_FALSE([appState isInSafeMode]);
+
+ // Action.
+ BOOL result = [appState requiresHandlingAfterLaunchWithOptions:launchOptions
+ stateBackground:NO];
+
+ // Test.
+ EXPECT_TRUE(result);
+ EXPECT_TRUE([appState isInSafeMode]);
+ EXPECT_OCMOCK_VERIFY(browserLauncherMock);
+ EXPECT_OCMOCK_VERIFY(windowMock);
+}
+
+// Tests that if the application is active
+// -requiresHandlingAfterLaunchWithOptions saves the launchOptions and start the
+// application in foreground.
+TEST_F(AppStateTest, requiresHandlingAfterLaunchWithOptionsForeground) {
+ // Setup.
+ NSString* sourceApplication = @"com.apple.mobilesafari";
+ NSDictionary* launchOptions =
+ @{UIApplicationLaunchOptionsSourceApplicationKey : sourceApplication};
+
+ [[[getStartupInformationMock() stub] andReturnValue:@YES] isColdStart];
+
+ [[[getWindowMock() stub] andReturn:nil] rootViewController];
+
+ AppState* appState = getAppStateWithMock();
+
+ id browserLauncherMock = getBrowserLauncherMock();
+ BrowserInitializationStageType stageBasic = INITIALIZATION_STAGE_BASIC;
+ [[browserLauncherMock expect] startUpBrowserToStage:stageBasic];
+ BrowserInitializationStageType stageForeground =
+ INITIALIZATION_STAGE_FOREGROUND;
+ [[browserLauncherMock expect] startUpBrowserToStage:stageForeground];
+ [[browserLauncherMock expect] setLaunchOptions:launchOptions];
+
+ swizzleSafeModeShouldStart(NO);
+
+ // Action.
+ BOOL result = [appState requiresHandlingAfterLaunchWithOptions:launchOptions
+ stateBackground:NO];
+
+ // Test.
+ EXPECT_TRUE(result);
+ EXPECT_OCMOCK_VERIFY(browserLauncherMock);
+}
+
+// Test that -willResignActive set cold start to NO and launch record.
+TEST(AppStateNoFixtureTest, willResignActive) {
+ // Setup.
+ id tabModel = [OCMockObject mockForClass:[TabModel class]];
+ [[tabModel expect] recordSessionMetrics];
+
+ id browserViewInformation =
+ [OCMockObject mockForProtocol:@protocol(BrowserViewInformation)];
+
+ [[[browserViewInformation stub] andReturn:tabModel] mainTabModel];
+
+ id browserLauncher =
+ [OCMockObject mockForProtocol:@protocol(BrowserLauncher)];
+ [[[browserLauncher stub] andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
+ browserInitializationStage];
+ [[[browserLauncher stub] andReturn:browserViewInformation]
+ browserViewInformation];
+
+ id applicationDelegate =
+ [OCMockObject mockForClass:[MainApplicationDelegate class]];
+ id window = [OCMockObject mockForClass:[UIWindow class]];
+
+ base::scoped_nsobject<FakeStartupInformation> startupInformation(
+ [[FakeStartupInformation alloc] init]);
+ [startupInformation setIsColdStart:YES];
+
+ base::scoped_nsobject<AppState> appState([[AppState alloc]
+ initWithBrowserLauncher:browserLauncher
+ startupInformation:startupInformation
+ applicationDelegate:applicationDelegate]);
+ [appState setWindow:window];
+
+ ASSERT_TRUE([startupInformation isColdStart]);
+
+ // Action.
+ [appState willResignActiveTabModel];
+
+ // Test.
+ EXPECT_FALSE([startupInformation isColdStart]);
+ EXPECT_OCMOCK_VERIFY(tabModel);
+}
+
+// Test that -applicationWillTerminate clears everything.
+TEST_F(AppStateWithThreadTest, willTerminate) {
+ // Setup.
+ IOSChromeScopedTestingChromeBrowserProvider provider_(
+ base::MakeUnique<FakeChromeBrowserProvider>());
+
+ id browserLauncher =
+ [OCMockObject mockForProtocol:@protocol(BrowserLauncher)];
+ id applicationDelegate =
+ [OCMockObject mockForClass:[MainApplicationDelegate class]];
+ id window = [OCMockObject mockForClass:[UIWindow class]];
+ id browserViewInformation =
+ [OCMockObject mockForProtocol:@protocol(BrowserViewInformation)];
+ [[[browserLauncher stub] andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
+ browserInitializationStage];
+ [[[browserLauncher stub] andReturn:browserViewInformation]
+ browserViewInformation];
+
+ id settingsNavigationController =
+ [OCMockObject mockForClass:[SettingsNavigationController class]];
+
+ id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
+ [[[appNavigation stub] andReturn:settingsNavigationController]
+ settingsNavigationController];
+ [[appNavigation expect] closeSettingsAnimated:NO completion:nil];
+
+ [[browserViewInformation expect] cleanDeviceSharingManager];
+ [[browserViewInformation expect] haltAllTabs];
+
+ id startupInformation =
+ [OCMockObject mockForProtocol:@protocol(StartupInformation)];
+ [[startupInformation expect] stopChromeMain];
+
+ base::scoped_nsobject<AppState> appState([[AppState alloc]
+ initWithBrowserLauncher:browserLauncher
+ startupInformation:startupInformation
+ applicationDelegate:applicationDelegate]);
+ [appState setWindow:window];
+
+ id application = [OCMockObject mockForClass:[UIApplication class]];
+ [[application expect] setMinimumBackgroundFetchInterval:
+ UIApplicationBackgroundFetchIntervalNever];
+
+ // Action.
+ [appState applicationWillTerminate:application
+ applicationNavigation:appNavigation];
+
+ // Test.
+ EXPECT_OCMOCK_VERIFY(startupInformation);
+ EXPECT_OCMOCK_VERIFY(appNavigation);
+ EXPECT_OCMOCK_VERIFY(browserViewInformation);
+ EXPECT_OCMOCK_VERIFY(application);
+ FakeAppDistributionProvider* provider =
+ static_cast<FakeAppDistributionProvider*>(
+ ios::GetChromeBrowserProvider()->GetAppDistributionProvider());
+ EXPECT_TRUE(provider->cancel_called());
+}
+
+// Test that -resumeSessionWithTabOpener removes incognito blocker,
+// restart metrics and launchs from StartupParameters if they exist.
+TEST_F(AppStateTest, resumeSessionWithStartupParameters) {
+ // Setup.
+
+ // BrowserLauncher.
+ id browserViewInformation = getBrowserViewInformationMock();
+ [[[getBrowserLauncherMock() stub]
+ andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
+ browserInitializationStage];
+ [[[getBrowserLauncherMock() stub] andReturn:browserViewInformation]
+ browserViewInformation];
+
+ // StartupInformation.
+ id appStartupParameters =
+ [OCMockObject mockForClass:[AppStartupParameters class]];
+ [[[getStartupInformationMock() stub] andReturn:appStartupParameters]
+ startupParameters];
+ [[[getStartupInformationMock() stub] andReturnValue:@NO] isColdStart];
+
+ // TabOpening.
+ id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
+ // TabSwitcher.
+ id tabSwitcher = [OCMockObject mockForProtocol:@protocol(TabSwitching)];
+
+ // BrowserViewInformation.
+ id mainTabModel = [OCMockObject mockForClass:[TabModel class]];
+ [[mainTabModel expect] resetSessionMetrics];
+ [[[browserViewInformation stub] andReturn:mainTabModel] mainTabModel];
+
+ // Swizzle Startup Parameters.
+ swizzleHandleStartupParameters(tabOpener, browserViewInformation);
+
+ UIWindow* window = [[[UIWindow alloc] init] autorelease];
+ AppState* appState = getAppStateWithOpenNTPAndIncognitoBlock(NO, window);
+
+ ASSERT_EQ(NSUInteger(1), [window subviews].count);
+
+ // Action.
+ [appState resumeSessionWithTabOpener:tabOpener tabSwitcher:tabSwitcher];
+
+ // Test.
+ EXPECT_EQ(NSUInteger(0), [window subviews].count);
+ EXPECT_OCMOCK_VERIFY(mainTabModel);
+}
+
+// Test that -resumeSessionWithTabOpener removes incognito blocker,
+// restart metrics and creates a new tab from tab switcher if shouldOpenNTP is
+// YES.
+TEST_F(AppStateTest, resumeSessionShouldOpenNTPTabSwitcher) {
+ // Setup.
+ // BrowserLauncher.
+ id browserViewInformation = getBrowserViewInformationMock();
+ [[[getBrowserLauncherMock() stub]
+ andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
+ browserInitializationStage];
+ [[[getBrowserLauncherMock() stub] andReturn:browserViewInformation]
+ browserViewInformation];
+
+ // StartupInformation.
+ [[[getStartupInformationMock() stub] andReturn:nil] startupParameters];
+ [[[getStartupInformationMock() stub] andReturnValue:@NO] isColdStart];
+
+ // TabOpening.
+ id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
+
+ // BrowserViewInformation.
+ id mainTabModel = [OCMockObject mockForClass:[TabModel class]];
+ [[mainTabModel expect] resetSessionMetrics];
+ [[[browserViewInformation stub] andReturn:mainTabModel] mainTabModel];
+
+ // TabSwitcher.
+ id tabSwitcher = [OCMockObject mockForProtocol:@protocol(TabSwitching)];
+ [[[tabSwitcher stub] andReturnValue:@YES] openNewTabFromTabSwitcher];
+
+ UIWindow* window = [[[UIWindow alloc] init] autorelease];
+ AppState* appState = getAppStateWithOpenNTPAndIncognitoBlock(YES, window);
+
+ ASSERT_EQ(NSUInteger(1), [window subviews].count);
+
+ // Action.
+ [appState resumeSessionWithTabOpener:tabOpener tabSwitcher:tabSwitcher];
+
+ // Test.
+ EXPECT_EQ(NSUInteger(0), [window subviews].count);
+ EXPECT_OCMOCK_VERIFY(mainTabModel);
+}
+
+// Test that -resumeSessionWithTabOpener removes incognito blocker,
+// restart metrics and creates a new tab if shouldOpenNTP is YES.
+TEST_F(AppStateTest, resumeSessionShouldOpenNTPNoTabSwitcher) {
+ // Setup.
+ // BrowserLauncher.
+ id browserViewInformation = getBrowserViewInformationMock();
+ [[[getBrowserLauncherMock() stub]
+ andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)]
+ browserInitializationStage];
+ [[[getBrowserLauncherMock() stub] andReturn:browserViewInformation]
+ browserViewInformation];
+
+ // StartupInformation.
+ [[[getStartupInformationMock() stub] andReturn:nil] startupParameters];
+ [[[getStartupInformationMock() stub] andReturnValue:@NO] isColdStart];
+
+ // TabOpening.
+ id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
+
+ // BrowserViewInformation.
+ id mainTabModel = [OCMockObject mockForClass:[TabModel class]];
+ [[mainTabModel expect] resetSessionMetrics];
+
+ id currentBVC = [OCMockObject mockForClass:[BrowserViewController class]];
+ [[currentBVC expect] newTab:nil];
+ stubNullBrowserState(currentBVC);
+
+ [[[browserViewInformation stub] andReturn:mainTabModel] mainTabModel];
+ [[[browserViewInformation stub] andReturn:currentBVC] currentBVC];
+
+ // TabSwitcher.
+ id tabSwitcher = [OCMockObject mockForProtocol:@protocol(TabSwitching)];
+ [[[tabSwitcher stub] andReturnValue:@NO] openNewTabFromTabSwitcher];
+
+ UIWindow* window = [[[UIWindow alloc] init] autorelease];
+ AppState* appState = getAppStateWithOpenNTPAndIncognitoBlock(YES, window);
+
+ // incognitoBlocker.
+ ASSERT_EQ(NSUInteger(1), [window subviews].count);
+
+ // Action.
+ [appState resumeSessionWithTabOpener:tabOpener tabSwitcher:tabSwitcher];
+
+ // Test.
+ EXPECT_EQ(NSUInteger(0), [window subviews].count);
+ EXPECT_OCMOCK_VERIFY(mainTabModel);
+ EXPECT_OCMOCK_VERIFY(currentBVC);
+}
+
+// Tests that -applicationWillEnterForeground resets components as needed.
+TEST_F(AppStateTest, applicationWillEnterForeground) {
+ // Setup.
+ IOSChromeScopedTestingChromeBrowserProvider provider_(
+ base::MakeUnique<FakeChromeBrowserProvider>());
+ id application = [OCMockObject mockForClass:[UIApplication class]];
+ id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
+ id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
+ id browserViewInformation = getBrowserViewInformationMock();
+ id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
+ id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
+ id tabModel = [OCMockObject mockForClass:[TabModel class]];
+
+ BrowserInitializationStageType stage = INITIALIZATION_STAGE_FOREGROUND;
+ [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
+ browserInitializationStage];
+ [[[getBrowserLauncherMock() stub] andReturn:browserViewInformation]
+ browserViewInformation];
+ [[[browserViewInformation stub] andReturn:tabModel] currentTabModel];
+ [[metricsMediator expect] updateMetricsStateBasedOnPrefsUserTriggered:NO];
+ [[memoryHelper expect] resetForegroundMemoryWarningCount];
+ [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
+ [[[tabOpener stub] andReturnValue:@YES]
+ shouldOpenNTPTabOnActivationOfTabModel:tabModel];
+
+ stubNullCurrentBrowserState(browserViewInformation);
+
+ void (^swizzleBlock)() = ^() {
+ };
+
+ ScopedBlockSwizzler swizzler(
+ [MetricsMediator class],
+ @selector(logLaunchMetricsWithStartupInformation:browserViewInformation:),
+ swizzleBlock);
+
+ // Actions.
+ [getAppStateWithMock() applicationWillEnterForeground:application
+ metricsMediator:metricsMediator
+ memoryHelper:memoryHelper
+ tabOpener:tabOpener
+ appNavigation:appNavigation];
+
+ // Tests.
+ EXPECT_OCMOCK_VERIFY(metricsMediator);
+ EXPECT_OCMOCK_VERIFY(memoryHelper);
+ FakeUserFeedbackProvider* user_feedback_provider =
+ static_cast<FakeUserFeedbackProvider*>(
+ ios::GetChromeBrowserProvider()->GetUserFeedbackProvider());
+ EXPECT_TRUE(user_feedback_provider->synchronize_called());
+}
+
+// Tests that -applicationWillEnterForeground starts the browser if the
+// application is in background.
+TEST_F(AppStateTest, applicationWillEnterForegroundFromBackground) {
+ // Setup.
+ id application = [OCMockObject mockForClass:[UIApplication class]];
+ id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
+ id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
+ id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
+ id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
+
+ BrowserInitializationStageType stage = INITIALIZATION_STAGE_BACKGROUND;
+ [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
+ browserInitializationStage];
+
+ [[[getWindowMock() stub] andReturn:nil] rootViewController];
+ swizzleSafeModeShouldStart(NO);
+
+ [[[getStartupInformationMock() stub] andReturnValue:@YES] isColdStart];
+ [[getBrowserLauncherMock() expect]
+ startUpBrowserToStage:INITIALIZATION_STAGE_FOREGROUND];
+
+ // Actions.
+ [getAppStateWithMock() applicationWillEnterForeground:application
+ metricsMediator:metricsMediator
+ memoryHelper:memoryHelper
+ tabOpener:tabOpener
+ appNavigation:appNavigation];
+
+ // Tests.
+ EXPECT_OCMOCK_VERIFY(getBrowserLauncherMock());
+}
+
+// Tests that -applicationWillEnterForeground starts the safe mode if the
+// application is in background.
+TEST_F(AppStateTest,
+ applicationWillEnterForegroundFromBackgroundShouldStartSafeMode) {
+ // Setup.
+ id application = [OCMockObject mockForClass:[UIApplication class]];
+ id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
+ id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
+ id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
+ id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
+
+ id window = getWindowMock();
+
+ BrowserInitializationStageType stage = INITIALIZATION_STAGE_BACKGROUND;
+ [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
+ browserInitializationStage];
+
+ [[[window stub] andReturn:nil] rootViewController];
+ [[window expect] makeKeyAndVisible];
+ [[window stub] setRootViewController:[OCMArg any]];
+ swizzleSafeModeShouldStart(YES);
+
+ // Actions.
+ [getAppStateWithMock() applicationWillEnterForeground:application
+ metricsMediator:metricsMediator
+ memoryHelper:memoryHelper
+ tabOpener:tabOpener
+ appNavigation:appNavigation];
+
+ // Tests.
+ EXPECT_OCMOCK_VERIFY(window);
+ EXPECT_TRUE([getAppStateWithMock() isInSafeMode]);
+}
+
+// Tests that -applicationWillEnterForeground returns directly if the
+// application is in safe mode and in foreground
+TEST_F(AppStateTest, applicationWillEnterForegroundFromForegroundSafeMode) {
+ // Setup.
+ id application = [OCMockObject mockForClass:[UIApplication class]];
+ id metricsMediator = [OCMockObject mockForClass:[MetricsMediator class]];
+ id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
+ id tabOpener = [OCMockObject mockForProtocol:@protocol(TabOpening)];
+ id appNavigation = [OCMockObject mockForProtocol:@protocol(AppNavigation)];
+
+ BrowserInitializationStageType stage = INITIALIZATION_STAGE_FOREGROUND;
+ [[[getBrowserLauncherMock() stub] andReturnValue:@(stage)]
+ browserInitializationStage];
+
+ AppState* appState = getAppStateWithMock();
+
+ UIWindow* window = [[[UIWindow alloc] init] autorelease];
+ appState.safeModeCoordinator =
+ [[[SafeModeCoordinator alloc] initWithWindow:window] autorelease];
+
+ ASSERT_TRUE([appState isInSafeMode]);
+
+ // Actions.
+ [appState applicationWillEnterForeground:application
+ metricsMediator:metricsMediator
+ memoryHelper:memoryHelper
+ tabOpener:tabOpener
+ appNavigation:appNavigation];
+}
+
+// Tests that -applicationDidEnterBackground creates an incognito blocker.
+TEST_F(AppStateTest, applicationDidEnterBackgroundIncognito) {
+ // Setup.
+ UIWindow* window = [[[UIWindow alloc] init] autorelease];
+ id application = [OCMockObject niceMockForClass:[UIApplication class]];
+ id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
+ id browserViewInformation = getBrowserViewInformationMock();
+ id tabModel = [OCMockObject mockForClass:[TabModel class]];
+ id startupInformation = getStartupInformationMock();
+ id browserLauncher = getBrowserLauncherMock();
+ BrowserInitializationStageType stage = INITIALIZATION_STAGE_FOREGROUND;
+
+ AppState* appState = getAppStateWithRealWindow(window);
+
+ [[startupInformation expect] expireFirstUserActionRecorder];
+ [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
+ [[[tabModel stub] andReturnValue:@NO] isEmpty];
+ [[[browserViewInformation stub] andReturn:tabModel] otrTabModel];
+ [[[browserViewInformation stub] andReturn:nil] currentBVC];
+ stubNullCurrentBrowserState(browserViewInformation);
+ [[[browserLauncher stub] andReturnValue:@(stage)] browserInitializationStage];
+ [[[browserLauncher stub] andReturn:browserViewInformation]
+ browserViewInformation];
+
+ swizzleMetricsMediatorDisableReporting();
+
+ ASSERT_EQ(NSUInteger(0), [window subviews].count);
+
+ // Action.
+ [appState applicationDidEnterBackground:application
+ memoryHelper:memoryHelper
+ tabSwitcherIsActive:YES];
+
+ // Tests.
+ EXPECT_OCMOCK_VERIFY(startupInformation);
+ EXPECT_TRUE(metricsMediatorHasBeenCalled());
+ EXPECT_EQ(NSUInteger(1), [window subviews].count);
+}
+
+// Tests that -applicationDidEnterBackground do nothing if the application has
+// never been in a Foreground stage.
+TEST_F(AppStateTest, applicationDidEnterBackgroundStageBackground) {
+ // Setup.
+ UIWindow* window = [[[UIWindow alloc] init] autorelease];
+ id application = [OCMockObject mockForClass:[UIApplication class]];
+ id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
+ id browserLauncher = getBrowserLauncherMock();
+ BrowserInitializationStageType stage = INITIALIZATION_STAGE_BACKGROUND;
+
+ [[[browserLauncher stub] andReturnValue:@(stage)] browserInitializationStage];
+
+ ASSERT_EQ(NSUInteger(0), [window subviews].count);
+
+ // Action.
+ [getAppStateWithRealWindow(window) applicationDidEnterBackground:application
+ memoryHelper:memoryHelper
+ tabSwitcherIsActive:YES];
+
+ // Tests.
+ EXPECT_EQ(NSUInteger(0), [window subviews].count);
+}
+
+// Tests that -applicationDidEnterBackground does not create an incognito
+// blocker if there is no incognito tab.
+TEST_F(AppStateTest, applicationDidEnterBackgroundNoIncognitoBlocker) {
+ // Setup.
+ UIWindow* window = [[[UIWindow alloc] init] autorelease];
+ id application = [OCMockObject niceMockForClass:[UIApplication class]];
+ id memoryHelper = [OCMockObject mockForClass:[MemoryWarningHelper class]];
+ id browserViewInformation = getBrowserViewInformationMock();
+ id tabModel = [OCMockObject mockForClass:[TabModel class]];
+ id startupInformation = getStartupInformationMock();
+ id browserLauncher = getBrowserLauncherMock();
+ BrowserInitializationStageType stage = INITIALIZATION_STAGE_FOREGROUND;
+
+ AppState* appState = getAppStateWithRealWindow(window);
+
+ [[startupInformation expect] expireFirstUserActionRecorder];
+ [[[memoryHelper stub] andReturnValue:@0] foregroundMemoryWarningCount];
+ [[[tabModel stub] andReturnValue:@YES] isEmpty];
+ [[[browserViewInformation stub] andReturn:tabModel] otrTabModel];
+ [[[browserViewInformation stub] andReturn:nil] currentBVC];
+ stubNullCurrentBrowserState(browserViewInformation);
+ [[[browserLauncher stub] andReturnValue:@(stage)] browserInitializationStage];
+ [[[browserLauncher stub] andReturn:browserViewInformation]
+ browserViewInformation];
+
+ swizzleMetricsMediatorDisableReporting();
+
+ ASSERT_EQ(NSUInteger(0), [window subviews].count);
+
+ // Action.
+ [appState applicationDidEnterBackground:application
+ memoryHelper:memoryHelper
+ tabSwitcherIsActive:YES];
+
+ // Tests.
+ EXPECT_OCMOCK_VERIFY(startupInformation);
+ EXPECT_TRUE(metricsMediatorHasBeenCalled());
+ EXPECT_EQ(NSUInteger(0), [window subviews].count);
+}
« 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