1 // Copyright 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/command_line.h"
9 #include "base/compiler_specific.h"
10 #include "base/run_loop.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/threading/sequenced_worker_pool.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
15 #include "chrome/browser/chromeos/login/login_manager_test.h"
16 #include "chrome/browser/chromeos/login/startup_utils.h"
17 #include "chrome/browser/chromeos/login/webui_login_view.h"
18 #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h"
19 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
20 #include "chrome/browser/managed_mode/managed_user_registration_utility.h"
21 #include "chrome/browser/managed_mode/managed_user_registration_utility_stub.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "chromeos/cryptohome/mock_async_method_caller.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/test/browser_test_utils.h"
26 #include "content/public/test/test_utils.h"
34 const char kStubEthernetServicePath[] = "eth0";
36 const char kTestManager[] = "test-manager@gmail.com";
37 const char kTestOtherUser[] = "test-user@gmail.com";
39 const char kTestManagerPassword[] = "password";
40 const char kSupervisedUserDisplayName[] = "John Doe";
41 const char kSupervisedUserPassword[] = "simplepassword";
45 class SupervisedUserTest : public chromeos::LoginManagerTest {
47 SupervisedUserTest() : LoginManagerTest(true),
48 mock_async_method_caller_(NULL),
49 network_portal_detector_(NULL),
50 registration_utility_stub_(NULL) {
53 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
54 LoginManagerTest::SetUpCommandLine(command_line);
55 command_line->AppendSwitch(::switches::kEnableManagedUsers);
58 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
59 LoginManagerTest::SetUpInProcessBrowserTestFixture();
60 mock_async_method_caller_ = new cryptohome::MockAsyncMethodCaller;
61 mock_async_method_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
62 cryptohome::AsyncMethodCaller::InitializeForTesting(
63 mock_async_method_caller_);
65 registration_utility_stub_ = new ManagedUserRegistrationUtilityStub();
66 scoped_utility_.reset(
67 new ScopedTestingManagedUserRegistrationUtility(
68 registration_utility_stub_));
70 // Setup network portal detector to return online state for both
71 // ethernet and wifi networks. Ethernet is an active network by
73 network_portal_detector_ = new NetworkPortalDetectorTestImpl();
74 NetworkPortalDetector::InitializeForTesting(network_portal_detector_);
75 NetworkPortalDetector::CaptivePortalState online_state;
76 online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE;
77 online_state.response_code = 204;
78 network_portal_detector_->SetDefaultNetworkPathForTesting(
79 kStubEthernetServicePath);
80 network_portal_detector_->SetDetectionResultsForTesting(
81 kStubEthernetServicePath, online_state);
84 virtual void CleanUpOnMainThread() OVERRIDE {
85 LoginManagerTest::CleanUpOnMainThread();
86 scoped_utility_.reset(NULL);
89 virtual void TearDown() OVERRIDE {
90 cryptohome::AsyncMethodCaller::Shutdown();
91 mock_async_method_caller_ = NULL;
92 LoginManagerTest::TearDown();
95 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
96 NetworkPortalDetector::Shutdown();
99 void JSEval(const std::string& script) {
100 EXPECT_TRUE(content::ExecuteScript(web_contents(), script));
103 void JSExpectAsync(const std::string& function) {
105 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
107 "(" + function + ")(function() {"
108 " window.domAutomationController.send(true);"
114 void JSSetTextField(const std::string& element_selector,
115 const std::string& value) {
116 std::string function;
117 function.append("document.querySelector('");
118 function.append(element_selector);
119 function.append("').value = '");
120 function.append(value);
121 function.append("'");
126 void CreateSupervisedUser();
127 void SigninAsSupervisedUser();
128 void RemoveSupervisedUser();
131 cryptohome::MockAsyncMethodCaller* mock_async_method_caller_;
132 NetworkPortalDetectorTestImpl* network_portal_detector_;
133 ManagedUserRegistrationUtilityStub* registration_utility_stub_;
134 scoped_ptr<ScopedTestingManagedUserRegistrationUtility> scoped_utility_;
137 DISALLOW_COPY_AND_ASSIGN(SupervisedUserTest);
140 void SupervisedUserTest::PrepareUsers() {
141 RegisterUser(kTestManager);
142 RegisterUser(kTestOtherUser);
143 chromeos::StartupUtils::MarkOobeCompleted();
146 void SupervisedUserTest::CreateSupervisedUser() {
147 // Create supervised user.
149 // Navigate to supervised user creation screen.
150 JSEval("chrome.send('showLocallyManagedUserCreationScreen')");
152 // Read intro and proceed.
153 JSExpect("$('managed-user-creation').currentPage_ == 'intro'");
155 JSEval("$('managed-user-creation-start-button').click()");
157 // Check that both users appear as managers, and test-manager@gmail.com is
158 // the first one. As no manager is selected, 'next' button is disabled
159 JSExpect("$('managed-user-creation').currentPage_ == 'manager'");
161 JSExpect(std::string("document.querySelectorAll(")
162 .append("'#managed-user-creation-managers-pane .manager-pod.focused')")
163 .append(".length == 0"));
164 JSExpect("$('managed-user-creation-next-button').disabled");
166 JSExpect("$('managed-user-creation').managerList_.pods.length == 2");
167 JSExpect(std::string("document.querySelectorAll(")
168 .append("'#managed-user-creation-managers-pane .manager-pod')")
169 .append(".length == 2"));
170 JSExpect(std::string("document.querySelectorAll(")
171 .append("'#managed-user-creation-managers-pane .manager-pod')")
172 .append("[0].user.emailAddress == '").append(kTestManager).append("'"));
173 // Select the first user as manager, and enter password.
174 JSEval(std::string("supervisedUserManagerPod = ")
175 .append("$('managed-user-creation').managerList_.pods[0]"));
176 JSEval(std::string("$('managed-user-creation').managerList_")
177 .append(".selectPod(supervisedUserManagerPod)"));
178 JSExpect("$('managed-user-creation-next-button').disabled");
180 "#managed-user-creation .manager-pod.focused input",
181 kTestManagerPassword);
183 JSEval("$('managed-user-creation').updateNextButtonForManager_()");
185 // Next button is now enabled.
186 JSExpect("!$('managed-user-creation-next-button').disabled");
187 SetExpectedCredentials(kTestManager, kTestManagerPassword);
188 content::WindowedNotificationObserver login_observer(
189 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
190 content::NotificationService::AllSources());
191 // Log in as manager.
192 JSEval("$('managed-user-creation-next-button').click()");
193 login_observer.Wait();
194 // OAuth token is valid.
196 SaveUserOAuthStatus(kTestManager, User::OAUTH2_TOKEN_STATUS_VALID);
197 base::RunLoop().RunUntilIdle();
198 // Enter managed user details.
199 JSExpect("$('managed-user-creation').currentPage_ == 'username'");
201 JSExpect("$('managed-user-creation-next-button').disabled");
203 "#managed-user-creation-name",
204 kSupervisedUserDisplayName);
205 JSEval("$('managed-user-creation').checkUserName_()");
207 base::RunLoop().RunUntilIdle();
210 "#managed-user-creation-password",
211 kSupervisedUserPassword);
213 "#managed-user-creation-password-confirm",
214 kSupervisedUserPassword);
216 JSEval("$('managed-user-creation').updateNextButtonForUser_()");
217 JSExpect("!$('managed-user-creation-next-button').disabled");
219 EXPECT_CALL(*mock_async_method_caller_, AsyncMount(_, _, _, _))
221 EXPECT_CALL(*mock_async_method_caller_, AsyncGetSanitizedUsername(_, _))
223 EXPECT_CALL(*mock_async_method_caller_, AsyncAddKey(_, _, _, _))
226 JSEval("$('managed-user-creation-next-button').click()");
228 testing::Mock::VerifyAndClearExpectations(mock_async_method_caller_);
230 EXPECT_TRUE(registration_utility_stub_->register_was_called());
231 EXPECT_EQ(registration_utility_stub_->display_name(),
232 UTF8ToUTF16(kSupervisedUserDisplayName));
234 registration_utility_stub_->RunSuccessCallback("token");
236 // Token writing moves control to BlockingPool and back.
237 base::RunLoop().RunUntilIdle();
238 content::BrowserThread::GetBlockingPool()->FlushForTesting();
239 base::RunLoop().RunUntilIdle();
241 JSExpect("$('managed-user-creation').currentPage_ == 'created'");
242 JSEval("$('managed-user-creation-gotit-button').click()");
245 void SupervisedUserTest::SigninAsSupervisedUser() {
246 // Log in as supervised user, make sure that everything works.
247 ASSERT_EQ(3UL, UserManager::Get()->GetUsers().size());
248 // Created supervised user have to be first in a list.
249 const User* user = UserManager::Get()->GetUsers().at(0);
250 ASSERT_EQ(UTF8ToUTF16(kSupervisedUserDisplayName), user->display_name());
251 LoginUser(user->email());
254 void SupervisedUserTest::RemoveSupervisedUser() {
255 // Remove supervised user.
257 ASSERT_EQ(3UL, UserManager::Get()->GetUsers().size());
258 // Created supervised user have to be first in a list.
259 const User* user = UserManager::Get()->GetUsers().at(0);
260 ASSERT_EQ(UTF8ToUTF16(kSupervisedUserDisplayName), user->display_name());
263 JSExpect("!$('pod-row').pods[0].isActionBoxMenuActive");
264 JSEval("$('pod-row').pods[0].querySelector('.action-box-button').click()");
265 JSExpect("$('pod-row').pods[0].isActionBoxMenuActive");
267 // Select "Remove user" element.
268 JSExpect("$('pod-row').pods[0].actionBoxRemoveUserWarningElement.hidden");
269 JSEval(std::string("$('pod-row').pods[0].")
270 .append("querySelector('.action-box-menu-remove').click()"));
271 JSExpect("!$('pod-row').pods[0].actionBoxRemoveUserWarningElement.hidden");
273 EXPECT_CALL(*mock_async_method_caller_, AsyncRemove(_, _)).Times(1);
276 JSEval(std::string("$('pod-row').pods[0].")
277 .append("querySelector('.remove-warning-button').click()"));
279 // Make sure there is no supervised user in list.
280 ASSERT_EQ(2UL, UserManager::Get()->GetUsers().size());
283 class SupervisedUserCreationTest : public SupervisedUserTest {
285 SupervisedUserCreationTest() : SupervisedUserTest() {}
287 DISALLOW_COPY_AND_ASSIGN(SupervisedUserCreationTest);
290 class SupervisedUserOwnerCreationTest : public SupervisedUserTest {
292 SupervisedUserOwnerCreationTest() : SupervisedUserTest() {}
294 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
295 SupervisedUserTest::SetUpInProcessBrowserTestFixture();
296 cros_settings_provider_.reset(new StubCrosSettingsProvider());
297 cros_settings_provider_->Set(kDeviceOwner, base::StringValue(kTestManager));
300 scoped_ptr<StubCrosSettingsProvider> cros_settings_provider_;
301 DISALLOW_COPY_AND_ASSIGN(SupervisedUserOwnerCreationTest);
304 IN_PROC_BROWSER_TEST_F(SupervisedUserCreationTest,
305 PRE_PRE_PRE_CreateAndRemoveSupervisedUser) {
309 IN_PROC_BROWSER_TEST_F(SupervisedUserCreationTest,
310 PRE_PRE_CreateAndRemoveSupervisedUser) {
311 CreateSupervisedUser();
314 IN_PROC_BROWSER_TEST_F(SupervisedUserCreationTest,
315 PRE_CreateAndRemoveSupervisedUser) {
316 SigninAsSupervisedUser();
319 IN_PROC_BROWSER_TEST_F(SupervisedUserCreationTest,
320 CreateAndRemoveSupervisedUser) {
321 RemoveSupervisedUser();
324 IN_PROC_BROWSER_TEST_F(SupervisedUserOwnerCreationTest,
325 PRE_PRE_PRE_CreateAndRemoveSupervisedUser) {
329 IN_PROC_BROWSER_TEST_F(SupervisedUserOwnerCreationTest,
330 PRE_PRE_CreateAndRemoveSupervisedUser) {
331 CreateSupervisedUser();
334 IN_PROC_BROWSER_TEST_F(SupervisedUserOwnerCreationTest,
335 PRE_CreateAndRemoveSupervisedUser) {
336 SigninAsSupervisedUser();
339 IN_PROC_BROWSER_TEST_F(SupervisedUserOwnerCreationTest,
340 CreateAndRemoveSupervisedUser) {
341 RemoveSupervisedUser();
344 } // namespace chromeos