1 // Copyright 2020 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 #include "chrome/browser/chromeos/login/screens/terms_of_service_screen.h"
6
7 #include "ash/public/cpp/login_screen_test_api.h"
8 #include "base/bind.h"
9 #include "base/run_loop.h"
10 #include "chrome/browser/chromeos/login/existing_user_controller.h"
11 #include "chrome/browser/chromeos/login/screen_manager.h"
12 #include "chrome/browser/chromeos/login/test/device_state_mixin.h"
13 #include "chrome/browser/chromeos/login/test/embedded_test_server_mixin.h"
14 #include "chrome/browser/chromeos/login/test/js_checker.h"
15 #include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h"
16 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
17 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
18 #include "chrome/browser/chromeos/login/test/session_manager_state_waiter.h"
19 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
20 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
21 #include "chrome/browser/chromeos/login/wizard_controller.h"
22 #include "chrome/browser/chromeos/policy/device_local_account.h"
23 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
24 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
25 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
26 #include "chrome/browser/ui/browser.h"
27 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
28 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
29 #include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h"
30 #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
31 #include "components/policy/proto/chrome_device_policy.pb.h"
32 #include "content/public/test/browser_test.h"
33 #include "net/test/embedded_test_server/http_request.h"
34 #include "net/test/embedded_test_server/http_response.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36
37 namespace em = enterprise_management;
38
39 using net::test_server::BasicHttpResponse;
40 using net::test_server::HttpRequest;
41 using net::test_server::HttpResponse;
42
43 using testing::_;
44 using testing::InvokeWithoutArgs;
45
46 namespace chromeos {
47 namespace {
48
49 const char kAccountId[] = "dla@example.com";
50 const char kDisplayName[] = "display name";
51
52 } // namespace
53
54 class TermsOfServiceScreenTest : public OobeBaseTest {
55 public:
TermsOfServiceScreenTest()56 TermsOfServiceScreenTest() {}
57 ~TermsOfServiceScreenTest() override = default;
58
RegisterAdditionalRequestHandlers()59 void RegisterAdditionalRequestHandlers() override {
60 embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
61 &TermsOfServiceScreenTest::HandleRequest, base::Unretained(this)));
62 }
63
SetUpInProcessBrowserTestFixture()64 void SetUpInProcessBrowserTestFixture() override {
65 OobeBaseTest::SetUpInProcessBrowserTestFixture();
66 chromeos::SessionManagerClient::InitializeFakeInMemory();
67 InitializePolicy();
68 }
69
InitializePolicy()70 void InitializePolicy() {
71 device_policy()->policy_data().set_public_key_version(1);
72 policy::DeviceLocalAccountTestHelper::SetupDeviceLocalAccount(
73 &device_local_account_policy_, kAccountId, kDisplayName);
74 UploadDeviceLocalAccountPolicy();
75 }
76
BuildDeviceLocalAccountPolicy()77 void BuildDeviceLocalAccountPolicy() {
78 device_local_account_policy_.SetDefaultSigningKey();
79 device_local_account_policy_.Build();
80 }
81
UploadDeviceLocalAccountPolicy()82 void UploadDeviceLocalAccountPolicy() {
83 BuildDeviceLocalAccountPolicy();
84 ASSERT_TRUE(local_policy_mixin_.server()->UpdatePolicy(
85 policy::dm_protocol::kChromePublicAccountPolicyType, kAccountId,
86 device_local_account_policy_.payload().SerializeAsString()));
87 }
88
UploadAndInstallDeviceLocalAccountPolicy()89 void UploadAndInstallDeviceLocalAccountPolicy() {
90 UploadDeviceLocalAccountPolicy();
91 session_manager_client()->set_device_local_account_policy(
92 kAccountId, device_local_account_policy_.GetBlob());
93 }
94
AddPublicSessionToDevicePolicy()95 void AddPublicSessionToDevicePolicy() {
96 em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
97 policy::DeviceLocalAccountTestHelper::AddPublicSession(&proto, kAccountId);
98 RefreshDevicePolicy();
99 ASSERT_TRUE(local_policy_mixin_.UpdateDevicePolicy(proto));
100 }
101
WaitForDisplayName()102 void WaitForDisplayName() {
103 policy::DictionaryLocalStateValueWaiter("UserDisplayName", kDisplayName,
104 account_id_.GetUserEmail())
105 .Wait();
106 }
107
WaitForPolicy()108 void WaitForPolicy() {
109 // Wait for the display name becoming available as that indicates
110 // device-local account policy is fully loaded, which is a prerequisite for
111 // successful login.
112 WaitForDisplayName();
113 }
114
StartLogin()115 void StartLogin() {
116 ASSERT_TRUE(ash::LoginScreenTestApi::ExpandPublicSessionPod(account_id_));
117 ash::LoginScreenTestApi::ClickPublicExpandedSubmitButton();
118 }
119
StartPublicSession()120 void StartPublicSession() {
121 UploadAndInstallDeviceLocalAccountPolicy();
122 AddPublicSessionToDevicePolicy();
123 WaitForPolicy();
124 StartLogin();
125 }
126
SetUpTermsOfServiceUrlPolicy()127 void SetUpTermsOfServiceUrlPolicy() {
128 device_local_account_policy_.payload()
129 .mutable_termsofserviceurl()
130 ->set_value(TestServerBaseUrl());
131 }
132
SetUpExitCallback()133 void SetUpExitCallback() {
134 TermsOfServiceScreen* screen = static_cast<TermsOfServiceScreen*>(
135 WizardController::default_controller()->screen_manager()->GetScreen(
136 TermsOfServiceScreenView::kScreenId));
137 original_callback_ = screen->get_exit_callback_for_testing();
138 screen->set_exit_callback_for_testing(base::BindRepeating(
139 &TermsOfServiceScreenTest::HandleScreenExit, base::Unretained(this)));
140 }
141
WaitFosScreenShown()142 void WaitFosScreenShown() {
143 OobeScreenWaiter(TermsOfServiceScreenView::kScreenId).Wait();
144 EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
145 }
146
WaitForScreenExit()147 void WaitForScreenExit() {
148 if (screen_exited_)
149 return;
150 base::RunLoop run_loop;
151 screen_exit_callback_ = run_loop.QuitClosure();
152 run_loop.Run();
153 }
154
TestServerBaseUrl()155 std::string TestServerBaseUrl() {
156 return base::TrimString(
157 embedded_test_server()->base_url().GetOrigin().spec(), "/",
158 base::TrimPositions::TRIM_TRAILING)
159 .as_string();
160 }
161
HandleRequest(const HttpRequest & request)162 std::unique_ptr<HttpResponse> HandleRequest(const HttpRequest& request) {
163 std::string text = "By using this test you are agree to fix future bugs";
164 return BuildHttpResponse(text);
165 }
166
167 // Returns a successful `BasicHttpResponse` with `content`.
BuildHttpResponse(const std::string & content)168 std::unique_ptr<BasicHttpResponse> BuildHttpResponse(
169 const std::string& content) {
170 std::unique_ptr<BasicHttpResponse> http_response =
171 std::make_unique<BasicHttpResponse>();
172 http_response->set_code(net::HTTP_OK);
173 http_response->set_content_type("text/plain");
174 http_response->set_content(content);
175 return http_response;
176 }
177
session_manager_client()178 chromeos::FakeSessionManagerClient* session_manager_client() {
179 return chromeos::FakeSessionManagerClient::Get();
180 }
181
182 base::Optional<TermsOfServiceScreen::Result> result_;
183 base::HistogramTester histogram_tester_;
184
185 private:
RefreshDevicePolicy()186 void RefreshDevicePolicy() { policy_helper()->RefreshDevicePolicy(); }
187
device_policy()188 policy::DevicePolicyBuilder* device_policy() {
189 return policy_helper()->device_policy();
190 }
191
policy_helper()192 policy::DevicePolicyCrosTestHelper* policy_helper() {
193 return &policy_helper_;
194 }
195
HandleScreenExit(TermsOfServiceScreen::Result result)196 void HandleScreenExit(TermsOfServiceScreen::Result result) {
197 screen_exited_ = true;
198 result_ = result;
199 original_callback_.Run(result);
200 if (screen_exit_callback_)
201 screen_exit_callback_.Run();
202 }
203
204 bool screen_exited_ = false;
205 base::RepeatingClosure screen_exit_callback_;
206 TermsOfServiceScreen::ScreenExitCallback original_callback_;
207 policy::UserPolicyBuilder device_local_account_policy_;
208
209 const AccountId account_id_ =
210 AccountId::FromUserEmail(GenerateDeviceLocalAccountUserId(
211 kAccountId,
212 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION));
213 policy::DevicePolicyCrosTestHelper policy_helper_;
214 chromeos::LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_};
215 chromeos::DeviceStateMixin device_state_{
216 &mixin_host_,
217 chromeos::DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
218 };
219
IN_PROC_BROWSER_TEST_F(TermsOfServiceScreenTest,Skipped)220 IN_PROC_BROWSER_TEST_F(TermsOfServiceScreenTest, Skipped) {
221 StartPublicSession();
222
223 chromeos::test::WaitForPrimaryUserSessionStart();
224
225 histogram_tester_.ExpectTotalCount(
226 "OOBE.StepCompletionTimeByExitReason.Terms-of-service.Accepted", 0);
227 histogram_tester_.ExpectTotalCount(
228 "OOBE.StepCompletionTimeByExitReason.Terms-of-service.Declined", 0);
229 histogram_tester_.ExpectTotalCount("OOBE.StepCompletionTime.Tos", 0);
230 }
231
IN_PROC_BROWSER_TEST_F(TermsOfServiceScreenTest,Accepted)232 IN_PROC_BROWSER_TEST_F(TermsOfServiceScreenTest, Accepted) {
233 SetUpTermsOfServiceUrlPolicy();
234 StartPublicSession();
235
236 WaitFosScreenShown();
237 SetUpExitCallback();
238
239 test::OobeJS().TapOnPath({"terms-of-service", "acceptButton"});
240
241 WaitForScreenExit();
242 EXPECT_EQ(result_.value(), TermsOfServiceScreen::Result::ACCEPTED);
243 histogram_tester_.ExpectTotalCount(
244 "OOBE.StepCompletionTimeByExitReason.Terms-of-service.Accepted", 1);
245 histogram_tester_.ExpectTotalCount(
246 "OOBE.StepCompletionTimeByExitReason.Terms-of-service.Declined", 0);
247 histogram_tester_.ExpectTotalCount("OOBE.StepCompletionTime.Tos", 1);
248
249 chromeos::test::WaitForPrimaryUserSessionStart();
250 }
251
IN_PROC_BROWSER_TEST_F(TermsOfServiceScreenTest,Declined)252 IN_PROC_BROWSER_TEST_F(TermsOfServiceScreenTest, Declined) {
253 SetUpTermsOfServiceUrlPolicy();
254 StartPublicSession();
255
256 WaitFosScreenShown();
257 SetUpExitCallback();
258
259 test::OobeJS().TapOnPath({"terms-of-service", "backButton"});
260 WaitForScreenExit();
261 EXPECT_EQ(result_.value(), TermsOfServiceScreen::Result::DECLINED);
262 histogram_tester_.ExpectTotalCount(
263 "OOBE.StepCompletionTimeByExitReason.Terms-of-service.Accepted", 0);
264 histogram_tester_.ExpectTotalCount(
265 "OOBE.StepCompletionTimeByExitReason.Terms-of-service.Declined", 1);
266 histogram_tester_.ExpectTotalCount("OOBE.StepCompletionTime.Tos", 1);
267
268 EXPECT_TRUE(session_manager_client()->session_stopped());
269 EXPECT_TRUE(ash::LoginScreenTestApi::IsPublicSessionExpanded());
270 }
271
272 } // namespace chromeos
273