| // Copyright 2020 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. |
| |
| #include <vector> |
| |
| #include "base/command_line.h" |
| #include "base/stl_util.h" |
| #include "base/values.h" |
| #include "chrome/browser/policy/policy_test_utils.h" |
| #include "chrome/browser/prefs/session_startup_pref.h" |
| #include "chrome/browser/resource_coordinator/tab_load_tracker_test_support.h" |
| #include "chrome/browser/search/search.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_tabstrip.h" |
| #include "chrome/browser/ui/search/local_ntp_test_utils.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/webui_url_constants.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/policy/core/common/policy_map.h" |
| #include "components/policy/core/common/policy_types.h" |
| #include "components/policy/policy_constants.h" |
| #include "components/prefs/pref_service.h" |
| #include "content/public/browser/notification_types.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/test/browser_test.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| namespace policy { |
| |
| namespace { |
| |
| constexpr const char* kRestoredURLs[] = { |
| "http://aaa.com/empty.html", |
| "http://bbb.com/empty.html", |
| }; |
| |
| bool IsNonSwitchArgument(const base::CommandLine::StringType& s) { |
| return s.empty() || s[0] != '-'; |
| } |
| |
| } // namespace |
| |
| // Similar to PolicyTest but allows setting policies before the browser is |
| // created. Each test parameter is a method that sets up the early policies |
| // and stores the expected startup URLs in |expected_urls_|. |
| class RestoreOnStartupPolicyTest : public PolicyTest, |
| public testing::WithParamInterface<void ( |
| RestoreOnStartupPolicyTest::*)(void)> { |
| public: |
| RestoreOnStartupPolicyTest() = default; |
| ~RestoreOnStartupPolicyTest() override = default; |
| |
| #if defined(OS_CHROMEOS) |
| void SetUpCommandLine(base::CommandLine* command_line) override { |
| // TODO(nkostylev): Investigate if we can remove this switch. |
| command_line->AppendSwitch(switches::kCreateBrowserOnStartupForTests); |
| PolicyTest::SetUpCommandLine(command_line); |
| } |
| #endif |
| |
| void SetUpInProcessBrowserTestFixture() override { |
| PolicyTest::SetUpInProcessBrowserTestFixture(); |
| // Set early policies now, before the browser is created. |
| (this->*(GetParam()))(); |
| |
| // Remove the non-switch arguments, so that session restore kicks in for |
| // these tests. |
| base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| base::CommandLine::StringVector argv = command_line->argv(); |
| base::EraseIf(argv, IsNonSwitchArgument); |
| command_line->InitFromArgv(argv); |
| ASSERT_TRUE( |
| std::equal(argv.begin(), argv.end(), command_line->argv().begin())); |
| } |
| |
| void ListOfURLs() { |
| // Verifies that policy can set the startup pages to a list of URLs. |
| base::ListValue urls; |
| for (const auto* url : kRestoredURLs) { |
| urls.AppendString(url); |
| expected_urls_.push_back(GURL(url)); |
| } |
| PolicyMap policies; |
| policies.Set(key::kRestoreOnStartup, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, |
| base::Value(SessionStartupPref::kPrefValueURLs), nullptr); |
| policies.Set(key::kRestoreOnStartupURLs, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, urls.Clone(), nullptr); |
| provider_.UpdateChromePolicy(policies); |
| } |
| |
| void NTP() { |
| // Verifies that policy can set the startup page to the NTP. |
| PolicyMap policies; |
| policies.Set(key::kRestoreOnStartup, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, |
| base::Value(SessionStartupPref::kPrefValueNewTab), nullptr); |
| provider_.UpdateChromePolicy(policies); |
| expected_urls_.push_back(GURL(chrome::kChromeUINewTabURL)); |
| } |
| |
| void Last() { |
| // Verifies that policy can set the startup pages to the last session. |
| PolicyMap policies; |
| policies.Set(key::kRestoreOnStartup, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, |
| base::Value(SessionStartupPref::kPrefValueLast), nullptr); |
| provider_.UpdateChromePolicy(policies); |
| // This should restore the tabs opened at PRE_RunTest below. |
| for (const auto* url : kRestoredURLs) |
| expected_urls_.push_back(GURL(url)); |
| } |
| |
| void Blocked() { |
| // Verifies that URLs are blocked during session restore. |
| PolicyMap policies; |
| policies.Set(key::kRestoreOnStartup, POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, |
| base::Value(SessionStartupPref::kPrefValueLast), nullptr); |
| base::Value urls(base::Value::Type::LIST); |
| for (const auto* url_string : kRestoredURLs) |
| urls.Append(url_string); |
| policies.Set(key::kURLBlocklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, |
| POLICY_SOURCE_CLOUD, std::move(urls), nullptr); |
| provider_.UpdateChromePolicy(policies); |
| // This should restore the tabs opened at PRE_RunTest below, yet all should |
| // be blocked. |
| blocked_ = true; |
| for (const auto* url_string : kRestoredURLs) |
| expected_urls_.emplace_back(url_string); |
| } |
| |
| // URLs that are expected to be loaded. |
| std::vector<GURL> expected_urls_; |
| |
| // True if the loaded URLs should be blocked by policy. |
| bool blocked_ = false; |
| }; |
| |
| IN_PROC_BROWSER_TEST_P(RestoreOnStartupPolicyTest, PRE_RunTest) { |
| // Do not show Welcome Page. |
| browser()->profile()->GetPrefs()->SetBoolean(prefs::kHasSeenWelcomePage, |
| true); |
| |
| // Open some tabs to verify if they are restored after the browser restarts. |
| // Most policy settings override this, except kPrefValueLast which enforces |
| // a restore. |
| ui_test_utils::NavigateToURL(browser(), GURL(kRestoredURLs[0])); |
| for (size_t i = 1; i < base::size(kRestoredURLs); ++i) { |
| content::WindowedNotificationObserver observer( |
| content::NOTIFICATION_LOAD_STOP, |
| content::NotificationService::AllSources()); |
| chrome::AddSelectedTabWithURL(browser(), GURL(kRestoredURLs[i]), |
| ui::PAGE_TRANSITION_LINK); |
| observer.Wait(); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_P(RestoreOnStartupPolicyTest, RunTest) { |
| TabStripModel* model = browser()->tab_strip_model(); |
| int size = static_cast<int>(expected_urls_.size()); |
| EXPECT_EQ(size, model->count()); |
| resource_coordinator::WaitForTransitionToLoaded(model); |
| for (int i = 0; i < size && i < model->count(); ++i) { |
| content::WebContents* web_contents = model->GetWebContentsAt(i); |
| if (blocked_) { |
| CheckURLIsBlockedInWebContents(web_contents, expected_urls_[i]); |
| } else if (expected_urls_[i] == GURL(chrome::kChromeUINewTabURL)) { |
| EXPECT_EQ(local_ntp_test_utils::GetFinalNtpUrl(browser()->profile()), |
| web_contents->GetURL()); |
| } else { |
| EXPECT_EQ(expected_urls_[i], web_contents->GetURL()); |
| } |
| } |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| RestoreOnStartupPolicyTestInstance, |
| RestoreOnStartupPolicyTest, |
| testing::Values(&RestoreOnStartupPolicyTest::ListOfURLs, |
| &RestoreOnStartupPolicyTest::NTP, |
| &RestoreOnStartupPolicyTest::Last, |
| &RestoreOnStartupPolicyTest::Blocked)); |
| } // namespace policy |