ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / chromeos / login / supervised / supervised_user_test_base.cc
blob64bec8af0cba3537e2e0316fb7751922814fed76
1 // Copyright 2014 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.
5 #include "chrome/browser/chromeos/login/supervised/supervised_user_test_base.h"
7 #include <string>
9 #include "base/compiler_specific.h"
10 #include "base/run_loop.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/chromeos/login/login_manager_test.h"
17 #include "chrome/browser/chromeos/login/startup_utils.h"
18 #include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h"
19 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
20 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
21 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
22 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
23 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
24 #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h"
25 #include "chrome/browser/chromeos/profiles/profile_helper.h"
26 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
27 #include "chrome/browser/profiles/profile_impl.h"
28 #include "chrome/browser/supervised_user/legacy/supervised_user_registration_utility.h"
29 #include "chrome/browser/supervised_user/legacy/supervised_user_registration_utility_stub.h"
30 #include "chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service.h"
31 #include "chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_factory.h"
32 #include "chrome/browser/supervised_user/legacy/supervised_user_sync_service.h"
33 #include "chrome/browser/supervised_user/legacy/supervised_user_sync_service_factory.h"
34 #include "chrome/browser/supervised_user/supervised_user_constants.h"
35 #include "chromeos/cryptohome/mock_async_method_caller.h"
36 #include "chromeos/cryptohome/mock_homedir_methods.h"
37 #include "chromeos/login/auth/key.h"
38 #include "chromeos/login/auth/user_context.h"
39 #include "content/public/browser/notification_service.h"
40 #include "content/public/test/browser_test_utils.h"
41 #include "content/public/test/test_utils.h"
42 #include "sync/api/fake_sync_change_processor.h"
43 #include "sync/api/sync_change.h"
44 #include "sync/api/sync_error_factory_mock.h"
45 #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
46 #include "sync/protocol/sync.pb.h"
48 using testing::_;
49 using base::StringPrintf;
51 namespace chromeos {
53 namespace {
55 const char kCurrentPage[] = "$('supervised-user-creation').currentPage_";
57 const char kStubEthernetGuid[] = "eth0";
61 SupervisedUsersSyncTestAdapter::SupervisedUsersSyncTestAdapter(Profile* profile)
62 : processor_(), next_sync_data_id_(0) {
63 service_ = SupervisedUserSyncServiceFactory::GetForProfile(profile);
64 processor_ = new syncer::FakeSyncChangeProcessor();
65 service_->MergeDataAndStartSyncing(
66 syncer::SUPERVISED_USERS,
67 syncer::SyncDataList(),
68 scoped_ptr<syncer::SyncChangeProcessor>(processor_),
69 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock));
72 scoped_ptr< ::sync_pb::ManagedUserSpecifics>
73 SupervisedUsersSyncTestAdapter::GetFirstChange() {
74 scoped_ptr< ::sync_pb::ManagedUserSpecifics> result(
75 new ::sync_pb::ManagedUserSpecifics);
76 CHECK(HasChanges())
77 << "GetFirstChange() should only be callled if HasChanges() is true";
78 const syncer::SyncData& data = processor_->changes().front().sync_data();
79 EXPECT_EQ(syncer::SUPERVISED_USERS, data.GetDataType());
80 result->CopyFrom(data.GetSpecifics().managed_user());
81 return result.Pass();
84 void SupervisedUsersSyncTestAdapter::AddChange(
85 const ::sync_pb::ManagedUserSpecifics& proto,
86 bool update) {
87 sync_pb::EntitySpecifics specifics;
89 specifics.mutable_managed_user()->CopyFrom(proto);
91 syncer::SyncData change_data = syncer::SyncData::CreateRemoteData(
92 ++next_sync_data_id_,
93 specifics,
94 base::Time(),
95 syncer::AttachmentIdList(),
96 syncer::AttachmentServiceProxyForTest::Create());
97 syncer::SyncChange change(FROM_HERE,
98 update ? syncer::SyncChange::ACTION_UPDATE
99 : syncer::SyncChange::ACTION_ADD,
100 change_data);
102 syncer::SyncChangeList change_list;
103 change_list.push_back(change);
105 service_->ProcessSyncChanges(FROM_HERE, change_list);
108 SupervisedUsersSharedSettingsSyncTestAdapter::
109 SupervisedUsersSharedSettingsSyncTestAdapter(Profile* profile)
110 : processor_(), next_sync_data_id_(0) {
111 service_ =
112 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(profile);
113 processor_ = new syncer::FakeSyncChangeProcessor();
114 service_->MergeDataAndStartSyncing(
115 syncer::SUPERVISED_USER_SHARED_SETTINGS,
116 syncer::SyncDataList(),
117 scoped_ptr<syncer::SyncChangeProcessor>(processor_),
118 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock));
121 scoped_ptr< ::sync_pb::ManagedUserSharedSettingSpecifics>
122 SupervisedUsersSharedSettingsSyncTestAdapter::GetFirstChange() {
123 scoped_ptr< ::sync_pb::ManagedUserSharedSettingSpecifics> result(
124 new ::sync_pb::ManagedUserSharedSettingSpecifics);
125 CHECK(HasChanges())
126 << "GetFirstChange() should only be callled if HasChanges() is true";
127 const syncer::SyncData& data = processor_->changes().front().sync_data();
128 EXPECT_EQ(syncer::SUPERVISED_USER_SHARED_SETTINGS, data.GetDataType());
129 result->CopyFrom(data.GetSpecifics().managed_user_shared_setting());
130 return result.Pass();
133 void SupervisedUsersSharedSettingsSyncTestAdapter::AddChange(
134 const ::sync_pb::ManagedUserSharedSettingSpecifics& proto,
135 bool update) {
136 sync_pb::EntitySpecifics specifics;
138 specifics.mutable_managed_user_shared_setting()->CopyFrom(proto);
140 syncer::SyncData change_data = syncer::SyncData::CreateRemoteData(
141 ++next_sync_data_id_,
142 specifics,
143 base::Time(),
144 syncer::AttachmentIdList(),
145 syncer::AttachmentServiceProxyForTest::Create());
146 syncer::SyncChange change(FROM_HERE,
147 update ? syncer::SyncChange::ACTION_UPDATE
148 : syncer::SyncChange::ACTION_ADD,
149 change_data);
151 syncer::SyncChangeList change_list;
152 change_list.push_back(change);
154 service_->ProcessSyncChanges(FROM_HERE, change_list);
157 void SupervisedUsersSharedSettingsSyncTestAdapter::AddChange(
158 const std::string& mu_id,
159 const std::string& key,
160 const base::Value& value,
161 bool acknowledged,
162 bool update) {
163 syncer::SyncData data =
164 SupervisedUserSharedSettingsService::CreateSyncDataForSetting(
165 mu_id, key, value, acknowledged);
166 AddChange(data.GetSpecifics().managed_user_shared_setting(), update);
169 SupervisedUserTestBase::SupervisedUserTestBase()
170 : LoginManagerTest(true),
171 mock_async_method_caller_(NULL),
172 mock_homedir_methods_(NULL),
173 network_portal_detector_(NULL),
174 registration_utility_stub_(NULL) {
177 SupervisedUserTestBase::~SupervisedUserTestBase() {
180 void SupervisedUserTestBase::SetUpInProcessBrowserTestFixture() {
181 LoginManagerTest::SetUpInProcessBrowserTestFixture();
182 mock_async_method_caller_ = new cryptohome::MockAsyncMethodCaller;
183 mock_async_method_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
184 cryptohome::AsyncMethodCaller::InitializeForTesting(
185 mock_async_method_caller_);
187 mock_homedir_methods_ = new cryptohome::MockHomedirMethods;
188 mock_homedir_methods_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
189 cryptohome::HomedirMethods::InitializeForTesting(mock_homedir_methods_);
191 registration_utility_stub_ = new SupervisedUserRegistrationUtilityStub();
192 scoped_utility_.reset(new ScopedTestingSupervisedUserRegistrationUtility(
193 registration_utility_stub_));
195 // Setup network portal detector to return online state for both
196 // ethernet and wifi networks. Ethernet is an active network by
197 // default.
198 network_portal_detector_ = new NetworkPortalDetectorTestImpl();
199 NetworkPortalDetector::InitializeForTesting(network_portal_detector_);
200 NetworkPortalDetector::CaptivePortalState online_state;
201 online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE;
202 online_state.response_code = 204;
203 network_portal_detector_->SetDefaultNetworkForTesting(kStubEthernetGuid);
204 network_portal_detector_->SetDetectionResultsForTesting(kStubEthernetGuid,
205 online_state);
208 void SupervisedUserTestBase::TearDown() {
209 cryptohome::AsyncMethodCaller::Shutdown();
210 cryptohome::HomedirMethods::Shutdown();
211 mock_homedir_methods_ = NULL;
212 mock_async_method_caller_ = NULL;
213 LoginManagerTest::TearDown();
216 void SupervisedUserTestBase::TearDownInProcessBrowserTestFixture() {
217 NetworkPortalDetector::Shutdown();
220 void SupervisedUserTestBase::JSEval(const std::string& script) {
221 EXPECT_TRUE(content::ExecuteScript(web_contents(), script)) << script;
224 void SupervisedUserTestBase::JSEvalOrExitBrowser(const std::string& script) {
225 ignore_result(content::ExecuteScript(web_contents(), script));
228 void SupervisedUserTestBase::JSExpectAsync(const std::string& function) {
229 bool result;
230 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
231 web_contents(),
232 StringPrintf(
233 "(%s)(function() { window.domAutomationController.send(true); });",
234 function.c_str()),
235 &result)) << function;
236 EXPECT_TRUE(result);
239 void SupervisedUserTestBase::JSSetTextField(const std::string& element_selector,
240 const std::string& value) {
241 std::string function =
242 StringPrintf("document.querySelector('%s').value = '%s'",
243 element_selector.c_str(),
244 value.c_str());
245 JSEval(function);
248 void SupervisedUserTestBase::PrepareUsers() {
249 RegisterUser(kTestManager);
250 RegisterUser(kTestOtherUser);
251 chromeos::StartupUtils::MarkOobeCompleted();
254 void SupervisedUserTestBase::StartFlowLoginAsManager() {
255 // Navigate to supervised user creation screen.
256 JSEval("chrome.send('showSupervisedUserCreationScreen')");
258 // Read intro and proceed.
259 JSExpect(StringPrintf("%s == 'intro'", kCurrentPage));
261 JSEval("$('supervised-user-creation-start-button').click()");
263 // Check that both users appear as managers, and test-manager@gmail.com is
264 // the first one.
265 JSExpect(StringPrintf("%s == 'manager'", kCurrentPage));
267 std::string manager_pods =
268 "document.querySelectorAll('#supervised-user-creation-managers-pane "
269 ".manager-pod')";
270 std::string selected_manager_pods =
271 "document.querySelectorAll('#supervised-user-creation-managers-pane "
272 ".manager-pod.focused')";
274 int managers_on_device = 2;
276 JSExpect(StringPrintf("%s.length == 1", selected_manager_pods.c_str()));
278 JSExpect(StringPrintf(
279 "$('supervised-user-creation').managerList_.pods.length == %d",
280 managers_on_device));
281 JSExpect(StringPrintf(
282 "%s.length == %d", manager_pods.c_str(), managers_on_device));
283 JSExpect(StringPrintf("%s[%d].user.emailAddress == '%s'",
284 manager_pods.c_str(),
286 kTestManager));
288 // Select the first user as manager, and enter password.
289 JSExpect("$('supervised-user-creation-next-button').disabled");
290 JSSetTextField("#supervised-user-creation .manager-pod.focused input",
291 kTestManagerPassword);
293 JSEval("$('supervised-user-creation').updateNextButtonForManager_()");
295 // Next button is now enabled.
296 JSExpect("!$('supervised-user-creation-next-button').disabled");
297 UserContext user_context(kTestManager);
298 user_context.SetKey(Key(kTestManagerPassword));
299 SetExpectedCredentials(user_context);
300 content::WindowedNotificationObserver login_observer(
301 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
302 content::NotificationService::AllSources());
304 // Log in as manager.
305 JSEval("$('supervised-user-creation-next-button').click()");
306 login_observer.Wait();
308 // OAuth token is valid.
309 user_manager::UserManager::Get()->SaveUserOAuthStatus(
310 kTestManager, user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
311 base::RunLoop().RunUntilIdle();
313 // Check the page have changed.
314 JSExpect(StringPrintf("%s == 'username'", kCurrentPage));
317 void SupervisedUserTestBase::FillNewUserData(const std::string& display_name) {
318 JSExpect("$('supervised-user-creation-next-button').disabled");
319 JSSetTextField("#supervised-user-creation-name", display_name);
320 JSEval("$('supervised-user-creation').checkUserName_()");
322 base::RunLoop().RunUntilIdle();
324 JSSetTextField("#supervised-user-creation-password",
325 kTestSupervisedUserPassword);
326 JSSetTextField("#supervised-user-creation-password-confirm",
327 kTestSupervisedUserPassword);
329 JSEval("$('supervised-user-creation').updateNextButtonForUser_()");
330 JSExpect("!$('supervised-user-creation-next-button').disabled");
333 void SupervisedUserTestBase::StartUserCreation(
334 const std::string& button_id,
335 const std::string& expected_display_name) {
336 EXPECT_CALL(*mock_homedir_methods_, MountEx(_, _, _, _)).Times(1);
337 EXPECT_CALL(*mock_homedir_methods_, AddKeyEx(_, _, _, _, _)).Times(1);
339 JSEval(std::string("$('").append(button_id).append("').click()"));
341 ::testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
343 EXPECT_TRUE(registration_utility_stub_->register_was_called());
344 EXPECT_EQ(registration_utility_stub_->display_name(),
345 base::UTF8ToUTF16(expected_display_name));
347 registration_utility_stub_->RunSuccessCallback("token");
349 // Token writing moves control to BlockingPool and back.
350 content::RunAllBlockingPoolTasksUntilIdle();
352 JSExpect(StringPrintf("%s == 'created'", kCurrentPage));
353 JSEvalOrExitBrowser("$('supervised-user-creation-gotit-button').click()");
356 void SupervisedUserTestBase::SigninAsSupervisedUser(
357 bool check_homedir_calls,
358 int user_index,
359 const std::string& expected_display_name) {
360 if (check_homedir_calls)
361 EXPECT_CALL(*mock_homedir_methods_, MountEx(_, _, _, _)).Times(1);
363 // Log in as supervised user, make sure that everything works.
364 ASSERT_EQ(3UL, user_manager::UserManager::Get()->GetUsers().size());
366 // Created supervised user have to be first in a list.
367 const user_manager::User* user =
368 user_manager::UserManager::Get()->GetUsers().at(user_index);
369 ASSERT_EQ(base::UTF8ToUTF16(expected_display_name), user->display_name());
371 // Clean first run flag before logging in.
372 static_cast<SupervisedUserManagerImpl*>(
373 ChromeUserManager::Get()->GetSupervisedUserManager())
374 ->CheckForFirstRun(user->email());
376 LoginUser(user->email());
377 if (check_homedir_calls)
378 ::testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
379 Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
380 shared_settings_adapter_.reset(
381 new SupervisedUsersSharedSettingsSyncTestAdapter(profile));
383 // Check ChromeOS preference is initialized.
384 EXPECT_TRUE(
385 static_cast<ProfileImpl*>(profile)->chromeos_preferences_);
388 void SupervisedUserTestBase::SigninAsManager(int user_index) {
389 // Log in as supervised user, make sure that everything works.
390 ASSERT_EQ(3UL, user_manager::UserManager::Get()->GetUsers().size());
392 // Created supervised user have to be first in a list.
393 const user_manager::User* user =
394 user_manager::UserManager::Get()->GetUsers().at(user_index);
395 LoginUser(user->email());
396 Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
397 shared_settings_adapter_.reset(
398 new SupervisedUsersSharedSettingsSyncTestAdapter(profile));
399 supervised_users_adapter_.reset(new SupervisedUsersSyncTestAdapter(profile));
402 void SupervisedUserTestBase::RemoveSupervisedUser(
403 size_t original_user_count,
404 int user_index,
405 const std::string& expected_display_name) {
406 // Remove supervised user.
407 ASSERT_EQ(original_user_count,
408 user_manager::UserManager::Get()->GetUsers().size());
410 // Created supervised user have to be first in a list.
411 const user_manager::User* user =
412 user_manager::UserManager::Get()->GetUsers().at(user_index);
413 ASSERT_EQ(base::UTF8ToUTF16(expected_display_name), user->display_name());
415 // Open pod menu.
416 JSExpect(
417 StringPrintf("!$('pod-row').pods[%d].isActionBoxMenuActive", user_index));
418 JSEval(StringPrintf(
419 "$('pod-row').pods[%d].querySelector('.action-box-button').click()",
420 user_index));
421 JSExpect(
422 StringPrintf("$('pod-row').pods[%d].isActionBoxMenuActive", user_index));
424 // Select "Remove user" element.
425 JSExpect(StringPrintf(
426 "$('pod-row').pods[%d].actionBoxRemoveUserWarningElement.hidden",
427 user_index));
428 JSEval(StringPrintf(
429 "$('pod-row').pods[%d].querySelector('.action-box-menu-remove').click()",
430 user_index));
431 JSExpect(StringPrintf(
432 "!$('pod-row').pods[%d].actionBoxRemoveUserWarningElement.hidden",
433 user_index));
435 EXPECT_CALL(*mock_async_method_caller_, AsyncRemove(_, _)).Times(1);
437 // Confirm deletion.
438 JSEval(StringPrintf(
439 "$('pod-row').pods[%d].querySelector('.remove-warning-button').click()",
440 user_index));
442 // Make sure there is no supervised user in list.
443 ASSERT_EQ(original_user_count - 1,
444 user_manager::UserManager::Get()->GetUsers().size());
447 } // namespace chromeos