blob: 890ba80b62049f5119744430f91321cc68284370 [file] [log] [blame]
// 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