1 // Copyright (c) 2013 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.
8 #include "base/basictypes.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/command_line.h"
13 #include "base/file_util.h"
14 #include "base/files/file_path.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/json/json_reader.h"
17 #include "base/json/json_writer.h"
18 #include "base/location.h"
19 #include "base/memory/ref_counted.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "base/message_loop/message_loop.h"
22 #include "base/message_loop/message_loop_proxy.h"
23 #include "base/path_service.h"
24 #include "base/prefs/pref_service.h"
25 #include "base/run_loop.h"
26 #include "base/sequenced_task_runner.h"
27 #include "base/strings/string_number_conversions.h"
28 #include "base/strings/string_util.h"
29 #include "base/strings/stringprintf.h"
30 #include "base/strings/utf_string_conversions.h"
31 #include "base/test/scoped_path_override.h"
32 #include "base/values.h"
33 #include "chrome/browser/browser_process.h"
34 #include "chrome/browser/chrome_notification_types.h"
35 #include "chrome/browser/chromeos/login/existing_user_controller.h"
36 #include "chrome/browser/chromeos/login/login_display_host.h"
37 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
38 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h"
39 #include "chrome/browser/chromeos/login/screens/wizard_screen.h"
40 #include "chrome/browser/chromeos/login/user.h"
41 #include "chrome/browser/chromeos/login/user_image_manager.h"
42 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
43 #include "chrome/browser/chromeos/login/user_image_manager_test_util.h"
44 #include "chrome/browser/chromeos/login/user_manager.h"
45 #include "chrome/browser/chromeos/login/user_manager_impl.h"
46 #include "chrome/browser/chromeos/login/webui_login_view.h"
47 #include "chrome/browser/chromeos/login/wizard_controller.h"
48 #include "chrome/browser/chromeos/policy/cloud_external_data_manager_base_test_util.h"
49 #include "chrome/browser/chromeos/policy/device_local_account.h"
50 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
51 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
52 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
53 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
54 #include "chrome/browser/extensions/extension_service.h"
55 #include "chrome/browser/extensions/extension_system.h"
56 #include "chrome/browser/lifetime/application_lifetime.h"
57 #include "chrome/browser/policy/browser_policy_connector.h"
58 #include "chrome/browser/policy/profile_policy_connector.h"
59 #include "chrome/browser/policy/profile_policy_connector_factory.h"
60 #include "chrome/browser/policy/test/local_policy_test_server.h"
61 #include "chrome/browser/prefs/session_startup_pref.h"
62 #include "chrome/browser/profiles/profile.h"
63 #include "chrome/browser/profiles/profile_manager.h"
64 #include "chrome/browser/ui/browser.h"
65 #include "chrome/browser/ui/browser_commands.h"
66 #include "chrome/browser/ui/browser_finder.h"
67 #include "chrome/browser/ui/browser_list.h"
68 #include "chrome/browser/ui/browser_window.h"
69 #include "chrome/browser/ui/host_desktop.h"
70 #include "chrome/browser/ui/tabs/tab_strip_model.h"
71 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
72 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
73 #include "chrome/common/chrome_paths.h"
74 #include "chrome/common/chrome_switches.h"
75 #include "chromeos/chromeos_paths.h"
76 #include "chromeos/chromeos_switches.h"
77 #include "chromeos/dbus/fake_session_manager_client.h"
78 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
79 #include "components/policy/core/common/cloud/cloud_policy_core.h"
80 #include "components/policy/core/common/cloud/cloud_policy_store.h"
81 #include "components/policy/core/common/cloud/policy_builder.h"
82 #include "components/policy/core/common/external_data_fetcher.h"
83 #include "components/policy/core/common/policy_map.h"
84 #include "components/policy/core/common/policy_namespace.h"
85 #include "components/policy/core/common/policy_service.h"
86 #include "content/public/browser/notification_details.h"
87 #include "content/public/browser/notification_source.h"
88 #include "content/public/browser/web_contents.h"
89 #include "content/public/browser/web_ui.h"
90 #include "content/public/test/browser_test_utils.h"
91 #include "content/public/test/test_utils.h"
92 #include "crypto/rsa_private_key.h"
93 #include "extensions/common/extension.h"
94 #include "grit/chromium_strings.h"
95 #include "grit/generated_resources.h"
96 #include "net/base/url_util.h"
97 #include "net/http/http_status_code.h"
98 #include "net/test/embedded_test_server/embedded_test_server.h"
99 #include "net/test/embedded_test_server/http_request.h"
100 #include "net/test/embedded_test_server/http_response.h"
101 #include "net/url_request/test_url_fetcher_factory.h"
102 #include "net/url_request/url_fetcher_delegate.h"
103 #include "net/url_request/url_request_status.h"
104 #include "policy/policy_constants.h"
105 #include "testing/gmock/include/gmock/gmock.h"
106 #include "ui/base/l10n/l10n_util.h"
107 #include "ui/gfx/image/image_skia.h"
108 #include "url/gurl.h"
109 //#include "third_party/cros_system_api/dbus/service_constants.h"
111 namespace em
= enterprise_management
;
113 using chromeos::LoginScreenContext
;
114 using testing::InvokeWithoutArgs
;
115 using testing::Return
;
122 const char kDomain
[] = "example.com";
123 const char kAccountId1
[] = "dla1@example.com";
124 const char kAccountId2
[] = "dla2@example.com";
125 const char kDisplayName
[] = "display name";
126 const char* kStartupURLs
[] = {
130 const char kExistentTermsOfServicePath
[] = "chromeos/enterprise/tos.txt";
131 const char kNonexistentTermsOfServicePath
[] = "chromeos/enterprise/tos404.txt";
132 const char kRelativeUpdateURL
[] = "/service/update2/crx";
133 const char kUpdateManifestHeader
[] =
134 "<?xml version='1.0' encoding='UTF-8'?>\n"
135 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>\n";
136 const char kUpdateManifestTemplate
[] =
137 " <app appid='%s'>\n"
138 " <updatecheck codebase='%s' version='%s' />\n"
140 const char kUpdateManifestFooter
[] =
142 const char kHostedAppID
[] = "kbmnembihfiondgfjekmnmcbddelicoi";
143 const char kHostedAppCRXPath
[] = "extensions/hosted_app.crx";
144 const char kHostedAppVersion
[] = "1.0.0.0";
145 const char kGoodExtensionID
[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
146 const char kGoodExtensionCRXPath
[] = "extensions/good.crx";
147 const char kGoodExtensionVersion
[] = "1.0";
149 const char kExternalData
[] = "External data";
150 const char kExternalDataURL
[] = "http://localhost/external_data";
152 // Helper that serves extension update manifests to Chrome.
153 class TestingUpdateManifestProvider
{
156 // Update manifests will be served at |relative_update_url|.
157 explicit TestingUpdateManifestProvider(
158 const std::string
& relative_update_url
);
159 ~TestingUpdateManifestProvider();
161 // When an update manifest is requested for the given extension |id|, indicate
162 // that |version| of the extension can be downloaded at |crx_url|.
163 void AddUpdate(const std::string
& id
,
164 const std::string
& version
,
165 const GURL
& crx_url
);
167 // This method must be registered with the test's EmbeddedTestServer to start
168 // serving update manifests.
169 scoped_ptr
<net::test_server::HttpResponse
> HandleRequest(
170 const net::test_server::HttpRequest
& request
);
175 Update(const std::string
& version
, const GURL
& crx_url
);
181 typedef std::map
<std::string
, Update
> UpdateMap
;
184 const std::string relative_update_url_
;
186 DISALLOW_COPY_AND_ASSIGN(TestingUpdateManifestProvider
);
189 TestingUpdateManifestProvider::Update::Update(const std::string
& version
,
195 TestingUpdateManifestProvider::Update::Update() {
198 TestingUpdateManifestProvider::TestingUpdateManifestProvider(
199 const std::string
& relative_update_url
)
200 : relative_update_url_(relative_update_url
) {
203 TestingUpdateManifestProvider::~TestingUpdateManifestProvider() {
206 void TestingUpdateManifestProvider::AddUpdate(const std::string
& id
,
207 const std::string
& version
,
208 const GURL
& crx_url
) {
209 updates_
[id
] = Update(version
, crx_url
);
212 scoped_ptr
<net::test_server::HttpResponse
>
213 TestingUpdateManifestProvider::HandleRequest(
214 const net::test_server::HttpRequest
& request
) {
215 const GURL
url("http://localhost" + request
.relative_url
);
216 if (url
.path() != relative_update_url_
)
217 return scoped_ptr
<net::test_server::HttpResponse
>();
219 std::string content
= kUpdateManifestHeader
;
220 for (net::QueryIterator
it(url
); !it
.IsAtEnd(); it
.Advance()) {
221 if (it
.GetKey() != "x")
223 // Extract the extension id from the subquery. Since GetValueForKeyInQuery()
224 // expects a complete URL, dummy scheme and host must be prepended.
226 net::GetValueForKeyInQuery(GURL("http://dummy?" + it
.GetUnescapedValue()),
228 UpdateMap::const_iterator entry
= updates_
.find(id
);
229 if (entry
!= updates_
.end()) {
230 content
+= base::StringPrintf(kUpdateManifestTemplate
,
232 entry
->second
.crx_url
.spec().c_str(),
233 entry
->second
.version
.c_str());
236 content
+= kUpdateManifestFooter
;
237 scoped_ptr
<net::test_server::BasicHttpResponse
>
238 http_response(new net::test_server::BasicHttpResponse
);
239 http_response
->set_code(net::HTTP_OK
);
240 http_response
->set_content(content
);
241 http_response
->set_content_type("text/xml");
242 return http_response
.PassAs
<net::test_server::HttpResponse
>();
245 bool DoesInstallSuccessReferToId(const std::string
& id
,
246 const content::NotificationSource
& source
,
247 const content::NotificationDetails
& details
) {
248 return content::Details
<const extensions::InstalledExtensionInfo
>(details
)->
249 extension
->id() == id
;
252 bool DoesInstallFailureReferToId(const std::string
& id
,
253 const content::NotificationSource
& source
,
254 const content::NotificationDetails
& details
) {
255 return content::Details
<const base::string16
>(details
)->
256 find(base::UTF8ToUTF16(id
)) != base::string16::npos
;
259 scoped_ptr
<net::FakeURLFetcher
> RunCallbackAndReturnFakeURLFetcher(
260 scoped_refptr
<base::SequencedTaskRunner
> task_runner
,
261 const base::Closure
& callback
,
263 net::URLFetcherDelegate
* delegate
,
264 const std::string
& response_data
,
265 net::HttpStatusCode response_code
,
266 net::URLRequestStatus::Status status
) {
267 task_runner
->PostTask(FROM_HERE
, callback
);
268 return make_scoped_ptr(new net::FakeURLFetcher(
269 url
, delegate
, response_data
, response_code
, status
));
274 class DeviceLocalAccountTest
: public DevicePolicyCrosBrowserTest
,
275 public chromeos::UserManager::Observer
{
277 DeviceLocalAccountTest()
278 : user_id_1_(GenerateDeviceLocalAccountUserId(
279 kAccountId1
, DeviceLocalAccount::TYPE_PUBLIC_SESSION
)),
280 user_id_2_(GenerateDeviceLocalAccountUserId(
281 kAccountId2
, DeviceLocalAccount::TYPE_PUBLIC_SESSION
)) {}
283 virtual ~DeviceLocalAccountTest() {}
285 virtual void SetUp() OVERRIDE
{
286 // Configure and start the test server.
287 scoped_ptr
<crypto::RSAPrivateKey
> signing_key(
288 PolicyBuilder::CreateTestSigningKey());
289 ASSERT_TRUE(test_server_
.SetSigningKey(signing_key
.get()));
291 test_server_
.RegisterClient(PolicyBuilder::kFakeToken
,
292 PolicyBuilder::kFakeDeviceId
);
293 ASSERT_TRUE(test_server_
.Start());
295 ASSERT_TRUE(extension_cache_root_dir_
.CreateUniqueTempDir());
296 extension_cache_root_dir_override_
.reset(new base::ScopedPathOverride(
297 chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS
,
298 extension_cache_root_dir_
.path()));
299 ASSERT_TRUE(external_data_cache_dir_
.CreateUniqueTempDir());
300 external_data_cache_dir_override_
.reset(new base::ScopedPathOverride(
301 chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTERNAL_DATA
,
302 external_data_cache_dir_
.path()));
303 DevicePolicyCrosBrowserTest::SetUp();
306 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
307 DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line
);
308 command_line
->AppendSwitch(chromeos::switches::kLoginManager
);
309 command_line
->AppendSwitch(chromeos::switches::kForceLoginManagerInTests
);
310 command_line
->AppendSwitchASCII(chromeos::switches::kLoginProfile
, "user");
311 command_line
->AppendSwitchASCII(
312 switches::kDeviceManagementUrl
, test_server_
.GetServiceURL().spec());
315 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE
{
316 DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture();
318 // Clear command-line arguments (but keep command-line switches) so the
319 // startup pages policy takes effect.
320 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
321 CommandLine::StringVector
argv(command_line
->argv());
322 argv
.erase(argv
.begin() + argv
.size() - command_line
->GetArgs().size(),
324 command_line
->InitFromArgv(argv
);
327 MarkAsEnterpriseOwned();
332 virtual void CleanUpOnMainThread() OVERRIDE
{
333 // This shuts down the login UI.
334 base::MessageLoop::current()->PostTask(FROM_HERE
,
335 base::Bind(&chrome::AttemptExit
));
336 base::RunLoop().RunUntilIdle();
339 virtual void LocalStateChanged(chromeos::UserManager
* user_manager
) OVERRIDE
{
343 void InitializePolicy() {
344 device_policy()->policy_data().set_public_key_version(1);
345 em::ChromeDeviceSettingsProto
& proto(device_policy()->payload());
346 proto
.mutable_show_user_names()->set_show_user_names(true);
348 device_local_account_policy_
.policy_data().set_policy_type(
349 dm_protocol::kChromePublicAccountPolicyType
);
350 device_local_account_policy_
.policy_data().set_username(kAccountId1
);
351 device_local_account_policy_
.policy_data().set_settings_entity_id(
353 device_local_account_policy_
.policy_data().set_public_key_version(1);
354 device_local_account_policy_
.payload().mutable_userdisplayname()->set_value(
358 void BuildDeviceLocalAccountPolicy() {
359 device_local_account_policy_
.SetDefaultSigningKey();
360 device_local_account_policy_
.Build();
363 void UploadDeviceLocalAccountPolicy() {
364 BuildDeviceLocalAccountPolicy();
365 test_server_
.UpdatePolicy(
366 dm_protocol::kChromePublicAccountPolicyType
, kAccountId1
,
367 device_local_account_policy_
.payload().SerializeAsString());
370 void UploadAndInstallDeviceLocalAccountPolicy() {
371 UploadDeviceLocalAccountPolicy();
372 session_manager_client()->set_device_local_account_policy(
373 kAccountId1
, device_local_account_policy_
.GetBlob());
376 void AddPublicSessionToDevicePolicy(const std::string
& username
) {
377 em::ChromeDeviceSettingsProto
& proto(device_policy()->payload());
378 em::DeviceLocalAccountInfoProto
* account
=
379 proto
.mutable_device_local_accounts()->add_account();
380 account
->set_account_id(username
);
382 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION
);
383 RefreshDevicePolicy();
384 test_server_
.UpdatePolicy(dm_protocol::kChromeDevicePolicyType
,
385 std::string(), proto
.SerializeAsString());
388 void CheckPublicSessionPresent(const std::string
& id
) {
389 const chromeos::User
* user
= chromeos::UserManager::Get()->FindUser(id
);
391 EXPECT_EQ(id
, user
->email());
392 EXPECT_EQ(chromeos::User::USER_TYPE_PUBLIC_ACCOUNT
, user
->GetType());
395 base::FilePath
GetCacheDirectoryForAccountID(const std::string
& account_id
) {
396 return extension_cache_root_dir_
.path()
397 .Append(base::HexEncode(account_id
.c_str(), account_id
.size()));
400 base::FilePath
GetCacheCRXFile(const std::string
& account_id
,
401 const std::string
& id
,
402 const std::string
& version
) {
403 return GetCacheDirectoryForAccountID(account_id
)
404 .Append(base::StringPrintf("%s-%s.crx", id
.c_str(), version
.c_str()));
407 // Returns a profile which can be used for testing.
408 Profile
* GetProfileForTest() {
409 // Any profile can be used here since this test does not test multi profile.
410 return ProfileManager::GetActiveUserProfile();
413 const std::string user_id_1_
;
414 const std::string user_id_2_
;
416 scoped_ptr
<base::RunLoop
> run_loop_
;
418 UserPolicyBuilder device_local_account_policy_
;
419 LocalPolicyTestServer test_server_
;
422 base::ScopedTempDir extension_cache_root_dir_
;
423 base::ScopedTempDir external_data_cache_dir_
;
424 scoped_ptr
<base::ScopedPathOverride
> extension_cache_root_dir_override_
;
425 scoped_ptr
<base::ScopedPathOverride
> external_data_cache_dir_override_
;
427 DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountTest
);
430 static bool IsKnownUser(const std::string
& account_id
) {
431 return chromeos::UserManager::Get()->IsKnownUser(account_id
);
434 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest
, LoginScreen
) {
435 AddPublicSessionToDevicePolicy(kAccountId1
);
436 AddPublicSessionToDevicePolicy(kAccountId2
);
438 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED
,
439 base::Bind(&IsKnownUser
, user_id_1_
))
441 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED
,
442 base::Bind(&IsKnownUser
, user_id_2_
))
445 CheckPublicSessionPresent(user_id_1_
);
446 CheckPublicSessionPresent(user_id_2_
);
449 static bool DisplayNameMatches(const std::string
& account_id
,
450 const std::string
& display_name
) {
451 const chromeos::User
* user
=
452 chromeos::UserManager::Get()->FindUser(account_id
);
453 if (!user
|| user
->display_name().empty())
455 EXPECT_EQ(base::UTF8ToUTF16(display_name
), user
->display_name());
459 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest
, DisplayName
) {
460 UploadAndInstallDeviceLocalAccountPolicy();
461 AddPublicSessionToDevicePolicy(kAccountId1
);
463 content::WindowedNotificationObserver(
464 chrome::NOTIFICATION_USER_LIST_CHANGED
,
465 base::Bind(&DisplayNameMatches
, user_id_1_
, kDisplayName
)).Wait();
468 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest
, PolicyDownload
) {
469 UploadDeviceLocalAccountPolicy();
470 AddPublicSessionToDevicePolicy(kAccountId1
);
472 // Policy for the account is not installed in session_manager_client. Because
473 // of this, the presence of the display name (which comes from policy) can be
474 // used as a signal that indicates successful policy download.
475 content::WindowedNotificationObserver(
476 chrome::NOTIFICATION_USER_LIST_CHANGED
,
477 base::Bind(&DisplayNameMatches
, user_id_1_
, kDisplayName
)).Wait();
479 // Sanity check: The policy should be present now.
480 ASSERT_FALSE(session_manager_client()->device_local_account_policy(
481 kAccountId1
).empty());
484 static bool IsNotKnownUser(const std::string
& account_id
) {
485 return !IsKnownUser(account_id
);
488 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest
, DevicePolicyChange
) {
489 AddPublicSessionToDevicePolicy(kAccountId1
);
490 AddPublicSessionToDevicePolicy(kAccountId2
);
492 // Wait until the login screen is up.
493 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED
,
494 base::Bind(&IsKnownUser
, user_id_1_
))
496 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED
,
497 base::Bind(&IsKnownUser
, user_id_2_
))
500 // Update policy to remove kAccountId2.
501 em::ChromeDeviceSettingsProto
& proto(device_policy()->payload());
502 proto
.mutable_device_local_accounts()->clear_account();
503 AddPublicSessionToDevicePolicy(kAccountId1
);
505 em::ChromeDeviceSettingsProto policy
;
506 policy
.mutable_show_user_names()->set_show_user_names(true);
507 em::DeviceLocalAccountInfoProto
* account1
=
508 policy
.mutable_device_local_accounts()->add_account();
509 account1
->set_account_id(kAccountId1
);
511 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION
);
513 test_server_
.UpdatePolicy(dm_protocol::kChromeDevicePolicyType
, std::string(),
514 policy
.SerializeAsString());
515 g_browser_process
->policy_service()->RefreshPolicies(base::Closure());
517 // Make sure the second device-local account disappears.
518 content::WindowedNotificationObserver(
519 chrome::NOTIFICATION_USER_LIST_CHANGED
,
520 base::Bind(&IsNotKnownUser
, user_id_2_
)).Wait();
523 static bool IsSessionStarted() {
524 return chromeos::UserManager::Get()->IsSessionStarted();
527 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest
, StartSession
) {
528 // Specify startup pages.
529 device_local_account_policy_
.payload().mutable_restoreonstartup()->set_value(
530 SessionStartupPref::kPrefValueURLs
);
531 em::StringListPolicyProto
* startup_urls_proto
=
532 device_local_account_policy_
.payload().mutable_restoreonstartupurls();
533 for (size_t i
= 0; i
< arraysize(kStartupURLs
); ++i
)
534 startup_urls_proto
->mutable_value()->add_entries(kStartupURLs
[i
]);
535 UploadAndInstallDeviceLocalAccountPolicy();
536 AddPublicSessionToDevicePolicy(kAccountId1
);
538 // This observes the display name becoming available as this indicates
539 // device-local account policy is fully loaded, which is a prerequisite for
541 content::WindowedNotificationObserver(
542 chrome::NOTIFICATION_USER_LIST_CHANGED
,
543 base::Bind(&DisplayNameMatches
, user_id_1_
, kDisplayName
)).Wait();
545 // Wait for the login UI to be ready.
546 chromeos::LoginDisplayHostImpl
* host
=
547 reinterpret_cast<chromeos::LoginDisplayHostImpl
*>(
548 chromeos::LoginDisplayHostImpl::default_host());
550 chromeos::OobeUI
* oobe_ui
= host
->GetOobeUI();
551 ASSERT_TRUE(oobe_ui
);
552 base::RunLoop run_loop
;
553 const bool oobe_ui_ready
= oobe_ui
->IsJSReady(run_loop
.QuitClosure());
557 // Start login into the device-local account.
558 host
->StartSignInScreen(LoginScreenContext());
559 chromeos::ExistingUserController
* controller
=
560 chromeos::ExistingUserController::current_controller();
561 ASSERT_TRUE(controller
);
562 controller
->LoginAsPublicAccount(user_id_1_
);
564 // Wait for the session to start.
565 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED
,
566 base::Bind(IsSessionStarted
)).Wait();
568 // Check that the startup pages specified in policy were opened.
569 BrowserList
* browser_list
=
570 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH
);
571 EXPECT_EQ(1U, browser_list
->size());
572 Browser
* browser
= browser_list
->get(0);
573 ASSERT_TRUE(browser
);
575 TabStripModel
* tabs
= browser
->tab_strip_model();
577 int expected_tab_count
= static_cast<int>(arraysize(kStartupURLs
));
578 EXPECT_EQ(expected_tab_count
, tabs
->count());
579 for (int i
= 0; i
< expected_tab_count
&& i
< tabs
->count(); ++i
) {
580 EXPECT_EQ(GURL(kStartupURLs
[i
]),
581 tabs
->GetWebContentsAt(i
)->GetVisibleURL());
585 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest
, FullscreenDisallowed
) {
586 UploadAndInstallDeviceLocalAccountPolicy();
587 AddPublicSessionToDevicePolicy(kAccountId1
);
589 // This observes the display name becoming available as this indicates
590 // device-local account policy is fully loaded, which is a prerequisite for
592 content::WindowedNotificationObserver(
593 chrome::NOTIFICATION_USER_LIST_CHANGED
,
594 base::Bind(&DisplayNameMatches
, user_id_1_
, kDisplayName
)).Wait();
596 // Wait for the login UI to be ready.
597 chromeos::LoginDisplayHostImpl
* host
=
598 reinterpret_cast<chromeos::LoginDisplayHostImpl
*>(
599 chromeos::LoginDisplayHostImpl::default_host());
601 chromeos::OobeUI
* oobe_ui
= host
->GetOobeUI();
602 ASSERT_TRUE(oobe_ui
);
603 base::RunLoop run_loop
;
604 const bool oobe_ui_ready
= oobe_ui
->IsJSReady(run_loop
.QuitClosure());
608 // Ensure that the browser stays alive, even though no windows are opened
609 // during session start.
610 chrome::StartKeepAlive();
612 // Start login into the device-local account.
613 host
->StartSignInScreen(LoginScreenContext());
614 chromeos::ExistingUserController
* controller
=
615 chromeos::ExistingUserController::current_controller();
616 ASSERT_TRUE(controller
);
617 controller
->LoginAsPublicAccount(user_id_1_
);
619 // Wait for the session to start.
620 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED
,
621 base::Bind(IsSessionStarted
)).Wait();
623 // Open a browser window.
624 chrome::NewEmptyWindow(GetProfileForTest(), chrome::HOST_DESKTOP_TYPE_ASH
);
625 BrowserList
* browser_list
=
626 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH
);
627 EXPECT_EQ(1U, browser_list
->size());
628 Browser
* browser
= browser_list
->get(0);
629 ASSERT_TRUE(browser
);
630 BrowserWindow
* browser_window
= browser
->window();
631 ASSERT_TRUE(browser_window
);
632 chrome::EndKeepAlive();
634 // Verify that an attempt to enter fullscreen mode is denied.
635 EXPECT_FALSE(browser_window
->IsFullscreen());
636 chrome::ToggleFullscreenMode(browser
);
637 EXPECT_FALSE(browser_window
->IsFullscreen());
640 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest
, ExtensionsUncached
) {
641 // Make it possible to force-install a hosted app and an extension.
642 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
643 TestingUpdateManifestProvider
testing_update_manifest_provider(
645 testing_update_manifest_provider
.AddUpdate(
648 embedded_test_server()->GetURL(std::string("/") + kHostedAppCRXPath
));
649 testing_update_manifest_provider
.AddUpdate(
651 kGoodExtensionVersion
,
652 embedded_test_server()->GetURL(std::string("/") + kGoodExtensionCRXPath
));
653 embedded_test_server()->RegisterRequestHandler(
654 base::Bind(&TestingUpdateManifestProvider::HandleRequest
,
655 base::Unretained(&testing_update_manifest_provider
)));
657 // Specify policy to force-install the hosted app and the extension.
658 em::StringList
* forcelist
= device_local_account_policy_
.payload()
659 .mutable_extensioninstallforcelist()->mutable_value();
660 forcelist
->add_entries(base::StringPrintf(
663 embedded_test_server()->GetURL(kRelativeUpdateURL
).spec().c_str()));
664 forcelist
->add_entries(base::StringPrintf(
667 embedded_test_server()->GetURL(kRelativeUpdateURL
).spec().c_str()));
669 UploadAndInstallDeviceLocalAccountPolicy();
670 AddPublicSessionToDevicePolicy(kAccountId1
);
672 // This observes the display name becoming available as this indicates
673 // device-local account policy is fully loaded, which is a prerequisite for
675 content::WindowedNotificationObserver(
676 chrome::NOTIFICATION_USER_LIST_CHANGED
,
677 base::Bind(&DisplayNameMatches
, user_id_1_
, kDisplayName
)).Wait();
679 // Wait for the login UI to be ready.
680 chromeos::LoginDisplayHostImpl
* host
=
681 reinterpret_cast<chromeos::LoginDisplayHostImpl
*>(
682 chromeos::LoginDisplayHostImpl::default_host());
684 chromeos::OobeUI
* oobe_ui
= host
->GetOobeUI();
685 ASSERT_TRUE(oobe_ui
);
686 base::RunLoop run_loop
;
687 const bool oobe_ui_ready
= oobe_ui
->IsJSReady(run_loop
.QuitClosure());
691 // Ensure that the browser stays alive, even though no windows are opened
692 // during session start.
693 chrome::StartKeepAlive();
695 // Start listening for app/extension installation results.
696 content::WindowedNotificationObserver
hosted_app_observer(
697 chrome::NOTIFICATION_EXTENSION_INSTALLED
,
698 base::Bind(DoesInstallSuccessReferToId
, kHostedAppID
));
699 content::WindowedNotificationObserver
extension_observer(
700 chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR
,
701 base::Bind(DoesInstallFailureReferToId
, kGoodExtensionID
));
703 // Start login into the device-local account.
704 host
->StartSignInScreen(LoginScreenContext());
705 chromeos::ExistingUserController
* controller
=
706 chromeos::ExistingUserController::current_controller();
707 ASSERT_TRUE(controller
);
708 controller
->LoginAsPublicAccount(user_id_1_
);
710 // Wait for the hosted app installation to succeed and the extension
711 // installation to fail (because hosted apps are whitelisted for use in
712 // device-local accounts and extensions are not).
713 hosted_app_observer
.Wait();
714 extension_observer
.Wait();
716 // Verify that the hosted app was installed.
717 Profile
* profile
= GetProfileForTest();
718 ASSERT_TRUE(profile
);
719 ExtensionService
* extension_service
=
720 extensions::ExtensionSystem::Get(profile
)->extension_service();
721 EXPECT_TRUE(extension_service
->GetExtensionById(kHostedAppID
, true));
723 // Verify that the extension was not installed.
724 EXPECT_FALSE(extension_service
->GetExtensionById(kGoodExtensionID
, true));
726 // Verify that the app was copied to the account's extension cache.
727 base::FilePath test_dir
;
728 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &test_dir
));
729 EXPECT_TRUE(ContentsEqual(
730 GetCacheCRXFile(kAccountId1
, kHostedAppID
, kHostedAppVersion
),
731 test_dir
.Append(kHostedAppCRXPath
)));
733 // Verify that the extension was not copied to the account's extension cache.
734 EXPECT_FALSE(PathExists(GetCacheCRXFile(
735 kAccountId1
, kGoodExtensionID
, kGoodExtensionVersion
)));
738 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest
, ExtensionsCached
) {
739 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
741 // Pre-populate the device local account's extension cache with a hosted app
743 EXPECT_TRUE(base::CreateDirectory(
744 GetCacheDirectoryForAccountID(kAccountId1
)));
745 base::FilePath test_dir
;
746 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &test_dir
));
747 const base::FilePath cached_hosted_app
=
748 GetCacheCRXFile(kAccountId1
, kHostedAppID
, kHostedAppVersion
);
749 EXPECT_TRUE(CopyFile(test_dir
.Append(kHostedAppCRXPath
),
751 const base::FilePath cached_extension
=
752 GetCacheCRXFile(kAccountId1
, kGoodExtensionID
, kGoodExtensionVersion
);
753 EXPECT_TRUE(CopyFile(test_dir
.Append(kGoodExtensionCRXPath
),
756 // Specify policy to force-install the hosted app.
757 em::StringList
* forcelist
= device_local_account_policy_
.payload()
758 .mutable_extensioninstallforcelist()->mutable_value();
759 forcelist
->add_entries(base::StringPrintf(
762 embedded_test_server()->GetURL(kRelativeUpdateURL
).spec().c_str()));
763 forcelist
->add_entries(base::StringPrintf(
766 embedded_test_server()->GetURL(kRelativeUpdateURL
).spec().c_str()));
768 UploadAndInstallDeviceLocalAccountPolicy();
769 AddPublicSessionToDevicePolicy(kAccountId1
);
771 // This observes the display name becoming available as this indicates
772 // device-local account policy is fully loaded, which is a prerequisite for
774 content::WindowedNotificationObserver(
775 chrome::NOTIFICATION_USER_LIST_CHANGED
,
776 base::Bind(&DisplayNameMatches
, user_id_1_
, kDisplayName
)).Wait();
778 // Wait for the login UI to be ready.
779 chromeos::LoginDisplayHostImpl
* host
=
780 reinterpret_cast<chromeos::LoginDisplayHostImpl
*>(
781 chromeos::LoginDisplayHostImpl::default_host());
783 chromeos::OobeUI
* oobe_ui
= host
->GetOobeUI();
784 ASSERT_TRUE(oobe_ui
);
785 base::RunLoop run_loop
;
786 const bool oobe_ui_ready
= oobe_ui
->IsJSReady(run_loop
.QuitClosure());
790 // Ensure that the browser stays alive, even though no windows are opened
791 // during session start.
792 chrome::StartKeepAlive();
794 // Start listening for app/extension installation results.
795 content::WindowedNotificationObserver
hosted_app_observer(
796 chrome::NOTIFICATION_EXTENSION_INSTALLED
,
797 base::Bind(DoesInstallSuccessReferToId
, kHostedAppID
));
798 content::WindowedNotificationObserver
extension_observer(
799 chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR
,
800 base::Bind(DoesInstallFailureReferToId
, kGoodExtensionID
));
802 // Start login into the device-local account.
803 host
->StartSignInScreen(LoginScreenContext());
804 chromeos::ExistingUserController
* controller
=
805 chromeos::ExistingUserController::current_controller();
806 ASSERT_TRUE(controller
);
807 controller
->LoginAsPublicAccount(user_id_1_
);
809 // Wait for the hosted app installation to succeed and the extension
810 // installation to fail.
811 hosted_app_observer
.Wait();
812 extension_observer
.Wait();
814 // Verify that the hosted app was installed.
815 Profile
* profile
= GetProfileForTest();
816 ASSERT_TRUE(profile
);
817 ExtensionService
* extension_service
=
818 extensions::ExtensionSystem::Get(profile
)->extension_service();
819 EXPECT_TRUE(extension_service
->GetExtensionById(kHostedAppID
, true));
821 // Verify that the extension was not installed.
822 EXPECT_FALSE(extension_service
->GetExtensionById(kGoodExtensionID
, true));
824 // Verify that the app is still in the account's extension cache.
825 EXPECT_TRUE(PathExists(cached_hosted_app
));
827 // Verify that the extension was removed from the account's extension cache.
828 EXPECT_FALSE(PathExists(cached_extension
));
831 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest
, ExternalData
) {
832 // chromeos::UserManager requests an external data fetch whenever
833 // the key::kUserAvatarImage policy is set. Since this test wants to
834 // verify that the underlying policy subsystem will start a fetch
835 // without this request as well, the chromeos::UserManager must be
836 // prevented from seeing the policy change.
837 reinterpret_cast<chromeos::UserManagerImpl
*>(chromeos::UserManager::Get())->
838 StopPolicyObserverForTesting();
840 UploadDeviceLocalAccountPolicy();
841 AddPublicSessionToDevicePolicy(kAccountId1
);
843 // This observes the display name becoming available as this indicates
844 // device-local account policy is fully loaded.
845 content::WindowedNotificationObserver(
846 chrome::NOTIFICATION_USER_LIST_CHANGED
,
847 base::Bind(&DisplayNameMatches
, user_id_1_
, kDisplayName
)).Wait();
849 // Start serving external data at |kExternalDataURL|.
850 scoped_ptr
<base::RunLoop
> run_loop(new base::RunLoop
);
851 scoped_ptr
<net::FakeURLFetcherFactory
> fetcher_factory(
852 new net::FakeURLFetcherFactory(
854 base::Bind(&RunCallbackAndReturnFakeURLFetcher
,
855 base::MessageLoopProxy::current(),
856 run_loop
->QuitClosure())));
857 fetcher_factory
->SetFakeResponse(GURL(kExternalDataURL
),
860 net::URLRequestStatus::SUCCESS
);
862 // Specify an external data reference for the key::kUserAvatarImage policy.
863 scoped_ptr
<base::DictionaryValue
> metadata
=
864 test::ConstructExternalDataReference(kExternalDataURL
, kExternalData
);
866 base::JSONWriter::Write(metadata
.get(), &policy
);
867 device_local_account_policy_
.payload().mutable_useravatarimage()->set_value(
869 UploadAndInstallDeviceLocalAccountPolicy();
870 DeviceLocalAccountPolicyBroker
* broker
=
871 g_browser_process
->browser_policy_connector()->
872 GetDeviceLocalAccountPolicyService()->GetBrokerForUser(user_id_1_
);
874 broker
->core()->store()->Load();
876 // The external data should be fetched and cached automatically. Wait for this
880 // Stop serving external data at |kExternalDataURL|.
881 fetcher_factory
.reset();
883 const PolicyMap::Entry
* policy_entry
=
884 broker
->core()->store()->policy_map().Get(key::kUserAvatarImage
);
885 ASSERT_TRUE(policy_entry
);
886 ASSERT_TRUE(policy_entry
->external_data_fetcher
);
888 // Retrieve the external data. Although the data is no longer being served at
889 // |kExternalDataURL|, the retrieval should succeed because the data has been
891 run_loop
.reset(new base::RunLoop
);
892 scoped_ptr
<std::string
> fetched_external_data
;
893 policy_entry
->external_data_fetcher
->Fetch(base::Bind(
894 &test::ExternalDataFetchCallback
,
895 &fetched_external_data
,
896 run_loop
->QuitClosure()));
899 ASSERT_TRUE(fetched_external_data
);
900 EXPECT_EQ(kExternalData
, *fetched_external_data
);
902 // Wait for the login UI to be ready.
903 chromeos::LoginDisplayHostImpl
* host
=
904 reinterpret_cast<chromeos::LoginDisplayHostImpl
*>(
905 chromeos::LoginDisplayHostImpl::default_host());
907 chromeos::OobeUI
* oobe_ui
= host
->GetOobeUI();
908 ASSERT_TRUE(oobe_ui
);
909 run_loop
.reset(new base::RunLoop
);
910 const bool oobe_ui_ready
= oobe_ui
->IsJSReady(run_loop
->QuitClosure());
914 // Ensure that the browser stays alive, even though no windows are opened
915 // during session start.
916 chrome::StartKeepAlive();
918 // Start login into the device-local account.
919 host
->StartSignInScreen(LoginScreenContext());
920 chromeos::ExistingUserController
* controller
=
921 chromeos::ExistingUserController::current_controller();
922 ASSERT_TRUE(controller
);
923 controller
->LoginAsPublicAccount(user_id_1_
);
925 // Wait for the session to start.
926 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED
,
927 base::Bind(IsSessionStarted
)).Wait();
929 // Verify that the external data reference has propagated to the device-local
930 // account's ProfilePolicyConnector.
931 ProfilePolicyConnector
* policy_connector
=
932 ProfilePolicyConnectorFactory::GetForProfile(GetProfileForTest());
933 ASSERT_TRUE(policy_connector
);
934 const PolicyMap
& policies
= policy_connector
->policy_service()->GetPolicies(
935 PolicyNamespace(POLICY_DOMAIN_CHROME
, std::string()));
936 policy_entry
= policies
.Get(key::kUserAvatarImage
);
937 ASSERT_TRUE(policy_entry
);
938 EXPECT_TRUE(base::Value::Equals(metadata
.get(), policy_entry
->value
));
939 ASSERT_TRUE(policy_entry
->external_data_fetcher
);
941 // Retrieve the external data via the ProfilePolicyConnector. The retrieval
942 // should succeed because the data has been cached.
943 run_loop
.reset(new base::RunLoop
);
944 fetched_external_data
.reset();
945 policy_entry
->external_data_fetcher
->Fetch(base::Bind(
946 &test::ExternalDataFetchCallback
,
947 &fetched_external_data
,
948 run_loop
->QuitClosure()));
951 ASSERT_TRUE(fetched_external_data
);
952 EXPECT_EQ(kExternalData
, *fetched_external_data
);
955 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest
, UserAvatarImage
) {
956 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
958 UploadDeviceLocalAccountPolicy();
959 AddPublicSessionToDevicePolicy(kAccountId1
);
961 // This observes the display name becoming available as this indicates
962 // device-local account policy is fully loaded.
963 content::WindowedNotificationObserver(
964 chrome::NOTIFICATION_USER_LIST_CHANGED
,
965 base::Bind(&DisplayNameMatches
, user_id_1_
, kDisplayName
)).Wait();
967 base::FilePath test_dir
;
968 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &test_dir
));
969 std::string image_data
;
970 ASSERT_TRUE(base::ReadFileToString(
971 test_dir
.Append(chromeos::test::kUserAvatarImage1RelativePath
),
975 base::JSONWriter::Write(test::ConstructExternalDataReference(
976 embedded_test_server()->GetURL(std::string("/") +
977 chromeos::test::kUserAvatarImage1RelativePath
).spec(),
980 device_local_account_policy_
.payload().mutable_useravatarimage()->set_value(
982 UploadAndInstallDeviceLocalAccountPolicy();
983 DeviceLocalAccountPolicyBroker
* broker
=
984 g_browser_process
->browser_policy_connector()->
985 GetDeviceLocalAccountPolicyService()->GetBrokerForUser(user_id_1_
);
988 run_loop_
.reset(new base::RunLoop
);
989 chromeos::UserManager::Get()->AddObserver(this);
990 broker
->core()->store()->Load();
992 chromeos::UserManager::Get()->RemoveObserver(this);
994 scoped_ptr
<gfx::ImageSkia
> policy_image
= chromeos::test::ImageLoader(
995 test_dir
.Append(chromeos::test::kUserAvatarImage1RelativePath
)).Load();
996 ASSERT_TRUE(policy_image
);
998 const chromeos::User
* user
=
999 chromeos::UserManager::Get()->FindUser(user_id_1_
);
1002 base::FilePath user_data_dir
;
1003 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA
, &user_data_dir
));
1004 const base::FilePath saved_image_path
=
1005 user_data_dir
.Append(user_id_1_
).AddExtension("jpg");
1007 EXPECT_FALSE(user
->HasDefaultImage());
1008 EXPECT_EQ(chromeos::User::kExternalImageIndex
, user
->image_index());
1009 EXPECT_TRUE(chromeos::test::AreImagesEqual(*policy_image
, user
->image()));
1010 const base::DictionaryValue
* images_pref
=
1011 g_browser_process
->local_state()->GetDictionary("user_image_info");
1012 ASSERT_TRUE(images_pref
);
1013 const base::DictionaryValue
* image_properties
;
1014 ASSERT_TRUE(images_pref
->GetDictionaryWithoutPathExpansion(
1016 &image_properties
));
1018 std::string image_path
;
1019 ASSERT_TRUE(image_properties
->GetInteger("index", &image_index
));
1020 ASSERT_TRUE(image_properties
->GetString("path", &image_path
));
1021 EXPECT_EQ(chromeos::User::kExternalImageIndex
, image_index
);
1022 EXPECT_EQ(saved_image_path
.value(), image_path
);
1024 scoped_ptr
<gfx::ImageSkia
> saved_image
=
1025 chromeos::test::ImageLoader(saved_image_path
).Load();
1026 ASSERT_TRUE(saved_image
);
1028 // Check image dimensions. Images can't be compared since JPEG is lossy.
1029 EXPECT_EQ(policy_image
->width(), saved_image
->width());
1030 EXPECT_EQ(policy_image
->height(), saved_image
->height());
1033 class TermsOfServiceTest
: public DeviceLocalAccountTest
,
1034 public testing::WithParamInterface
<bool> {
1037 IN_PROC_BROWSER_TEST_P(TermsOfServiceTest
, TermsOfServiceScreen
) {
1038 // Specify Terms of Service URL.
1039 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
1040 device_local_account_policy_
.payload().mutable_termsofserviceurl()->set_value(
1041 embedded_test_server()->GetURL(
1043 (GetParam() ? kExistentTermsOfServicePath
1044 : kNonexistentTermsOfServicePath
)).spec());
1045 UploadAndInstallDeviceLocalAccountPolicy();
1046 AddPublicSessionToDevicePolicy(kAccountId1
);
1048 // Wait for the device-local account policy to be fully loaded.
1049 content::WindowedNotificationObserver(
1050 chrome::NOTIFICATION_USER_LIST_CHANGED
,
1051 base::Bind(&DisplayNameMatches
, user_id_1_
, kDisplayName
)).Wait();
1053 // Wait for the login UI to be ready.
1054 chromeos::LoginDisplayHostImpl
* host
=
1055 reinterpret_cast<chromeos::LoginDisplayHostImpl
*>(
1056 chromeos::LoginDisplayHostImpl::default_host());
1058 chromeos::OobeUI
* oobe_ui
= host
->GetOobeUI();
1059 ASSERT_TRUE(oobe_ui
);
1060 base::RunLoop oobe_ui_wait_run_loop
;
1061 const bool oobe_ui_ready
=
1062 oobe_ui
->IsJSReady(oobe_ui_wait_run_loop
.QuitClosure());
1064 oobe_ui_wait_run_loop
.Run();
1066 // Start login into the device-local account.
1067 host
->StartSignInScreen(LoginScreenContext());
1068 chromeos::ExistingUserController
* controller
=
1069 chromeos::ExistingUserController::current_controller();
1070 ASSERT_TRUE(controller
);
1071 controller
->LoginAsPublicAccount(user_id_1_
);
1073 // Set up an observer that will quit the message loop when login has succeeded
1074 // and the first wizard screen, if any, is being shown.
1075 base::RunLoop login_wait_run_loop
;
1076 chromeos::MockConsumer login_status_consumer
;
1077 EXPECT_CALL(login_status_consumer
, OnLoginSuccess(_
))
1079 .WillOnce(InvokeWithoutArgs(&login_wait_run_loop
, &base::RunLoop::Quit
));
1081 // Spin the loop until the observer fires. Then, unregister the observer.
1082 controller
->set_login_status_consumer(&login_status_consumer
);
1083 login_wait_run_loop
.Run();
1084 controller
->set_login_status_consumer(NULL
);
1086 // Verify that the Terms of Service screen is being shown.
1087 chromeos::WizardController
* wizard_controller
=
1088 chromeos::WizardController::default_controller();
1089 ASSERT_TRUE(wizard_controller
);
1090 ASSERT_TRUE(wizard_controller
->current_screen());
1091 EXPECT_EQ(chromeos::WizardController::kTermsOfServiceScreenName
,
1092 wizard_controller
->current_screen()->GetName());
1094 // Wait for the Terms of Service to finish downloading, then get the status of
1095 // the screen's UI elements.
1096 chromeos::WebUILoginView
* web_ui_login_view
= host
->GetWebUILoginView();
1097 ASSERT_TRUE(web_ui_login_view
);
1098 content::WebUI
* web_ui
= web_ui_login_view
->GetWebUI();
1099 ASSERT_TRUE(web_ui
);
1100 content::WebContents
* contents
= web_ui
->GetWebContents();
1101 ASSERT_TRUE(contents
);
1103 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents
,
1104 "var screen = document.getElementById('terms-of-service');"
1105 "function SendReplyIfDownloadDone() {"
1106 " if (screen.classList.contains('tos-loading'))"
1109 " status.heading = document.getElementById('tos-heading').textContent;"
1110 " status.subheading ="
1111 " document.getElementById('tos-subheading').textContent;"
1112 " status.contentHeading ="
1113 " document.getElementById('tos-content-heading').textContent;"
1115 " document.getElementById('tos-content-main').textContent;"
1116 " status.error = screen.classList.contains('error');"
1117 " status.acceptEnabled ="
1118 " !document.getElementById('tos-accept-button').disabled;"
1119 " domAutomationController.send(JSON.stringify(status));"
1120 " observer.disconnect();"
1123 "var observer = new MutationObserver(SendReplyIfDownloadDone);"
1124 "if (!SendReplyIfDownloadDone()) {"
1125 " var options = { attributes: true, attributeFilter: [ 'class' ] };"
1126 " observer.observe(screen, options);"
1129 scoped_ptr
<base::Value
> value_ptr(base::JSONReader::Read(json
));
1130 const base::DictionaryValue
* status
= NULL
;
1131 ASSERT_TRUE(value_ptr
.get());
1132 ASSERT_TRUE(value_ptr
->GetAsDictionary(&status
));
1133 std::string heading
;
1134 EXPECT_TRUE(status
->GetString("heading", &heading
));
1135 std::string subheading
;
1136 EXPECT_TRUE(status
->GetString("subheading", &subheading
));
1137 std::string content_heading
;
1138 EXPECT_TRUE(status
->GetString("contentHeading", &content_heading
));
1139 std::string content
;
1140 EXPECT_TRUE(status
->GetString("content", &content
));
1142 EXPECT_TRUE(status
->GetBoolean("error", &error
));
1143 bool accept_enabled
;
1144 EXPECT_TRUE(status
->GetBoolean("acceptEnabled", &accept_enabled
));
1146 // Verify that the screen's headings have been set correctly.
1148 l10n_util::GetStringFUTF8(IDS_TERMS_OF_SERVICE_SCREEN_HEADING
,
1149 base::UTF8ToUTF16(kDomain
)),
1152 l10n_util::GetStringFUTF8(IDS_TERMS_OF_SERVICE_SCREEN_SUBHEADING
,
1153 base::UTF8ToUTF16(kDomain
)),
1156 l10n_util::GetStringFUTF8(IDS_TERMS_OF_SERVICE_SCREEN_CONTENT_HEADING
,
1157 base::UTF8ToUTF16(kDomain
)),
1161 // The Terms of Service URL was invalid. Verify that the screen is showing
1162 // an error and the accept button is disabled.
1164 EXPECT_FALSE(accept_enabled
);
1168 // The Terms of Service URL was valid. Verify that the screen is showing the
1169 // downloaded Terms of Service and the accept button is enabled.
1170 base::FilePath test_dir
;
1171 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &test_dir
));
1172 std::string terms_of_service
;
1173 ASSERT_TRUE(base::ReadFileToString(
1174 test_dir
.Append(kExistentTermsOfServicePath
), &terms_of_service
));
1175 EXPECT_EQ(terms_of_service
, content
);
1176 EXPECT_FALSE(error
);
1177 EXPECT_TRUE(accept_enabled
);
1179 // Click the accept button.
1180 ASSERT_TRUE(content::ExecuteScript(contents
,
1181 "$('tos-accept-button').click();"));
1183 // Wait for the session to start.
1184 if (!IsSessionStarted()) {
1185 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED
,
1186 base::Bind(IsSessionStarted
)).Wait();
1190 INSTANTIATE_TEST_CASE_P(TermsOfServiceTestInstance
,
1191 TermsOfServiceTest
, testing::Bool());
1193 } // namespace policy