Chromium Code Reviews| Index: chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc |
| diff --git a/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc b/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc |
| index d414baff7dbfef3050d5de96029f6a0b5a877166..562216c8b283564e3a5b0fa46c7a03300f564fdb 100644 |
| --- a/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc |
| +++ b/chrome/browser/chromeos/lock_screen_apps/state_controller_unittest.cc |
| @@ -12,22 +12,67 @@ |
| #include "ash/public/interfaces/tray_action.mojom.h" |
| #include "base/files/file_path.h" |
| #include "base/memory/ptr_util.h" |
| -#include "base/run_loop.h" |
| #include "base/test/scoped_command_line.h" |
| #include "chrome/browser/chromeos/lock_screen_apps/app_manager.h" |
| #include "chrome/browser/chromeos/lock_screen_apps/state_observer.h" |
| +#include "chrome/browser/extensions/extension_service.h" |
| +#include "chrome/browser/extensions/test_extension_system.h" |
| +#include "chrome/browser/ui/apps/chrome_app_delegate.h" |
| #include "chrome/common/chrome_constants.h" |
| +#include "chrome/test/base/browser_with_test_window_test.h" |
| #include "chrome/test/base/testing_browser_process.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "chrome/test/base/testing_profile_manager.h" |
| #include "components/session_manager/core/session_manager.h" |
| -#include "content/public/test/test_browser_thread_bundle.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "content/public/browser/web_contents_observer.h" |
| +#include "content/public/test/test_utils.h" |
| +#include "content/public/test/web_contents_tester.h" |
| +#include "extensions/browser/app_window/app_window.h" |
| +#include "extensions/browser/app_window/app_window_contents.h" |
| +#include "extensions/browser/app_window/native_app_window.h" |
| +#include "extensions/common/api/app_runtime.h" |
| +#include "extensions/common/extension_builder.h" |
| +#include "extensions/common/value_builder.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| using ash::mojom::TrayActionState; |
| namespace { |
| +// App IDs used for test apps. |
| +const char kTestAppId[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; |
| +const char kSecondaryTestAppId[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; |
| + |
| +scoped_refptr<extensions::Extension> CreateTestNoteTakingApp( |
| + const std::string& app_id) { |
| + return extensions::ExtensionBuilder() |
| + .SetManifest( |
| + extensions::DictionaryBuilder() |
| + .Set("name", "Test App") |
| + .Set("version", "1.0") |
| + .Set("manifest_version", 2) |
| + .Set("app", |
| + extensions::DictionaryBuilder() |
| + .Set("background", |
| + extensions::DictionaryBuilder() |
| + .Set("scripts", extensions::ListBuilder() |
| + .Append("background.js") |
| + .Build()) |
| + .Build()) |
| + .Build()) |
| + .Set("action_handlers", |
| + extensions::ListBuilder() |
| + .Append(extensions::DictionaryBuilder() |
| + .Set("action", "new_note") |
| + .SetBoolean("enabled_on_lock_screen", true) |
| + .Build()) |
| + .Build()) |
| + .Build()) |
| + .SetID(app_id) |
| + .Build(); |
| +} |
| + |
| class TestAppManager : public lock_screen_apps::AppManager { |
| public: |
| enum class State { |
| @@ -183,6 +228,70 @@ class TestTrayAction : public ash::mojom::TrayAction { |
| DISALLOW_COPY_AND_ASSIGN(TestTrayAction); |
| }; |
| +class TestAppWindow : public content::WebContentsObserver { |
| + public: |
| + TestAppWindow(Profile* profile, const extensions::Extension* extension) |
| + : web_contents_( |
| + content::WebContentsTester::CreateTestWebContents(profile, |
| + nullptr)), |
| + window_(new extensions::AppWindow(profile, |
| + new ChromeAppDelegate(true), |
| + extension)) {} |
| + |
| + ~TestAppWindow() override { |
| + // Make sure the window is initialized, so |window_| does not get leaked. |
| + if (!initialized_) |
| + Initialize(false /* shown */); |
| + |
| + Close(); |
| + } |
| + |
| + void Initialize(bool shown) { |
| + ASSERT_FALSE(initialized_); |
| + initialized_ = true; |
| + |
| + extensions::AppWindow::CreateParams params; |
| + params.hidden = !shown; |
| + window_->Init(GURL(std::string()), |
| + new extensions::AppWindowContentsImpl(window_), |
| + web_contents_->GetMainFrame(), params); |
| + Observe(window_->web_contents()); |
| + } |
| + |
| + void Close() { |
| + if (!window_) |
| + return; |
| + |
| + if (!initialized_) |
| + return; |
| + |
| + content::WebContentsDestroyedWatcher destroyed_watcher( |
| + window_->web_contents()); |
| + window_->GetBaseWindow()->Close(); |
| + destroyed_watcher.Wait(); |
| + |
| + EXPECT_FALSE(window_); |
| + EXPECT_TRUE(closed_); |
| + } |
| + |
| + void WebContentsDestroyed() override { |
| + closed_ = true; |
| + window_ = nullptr; |
| + } |
| + |
| + extensions::AppWindow* window() { return window_; } |
| + |
| + bool closed() const { return closed_; } |
| + |
| + private: |
| + std::unique_ptr<content::WebContents> web_contents_; |
| + extensions::AppWindow* window_; |
| + bool closed_ = false; |
| + bool initialized_ = false; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TestAppWindow); |
| +}; |
| + |
| class LockScreenAppStateNotSupportedTest : public testing::Test { |
| public: |
| LockScreenAppStateNotSupportedTest() = default; |
| @@ -200,7 +309,7 @@ class LockScreenAppStateNotSupportedTest : public testing::Test { |
| DISALLOW_COPY_AND_ASSIGN(LockScreenAppStateNotSupportedTest); |
| }; |
| -class LockScreenAppStateTest : public testing::Test { |
| +class LockScreenAppStateTest : public BrowserWithTestWindowTest { |
| public: |
| LockScreenAppStateTest() |
| : profile_manager_(TestingBrowserProcess::GetGlobal()) {} |
| @@ -213,6 +322,8 @@ class LockScreenAppStateTest : public testing::Test { |
| ASSERT_TRUE(profile_manager_.SetUp()); |
| + BrowserWithTestWindowTest::SetUp(); |
| + |
| session_manager_ = base::MakeUnique<session_manager::SessionManager>(); |
| session_manager_->SetSessionState( |
| session_manager::SessionState::LOGIN_PRIMARY); |
| @@ -231,43 +342,121 @@ class LockScreenAppStateTest : public testing::Test { |
| TestingProfile::Builder builder; |
| builder.SetPath( |
| profile_manager_.profiles_dir().AppendASCII(chrome::kInitialProfile)); |
| - TestingProfile* signin_profile = builder.BuildIncognito( |
| + signin_profile_ = builder.BuildIncognito( |
| profile_manager_.CreateTestingProfile(chrome::kInitialProfile)); |
| + InitExtensionSystem(profile()); |
| + InitExtensionSystem(signin_profile()); |
| + |
| std::unique_ptr<TestAppManager> app_manager = |
| base::MakeUnique<TestAppManager>(&profile_, |
| - signin_profile->GetOriginalProfile()); |
| + signin_profile_->GetOriginalProfile()); |
| app_manager_ = app_manager.get(); |
| state_controller_->SetAppManagerForTesting(std::move(app_manager)); |
| } |
| void TearDown() override { |
| + extensions::ExtensionSystem::Get(profile())->Shutdown(); |
| + extensions::ExtensionSystem::Get(signin_profile())->Shutdown(); |
| + |
| state_controller_->RemoveObserver(&observer_); |
| state_controller_.reset(); |
| session_manager_.reset(); |
| app_manager_ = nullptr; |
| + BrowserWithTestWindowTest::TearDown(); |
| + } |
| + |
| + void InitExtensionSystem(Profile* profile) { |
| + extensions::TestExtensionSystem* extension_system = |
| + static_cast<extensions::TestExtensionSystem*>( |
| + extensions::ExtensionSystem::Get(profile)); |
| + extension_system->CreateExtensionService( |
| + base::CommandLine::ForCurrentProcess(), |
| + base::FilePath() /* install_directory */, |
| + false /* autoupdate_enabled */); |
| + } |
| + |
| + void ExpectObservedStatesMatch(const std::vector<TrayActionState>& states, |
| + const std::string& message) { |
| + state_controller_->FlushTrayActionForTesting(); |
| + EXPECT_EQ(states, observer()->observed_states()) << message; |
| + EXPECT_EQ(states, tray_action()->observed_states()) << message; |
| + } |
| + |
| + void ClearObservedStates() { |
| + state_controller_->FlushTrayActionForTesting(); |
| + observer_.ClearObservedStates(); |
| + tray_action_.ClearObservedStates(); |
| } |
| - // Helper method to move state controller to available state. |
| + // Helper method to move state controller to the specified state. |
| // Should be called at the begining of tests, at most once. |
| - bool EnableNoteTakingApp(bool enable_app_launch) { |
| - app_manager_->SetInitialAppState("test_app_id", enable_app_launch); |
| + bool InitializeNoteTakingApp(TrayActionState target_state, |
| + bool enable_app_launch) { |
| + app_ = CreateTestNoteTakingApp(kTestAppId); |
| + extensions::ExtensionSystem::Get(signin_profile()) |
| + ->extension_service() |
| + ->AddExtension(app_.get()); |
| + |
| + app_manager_->SetInitialAppState(kTestAppId, enable_app_launch); |
| state_controller_->SetPrimaryProfile(&profile_); |
| + |
| + if (target_state == TrayActionState::kNotAvailable) |
| + return true; |
| + |
| session_manager_->SetSessionState(session_manager::SessionState::LOCKED); |
| if (app_manager_->state() != TestAppManager::State::kStarted) { |
| ADD_FAILURE() << "Lock app manager Start not invoked."; |
| return false; |
| } |
| + |
| + ClearObservedStates(); |
| + |
| + if (state_controller_->GetLockScreenNoteState() != |
| + TrayActionState::kAvailable) { |
| + ADD_FAILURE() << "Unable to move to available state."; |
| + return false; |
| + } |
| + if (target_state == TrayActionState::kAvailable) |
| + return true; |
| + |
| + tray_action()->SendNewNoteRequest(); |
| state_controller_->FlushTrayActionForTesting(); |
| - observer_.ClearObservedStates(); |
| - tray_action_.ClearObservedStates(); |
| + ClearObservedStates(); |
| + |
| + if (state_controller_->GetLockScreenNoteState() != |
| + TrayActionState::kLaunching) { |
| + ADD_FAILURE() << "Unable to move to launching state."; |
| + return false; |
| + } |
| + if (target_state == TrayActionState::kLaunching) |
| + return true; |
| + |
| + app_window_ = base::MakeUnique<TestAppWindow>(signin_profile(), app()); |
| + if (!state_controller_->CanCreateAppWindowForAction( |
|
benwells
2017/06/13 10:30:46
This call feels a bit redundant,as RegisterAppWind
tbarzic
2017/06/13 19:17:59
Done.
|
| + signin_profile(), app(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)) { |
| + ADD_FAILURE() << "Not allowed to create app window."; |
| + return false; |
| + } |
| + if (!state_controller_->RegisterAppWindowForAction( |
| + app_window()->window(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)) { |
| + ADD_FAILURE() << "Failed to register app window."; |
| + return false; |
| + } |
| + |
| + app_window()->Initialize(true /* shown */); |
| - return state_controller_->GetLockScreenNoteState() == |
| - TrayActionState::kAvailable; |
| + ClearObservedStates(); |
| + |
| + return state_controller()->GetLockScreenNoteState() == |
| + TrayActionState::kActive; |
| } |
| TestingProfile* profile() { return &profile_; } |
| + TestingProfile* signin_profile() { return signin_profile_; } |
| session_manager::SessionManager* session_manager() { |
| return session_manager_.get(); |
| @@ -283,11 +472,14 @@ class LockScreenAppStateTest : public testing::Test { |
| TestAppManager* app_manager() { return app_manager_; } |
| + TestAppWindow* app_window() { return app_window_.get(); } |
| + const extensions::Extension* app() { return app_.get(); } |
| + |
| private: |
| std::unique_ptr<base::test::ScopedCommandLine> command_line_; |
| - content::TestBrowserThreadBundle threads_; |
| TestingProfileManager profile_manager_; |
| TestingProfile profile_; |
| + TestingProfile* signin_profile_ = nullptr; |
| std::unique_ptr<session_manager::SessionManager> session_manager_; |
| @@ -297,6 +489,9 @@ class LockScreenAppStateTest : public testing::Test { |
| TestTrayAction tray_action_; |
| TestAppManager* app_manager_ = nullptr; |
| + std::unique_ptr<TestAppWindow> app_window_; |
| + scoped_refptr<const extensions::Extension> app_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(LockScreenAppStateTest); |
| }; |
| @@ -337,7 +532,7 @@ TEST_F(LockScreenAppStateTest, SetPrimaryProfileWhenSessionLocked) { |
| EXPECT_EQ(TestAppManager::State::kNotInitialized, app_manager()->state()); |
| - app_manager()->SetInitialAppState("app_id", true); |
| + app_manager()->SetInitialAppState(kTestAppId, true); |
| state_controller()->SetPrimaryProfile(profile()); |
| ASSERT_EQ(TestAppManager::State::kStarted, app_manager()->state()); |
| @@ -345,15 +540,11 @@ TEST_F(LockScreenAppStateTest, SetPrimaryProfileWhenSessionLocked) { |
| EXPECT_EQ(TrayActionState::kAvailable, |
| state_controller()->GetLockScreenNoteState()); |
| - state_controller()->FlushTrayActionForTesting(); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, observer()->observed_states()[0]); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, tray_action()->observed_states()[0]); |
| + ExpectObservedStatesMatch({TrayActionState::kAvailable}, "Available on lock"); |
| } |
| TEST_F(LockScreenAppStateTest, SessionLock) { |
| - app_manager()->SetInitialAppState("app_id", true); |
| + app_manager()->SetInitialAppState(kTestAppId, true); |
| state_controller()->SetPrimaryProfile(profile()); |
| ASSERT_EQ(TestAppManager::State::kStopped, app_manager()->state()); |
| @@ -363,13 +554,9 @@ TEST_F(LockScreenAppStateTest, SessionLock) { |
| EXPECT_EQ(TrayActionState::kAvailable, |
| state_controller()->GetLockScreenNoteState()); |
| - state_controller()->FlushTrayActionForTesting(); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, observer()->observed_states()[0]); |
| - observer()->ClearObservedStates(); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, tray_action()->observed_states()[0]); |
| - tray_action()->ClearObservedStates(); |
| + |
| + ExpectObservedStatesMatch({TrayActionState::kAvailable}, "Available on lock"); |
| + ClearObservedStates(); |
| // When the session is unlocked again, app manager is stopped, and tray action |
| // disabled again. |
| @@ -379,26 +566,16 @@ TEST_F(LockScreenAppStateTest, SessionLock) { |
| EXPECT_EQ(TrayActionState::kNotAvailable, |
| state_controller()->GetLockScreenNoteState()); |
| - state_controller()->FlushTrayActionForTesting(); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kNotAvailable, observer()->observed_states()[0]); |
| - observer()->ClearObservedStates(); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kNotAvailable, |
| - tray_action()->observed_states()[0]); |
| - tray_action()->ClearObservedStates(); |
| + |
| + ExpectObservedStatesMatch({TrayActionState::kNotAvailable}, |
| + "Not available on unlock"); |
| + ClearObservedStates(); |
| // Test that subsequent session lock works as expected. |
| session_manager()->SetSessionState(session_manager::SessionState::LOCKED); |
| ASSERT_EQ(TestAppManager::State::kStarted, app_manager()->state()); |
| - |
| - EXPECT_EQ(TrayActionState::kAvailable, |
| - state_controller()->GetLockScreenNoteState()); |
| - state_controller()->FlushTrayActionForTesting(); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, observer()->observed_states()[0]); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, tray_action()->observed_states()[0]); |
| + ExpectObservedStatesMatch({TrayActionState::kAvailable}, |
| + "Available on second lock"); |
| } |
| TEST_F(LockScreenAppStateTest, SessionUnlockedWhileStartingAppManager) { |
| @@ -422,15 +599,11 @@ TEST_F(LockScreenAppStateTest, SessionUnlockedWhileStartingAppManager) { |
| session_manager()->SetSessionState(session_manager::SessionState::LOCKED); |
| ASSERT_EQ(TestAppManager::State::kStarted, app_manager()->state()); |
| - app_manager()->UpdateApp("app_id", true); |
| + app_manager()->UpdateApp(kTestAppId, true); |
| EXPECT_EQ(TrayActionState::kAvailable, |
| state_controller()->GetLockScreenNoteState()); |
| - state_controller()->FlushTrayActionForTesting(); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, observer()->observed_states()[0]); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, tray_action()->observed_states()[0]); |
| + ExpectObservedStatesMatch({TrayActionState::kAvailable}, "Available on lock"); |
| } |
| TEST_F(LockScreenAppStateTest, AppManagerNoApp) { |
| @@ -458,69 +631,48 @@ TEST_F(LockScreenAppStateTest, AppManagerNoApp) { |
| // App manager should be started on next session lock. |
| session_manager()->SetSessionState(session_manager::SessionState::ACTIVE); |
| ASSERT_EQ(TestAppManager::State::kStopped, app_manager()->state()); |
| - app_manager()->SetInitialAppState("app_id", false); |
| + app_manager()->SetInitialAppState(kTestAppId, false); |
| session_manager()->SetSessionState(session_manager::SessionState::LOCKED); |
| EXPECT_EQ(TrayActionState::kAvailable, |
| state_controller()->GetLockScreenNoteState()); |
| - state_controller()->FlushTrayActionForTesting(); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, observer()->observed_states()[0]); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, tray_action()->observed_states()[0]); |
| + ExpectObservedStatesMatch({TrayActionState::kAvailable}, "Available on lock"); |
| } |
| TEST_F(LockScreenAppStateTest, AppAvailabilityChanges) { |
| state_controller()->SetPrimaryProfile(profile()); |
| ASSERT_EQ(TestAppManager::State::kStopped, app_manager()->state()); |
| - app_manager()->SetInitialAppState("app_id", false); |
| + app_manager()->SetInitialAppState(kTestAppId, false); |
| session_manager()->SetSessionState(session_manager::SessionState::LOCKED); |
| EXPECT_EQ(TestAppManager::State::kStarted, app_manager()->state()); |
| EXPECT_EQ(TrayActionState::kAvailable, |
| state_controller()->GetLockScreenNoteState()); |
| - state_controller()->FlushTrayActionForTesting(); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, observer()->observed_states()[0]); |
| - observer()->ClearObservedStates(); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, tray_action()->observed_states()[0]); |
| - tray_action()->ClearObservedStates(); |
| + ExpectObservedStatesMatch({TrayActionState::kAvailable}, "Available on lock"); |
| + ClearObservedStates(); |
| app_manager()->UpdateApp("", false); |
| EXPECT_EQ(TrayActionState::kNotAvailable, |
| state_controller()->GetLockScreenNoteState()); |
| - state_controller()->FlushTrayActionForTesting(); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kNotAvailable, observer()->observed_states()[0]); |
| - observer()->ClearObservedStates(); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kNotAvailable, |
| - tray_action()->observed_states()[0]); |
| - tray_action()->ClearObservedStates(); |
| + ExpectObservedStatesMatch({TrayActionState::kNotAvailable}, |
| + "Not available on app cleared"); |
| + ClearObservedStates(); |
| - app_manager()->UpdateApp("app_id_1", true); |
| + app_manager()->UpdateApp(kSecondaryTestAppId, true); |
| EXPECT_EQ(TrayActionState::kAvailable, |
| state_controller()->GetLockScreenNoteState()); |
| - state_controller()->FlushTrayActionForTesting(); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, observer()->observed_states()[0]); |
| - observer()->ClearObservedStates(); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kAvailable, tray_action()->observed_states()[0]); |
| - tray_action()->ClearObservedStates(); |
| + ExpectObservedStatesMatch({TrayActionState::kAvailable}, |
| + "Available on other app set"); |
| } |
| -TEST_F(LockScreenAppStateTest, MoveToBackgroundFromActive) { |
| - ASSERT_TRUE(EnableNoteTakingApp(true /* enable_app_launch */)); |
| - |
| - state_controller()->SetLockScreenNoteStateForTesting( |
| - TrayActionState::kActive); |
| +TEST_F(LockScreenAppStateTest, MoveToBackgroundAndForeground) { |
| + ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kActive, |
| + true /* enable_app_launch */)); |
| state_controller()->MoveToBackground(); |
| state_controller()->FlushTrayActionForTesting(); |
| @@ -528,17 +680,12 @@ TEST_F(LockScreenAppStateTest, MoveToBackgroundFromActive) { |
| EXPECT_EQ(TrayActionState::kBackground, |
| state_controller()->GetLockScreenNoteState()); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kBackground, observer()->observed_states()[0]); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kBackground, tray_action()->observed_states()[0]); |
| -} |
| - |
| -TEST_F(LockScreenAppStateTest, MoveToForeground) { |
| - ASSERT_TRUE(EnableNoteTakingApp(true /* enable_app_launch */)); |
| + ExpectObservedStatesMatch({TrayActionState::kBackground}, |
| + "Move to background"); |
| + ClearObservedStates(); |
| - state_controller()->SetLockScreenNoteStateForTesting( |
| - TrayActionState::kBackground); |
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_FALSE(app_window()->closed()); |
| state_controller()->MoveToForeground(); |
| state_controller()->FlushTrayActionForTesting(); |
| @@ -546,14 +693,15 @@ TEST_F(LockScreenAppStateTest, MoveToForeground) { |
| EXPECT_EQ(TrayActionState::kActive, |
| state_controller()->GetLockScreenNoteState()); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kActive, observer()->observed_states()[0]); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kActive, tray_action()->observed_states()[0]); |
| + ExpectObservedStatesMatch({TrayActionState::kActive}, "Move to foreground"); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_FALSE(app_window()->closed()); |
| } |
| TEST_F(LockScreenAppStateTest, MoveToForegroundFromNonBackgroundState) { |
| - ASSERT_TRUE(EnableNoteTakingApp(true /* enable_app_launch */)); |
| + ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kAvailable, |
| + true /* enable_app_launch */)); |
| state_controller()->MoveToForeground(); |
| state_controller()->FlushTrayActionForTesting(); |
| @@ -577,20 +725,15 @@ TEST_F(LockScreenAppStateTest, HandleActionWhenNotAvaiable) { |
| } |
| TEST_F(LockScreenAppStateTest, HandleAction) { |
| - ASSERT_TRUE(EnableNoteTakingApp(true /* enable_app_launch */)); |
| + ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kAvailable, |
| + true /* enable_app_launch */)); |
| tray_action()->SendNewNoteRequest(); |
| state_controller()->FlushTrayActionForTesting(); |
| - EXPECT_EQ(TrayActionState::kLaunching, |
| - state_controller()->GetLockScreenNoteState()); |
| - ASSERT_EQ(1u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kLaunching, observer()->observed_states()[0]); |
| - observer()->ClearObservedStates(); |
| - ASSERT_EQ(1u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kLaunching, tray_action()->observed_states()[0]); |
| - tray_action()->ClearObservedStates(); |
| - |
| + ExpectObservedStatesMatch({TrayActionState::kLaunching}, |
| + "Launch on new note request"); |
| + ClearObservedStates(); |
| EXPECT_EQ(1, app_manager()->launch_count()); |
| tray_action()->SendNewNoteRequest(); |
| @@ -604,21 +747,18 @@ TEST_F(LockScreenAppStateTest, HandleAction) { |
| } |
| TEST_F(LockScreenAppStateTest, HandleActionWithLaunchFailure) { |
| - ASSERT_TRUE(EnableNoteTakingApp(false /* enable_app_launch */)); |
| + ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kAvailable, |
| + false /* enable_app_launch */)); |
| tray_action()->SendNewNoteRequest(); |
| state_controller()->FlushTrayActionForTesting(); |
| EXPECT_EQ(TrayActionState::kAvailable, |
| state_controller()->GetLockScreenNoteState()); |
| - ASSERT_EQ(2u, observer()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kLaunching, observer()->observed_states()[0]); |
| - EXPECT_EQ(TrayActionState::kAvailable, observer()->observed_states()[1]); |
| - observer()->ClearObservedStates(); |
| - ASSERT_EQ(2u, tray_action()->observed_states().size()); |
| - EXPECT_EQ(TrayActionState::kLaunching, tray_action()->observed_states()[0]); |
| - EXPECT_EQ(TrayActionState::kAvailable, tray_action()->observed_states()[1]); |
| - tray_action()->ClearObservedStates(); |
| + ExpectObservedStatesMatch( |
| + {TrayActionState::kLaunching, TrayActionState::kAvailable}, |
| + "Failed launch on new note request"); |
| + ClearObservedStates(); |
| EXPECT_EQ(1, app_manager()->launch_count()); |
| @@ -628,9 +768,184 @@ TEST_F(LockScreenAppStateTest, HandleActionWithLaunchFailure) { |
| EXPECT_EQ(TrayActionState::kAvailable, |
| state_controller()->GetLockScreenNoteState()); |
| - // There should be no state change - the state_controller was already in |
| - // launching state when the request was received. |
| - EXPECT_EQ(2u, observer()->observed_states().size()); |
| - EXPECT_EQ(2u, tray_action()->observed_states().size()); |
| + ExpectObservedStatesMatch( |
| + {TrayActionState::kLaunching, TrayActionState::kAvailable}, |
| + "Second failed launch on new note request"); |
| EXPECT_EQ(2, app_manager()->launch_count()); |
| } |
| + |
| +TEST_F(LockScreenAppStateTest, AppWindowRegistration) { |
| + ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kAvailable, |
| + true /* enable_app_launch */)); |
| + |
| + EXPECT_FALSE(state_controller()->CanCreateAppWindowForAction( |
| + signin_profile(), app(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + |
| + TestAppWindow app_window(signin_profile(), app()); |
| + EXPECT_FALSE(state_controller()->RegisterAppWindowForAction( |
| + app_window.window(), extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + |
| + tray_action()->SendNewNoteRequest(); |
| + state_controller()->FlushTrayActionForTesting(); |
| + |
| + EXPECT_EQ(TrayActionState::kLaunching, |
| + state_controller()->GetLockScreenNoteState()); |
| + observer()->ClearObservedStates(); |
| + tray_action()->ClearObservedStates(); |
| + |
| + TestAppWindow non_eligible_app_window(profile(), app()); |
| + EXPECT_FALSE(state_controller()->CanCreateAppWindowForAction( |
| + profile(), app(), extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + EXPECT_FALSE(state_controller()->RegisterAppWindowForAction( |
| + non_eligible_app_window.window(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + |
| + EXPECT_FALSE(state_controller()->CanCreateAppWindowForAction( |
| + signin_profile(), app(), extensions::api::app_runtime::ACTION_TYPE_NONE)); |
| + EXPECT_FALSE(state_controller()->RegisterAppWindowForAction( |
| + app_window.window(), extensions::api::app_runtime::ACTION_TYPE_NONE)); |
| + |
| + EXPECT_TRUE(state_controller()->CanCreateAppWindowForAction( |
| + signin_profile(), app(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + // Repeated query should return true, until the app window is actually |
| + // registered as the action handler. |
| + EXPECT_TRUE(state_controller()->CanCreateAppWindowForAction( |
| + signin_profile(), app(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + |
| + EXPECT_TRUE(state_controller()->RegisterAppWindowForAction( |
| + app_window.window(), extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + app_window.Initialize(true /* shown */); |
| + EXPECT_EQ(TrayActionState::kActive, |
| + state_controller()->GetLockScreenNoteState()); |
| + |
| + // Test that second app window cannot be registered. |
| + TestAppWindow second_app_window(signin_profile(), app()); |
| + EXPECT_FALSE(state_controller()->CanCreateAppWindowForAction( |
| + signin_profile(), app(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + EXPECT_FALSE(state_controller()->RegisterAppWindowForAction( |
| + second_app_window.window(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + |
| + EXPECT_FALSE(state_controller()->CanCreateAppWindowForAction( |
| + signin_profile(), app(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + EXPECT_FALSE(state_controller()->RegisterAppWindowForAction( |
| + second_app_window.window(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + |
| + // Test the app window does not get closed by itself. |
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_FALSE(app_window.closed()); |
| + |
| + EXPECT_EQ(TrayActionState::kActive, |
| + state_controller()->GetLockScreenNoteState()); |
| + |
| + // Closing the second app window, will not change the state. |
| + second_app_window.Close(); |
| + EXPECT_EQ(TrayActionState::kActive, |
| + state_controller()->GetLockScreenNoteState()); |
| + |
| + app_window.Close(); |
| + EXPECT_EQ(TrayActionState::kAvailable, |
| + state_controller()->GetLockScreenNoteState()); |
| +} |
| + |
| +TEST_F(LockScreenAppStateTest, AppWindowClosedBeforeBeingShown) { |
| + ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kLaunching, |
| + true /* enable_app_launch */)); |
| + |
| + TestAppWindow app_window(signin_profile(), app()); |
| + ASSERT_TRUE(state_controller()->RegisterAppWindowForAction( |
| + app_window.window(), extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + app_window.Initialize(false /* shown */); |
| + |
| + app_window.Close(); |
| + EXPECT_EQ(TrayActionState::kAvailable, |
| + state_controller()->GetLockScreenNoteState()); |
| +} |
| + |
| +TEST_F(LockScreenAppStateTest, AppWindowClosedOnSessionUnlock) { |
| + ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kActive, |
| + true /* enable_app_launch */)); |
| + |
| + session_manager()->SetSessionState(session_manager::SessionState::ACTIVE); |
| + EXPECT_EQ(TrayActionState::kNotAvailable, |
| + state_controller()->GetLockScreenNoteState()); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_TRUE(app_window()->closed()); |
| +} |
| + |
| +TEST_F(LockScreenAppStateTest, AppWindowClosedOnAppUnload) { |
| + ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kActive, |
| + true /* enable_app_launch */)); |
| + |
| + extensions::ExtensionSystem::Get(signin_profile()) |
| + ->extension_service() |
| + ->UnloadExtension(app()->id(), |
| + extensions::UnloadedExtensionReason::UNINSTALL); |
| + app_manager()->UpdateApp("", false); |
| + |
| + EXPECT_EQ(TrayActionState::kNotAvailable, |
| + state_controller()->GetLockScreenNoteState()); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_TRUE(app_window()->closed()); |
| +} |
| + |
| +TEST_F(LockScreenAppStateTest, AppWindowClosedOnNoteTakingAppChange) { |
| + ASSERT_TRUE(InitializeNoteTakingApp(TrayActionState::kActive, |
| + true /* enable_app_launch */)); |
| + |
| + scoped_refptr<extensions::Extension> secondary_app = |
| + CreateTestNoteTakingApp(kSecondaryTestAppId); |
| + extensions::ExtensionSystem::Get(signin_profile()) |
| + ->extension_service() |
| + ->AddExtension(secondary_app.get()); |
| + |
| + app_manager()->UpdateApp(secondary_app->id(), true); |
| + |
| + EXPECT_EQ(TrayActionState::kAvailable, |
| + state_controller()->GetLockScreenNoteState()); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_TRUE(app_window()->closed()); |
| + |
| + tray_action()->SendNewNoteRequest(); |
| + state_controller()->FlushTrayActionForTesting(); |
| + |
| + TestAppWindow app_window(signin_profile(), app()); |
| + EXPECT_FALSE(state_controller()->CanCreateAppWindowForAction( |
| + signin_profile(), app(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + EXPECT_FALSE(state_controller()->RegisterAppWindowForAction( |
| + app_window.window(), extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + ASSERT_EQ(TrayActionState::kLaunching, |
| + state_controller()->GetLockScreenNoteState()); |
| + |
| + TestAppWindow secondary_app_window(signin_profile(), secondary_app.get()); |
| + EXPECT_TRUE(state_controller()->CanCreateAppWindowForAction( |
| + signin_profile(), secondary_app.get(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + EXPECT_TRUE(state_controller()->RegisterAppWindowForAction( |
| + secondary_app_window.window(), |
| + extensions::api::app_runtime::ACTION_TYPE_NEW_NOTE)); |
| + secondary_app_window.Initialize(true /* shown*/); |
| + EXPECT_EQ(TrayActionState::kActive, |
| + state_controller()->GetLockScreenNoteState()); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_FALSE(secondary_app_window.closed()); |
| + |
| + // Uninstall the app and test the secondary app window is closed. |
| + extensions::ExtensionSystem::Get(signin_profile()) |
| + ->extension_service() |
| + ->UnloadExtension(secondary_app->id(), |
| + extensions::UnloadedExtensionReason::UNINSTALL); |
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_TRUE(secondary_app_window.closed()); |
| +} |