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/compiler_specific.h"
9 #include "base/run_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/threading/sequenced_worker_pool.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
14 #include "chrome/browser/chromeos/login/login_manager_test.h"
15 #include "chrome/browser/chromeos/login/startup_utils.h"
16 #include "chrome/browser/chromeos/login/webui_login_view.h"
17 #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h"
18 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
19 #include "chrome/browser/managed_mode/managed_user_registration_utility.h"
20 #include "chrome/browser/managed_mode/managed_user_registration_utility_stub.h"
21 #include "chromeos/cryptohome/mock_async_method_caller.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/test/browser_test_utils.h"
24 #include "content/public/test/test_utils.h"
32 const char kStubEthernetServicePath
[] = "eth0";
34 const char kTestManager
[] = "test-manager@gmail.com";
35 const char kTestOtherUser
[] = "test-user@gmail.com";
37 const char kTestManagerPassword
[] = "password";
38 const char kSupervisedUserDisplayName
[] = "John Doe";
39 const char kSupervisedUserPassword
[] = "simplepassword";
43 class SupervisedUserTest
: public chromeos::LoginManagerTest
{
45 SupervisedUserTest() : LoginManagerTest(true),
46 mock_async_method_caller_(NULL
),
47 network_portal_detector_(NULL
),
48 registration_utility_stub_(NULL
) {
51 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE
{
52 LoginManagerTest::SetUpInProcessBrowserTestFixture();
53 mock_async_method_caller_
= new cryptohome::MockAsyncMethodCaller
;
54 mock_async_method_caller_
->SetUp(true, cryptohome::MOUNT_ERROR_NONE
);
55 cryptohome::AsyncMethodCaller::InitializeForTesting(
56 mock_async_method_caller_
);
58 registration_utility_stub_
= new ManagedUserRegistrationUtilityStub();
59 scoped_utility_
.reset(
60 new ScopedTestingManagedUserRegistrationUtility(
61 registration_utility_stub_
));
63 // Setup network portal detector to return online state for both
64 // ethernet and wifi networks. Ethernet is an active network by
66 network_portal_detector_
= new NetworkPortalDetectorTestImpl();
67 NetworkPortalDetector::InitializeForTesting(network_portal_detector_
);
68 NetworkPortalDetector::CaptivePortalState online_state
;
69 online_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
;
70 online_state
.response_code
= 204;
71 network_portal_detector_
->SetDefaultNetworkPathForTesting(
72 kStubEthernetServicePath
);
73 network_portal_detector_
->SetDetectionResultsForTesting(
74 kStubEthernetServicePath
, online_state
);
77 virtual void CleanUpOnMainThread() OVERRIDE
{
78 LoginManagerTest::CleanUpOnMainThread();
79 scoped_utility_
.reset(NULL
);
82 virtual void TearDown() OVERRIDE
{
83 cryptohome::AsyncMethodCaller::Shutdown();
84 mock_async_method_caller_
= NULL
;
85 LoginManagerTest::TearDown();
88 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE
{
89 NetworkPortalDetector::Shutdown();
92 void JSEval(const std::string
& script
) {
93 EXPECT_TRUE(content::ExecuteScript(web_contents(), script
));
96 void JSExpectAsync(const std::string
& function
) {
98 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
100 "(" + function
+ ")(function() {"
101 " window.domAutomationController.send(true);"
107 void JSSetTextField(const std::string
& element_selector
,
108 const std::string
& value
) {
109 std::string function
;
110 function
.append("document.querySelector('");
111 function
.append(element_selector
);
112 function
.append("').value = '");
113 function
.append(value
);
114 function
.append("'");
119 void CreateSupervisedUser();
120 void SigninAsSupervisedUser();
121 void RemoveSupervisedUser();
122 void LogInAsManagerAndFillUserData();
125 cryptohome::MockAsyncMethodCaller
* mock_async_method_caller_
;
126 NetworkPortalDetectorTestImpl
* network_portal_detector_
;
127 ManagedUserRegistrationUtilityStub
* registration_utility_stub_
;
128 scoped_ptr
<ScopedTestingManagedUserRegistrationUtility
> scoped_utility_
;
131 DISALLOW_COPY_AND_ASSIGN(SupervisedUserTest
);
134 void SupervisedUserTest::PrepareUsers() {
135 RegisterUser(kTestManager
);
136 RegisterUser(kTestOtherUser
);
137 chromeos::StartupUtils::MarkOobeCompleted();
140 void SupervisedUserTest::LogInAsManagerAndFillUserData() {
141 // Create supervised user.
143 // Navigate to supervised user creation screen.
144 JSEval("chrome.send('showLocallyManagedUserCreationScreen')");
146 // Read intro and proceed.
147 JSExpect("$('managed-user-creation').currentPage_ == 'intro'");
149 JSEval("$('managed-user-creation-start-button').click()");
151 // Check that both users appear as managers, and test-manager@gmail.com is
153 JSExpect("$('managed-user-creation').currentPage_ == 'manager'");
155 JSExpect(std::string("document.querySelectorAll(")
156 .append("'#managed-user-creation-managers-pane .manager-pod.focused')")
157 .append(".length == 1"));
159 JSExpect("$('managed-user-creation').managerList_.pods.length == 2");
160 JSExpect(std::string("document.querySelectorAll(")
161 .append("'#managed-user-creation-managers-pane .manager-pod')")
162 .append(".length == 2"));
163 JSExpect(std::string("document.querySelectorAll(")
164 .append("'#managed-user-creation-managers-pane .manager-pod')")
165 .append("[0].user.emailAddress == '").append(kTestManager
).append("'"));
166 // Select the first user as manager, and enter password.
167 JSExpect("$('managed-user-creation-next-button').disabled");
169 "#managed-user-creation .manager-pod.focused input",
170 kTestManagerPassword
);
172 JSEval("$('managed-user-creation').updateNextButtonForManager_()");
174 // Next button is now enabled.
175 JSExpect("!$('managed-user-creation-next-button').disabled");
176 SetExpectedCredentials(kTestManager
, kTestManagerPassword
);
177 content::WindowedNotificationObserver
login_observer(
178 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
,
179 content::NotificationService::AllSources());
180 // Log in as manager.
181 JSEval("$('managed-user-creation-next-button').click()");
182 login_observer
.Wait();
183 // OAuth token is valid.
185 SaveUserOAuthStatus(kTestManager
, User::OAUTH2_TOKEN_STATUS_VALID
);
186 base::RunLoop().RunUntilIdle();
187 // Enter managed user details.
188 JSExpect("$('managed-user-creation').currentPage_ == 'username'");
190 JSExpect("$('managed-user-creation-next-button').disabled");
192 "#managed-user-creation-name",
193 kSupervisedUserDisplayName
);
194 JSEval("$('managed-user-creation').checkUserName_()");
196 base::RunLoop().RunUntilIdle();
199 "#managed-user-creation-password",
200 kSupervisedUserPassword
);
202 "#managed-user-creation-password-confirm",
203 kSupervisedUserPassword
);
205 JSEval("$('managed-user-creation').updateNextButtonForUser_()");
206 JSExpect("!$('managed-user-creation-next-button').disabled");
209 void SupervisedUserTest::CreateSupervisedUser() {
210 LogInAsManagerAndFillUserData();
212 EXPECT_CALL(*mock_async_method_caller_
, AsyncMount(_
, _
, _
, _
))
214 EXPECT_CALL(*mock_async_method_caller_
, AsyncGetSanitizedUsername(_
, _
))
216 EXPECT_CALL(*mock_async_method_caller_
, AsyncAddKey(_
, _
, _
, _
))
219 JSEval("$('managed-user-creation-next-button').click()");
221 testing::Mock::VerifyAndClearExpectations(mock_async_method_caller_
);
223 EXPECT_TRUE(registration_utility_stub_
->register_was_called());
224 EXPECT_EQ(registration_utility_stub_
->display_name(),
225 base::UTF8ToUTF16(kSupervisedUserDisplayName
));
227 registration_utility_stub_
->RunSuccessCallback("token");
229 // Token writing moves control to BlockingPool and back.
230 base::RunLoop().RunUntilIdle();
231 content::BrowserThread::GetBlockingPool()->FlushForTesting();
232 base::RunLoop().RunUntilIdle();
234 JSExpect("$('managed-user-creation').currentPage_ == 'created'");
235 JSEval("$('managed-user-creation-gotit-button').click()");
238 void SupervisedUserTest::SigninAsSupervisedUser() {
239 // Log in as supervised user, make sure that everything works.
240 ASSERT_EQ(3UL, UserManager::Get()->GetUsers().size());
241 // Created supervised user have to be first in a list.
242 const User
* user
= UserManager::Get()->GetUsers().at(0);
243 ASSERT_EQ(base::UTF8ToUTF16(kSupervisedUserDisplayName
),
244 user
->display_name());
245 LoginUser(user
->email());
248 void SupervisedUserTest::RemoveSupervisedUser() {
249 // Remove supervised user.
251 ASSERT_EQ(3UL, UserManager::Get()->GetUsers().size());
252 // Created supervised user have to be first in a list.
253 const User
* user
= UserManager::Get()->GetUsers().at(0);
254 ASSERT_EQ(base::UTF8ToUTF16(kSupervisedUserDisplayName
),
255 user
->display_name());
258 JSExpect("!$('pod-row').pods[0].isActionBoxMenuActive");
259 JSEval("$('pod-row').pods[0].querySelector('.action-box-button').click()");
260 JSExpect("$('pod-row').pods[0].isActionBoxMenuActive");
262 // Select "Remove user" element.
263 JSExpect("$('pod-row').pods[0].actionBoxRemoveUserWarningElement.hidden");
264 JSEval(std::string("$('pod-row').pods[0].")
265 .append("querySelector('.action-box-menu-remove').click()"));
266 JSExpect("!$('pod-row').pods[0].actionBoxRemoveUserWarningElement.hidden");
268 EXPECT_CALL(*mock_async_method_caller_
, AsyncRemove(_
, _
)).Times(1);
271 JSEval(std::string("$('pod-row').pods[0].")
272 .append("querySelector('.remove-warning-button').click()"));
274 // Make sure there is no supervised user in list.
275 ASSERT_EQ(2UL, UserManager::Get()->GetUsers().size());
278 class SupervisedUserCreationTest
: public SupervisedUserTest
{
280 SupervisedUserCreationTest() : SupervisedUserTest() {}
283 DISALLOW_COPY_AND_ASSIGN(SupervisedUserCreationTest
);
286 class SupervisedUserTransactionCleanupTest
: public SupervisedUserTest
{
288 SupervisedUserTransactionCleanupTest() : SupervisedUserTest () {}
291 DISALLOW_COPY_AND_ASSIGN(SupervisedUserTransactionCleanupTest
);
294 class SupervisedUserOwnerCreationTest
: public SupervisedUserTest
{
296 SupervisedUserOwnerCreationTest() : SupervisedUserTest() {}
298 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE
{
299 SupervisedUserTest::SetUpInProcessBrowserTestFixture();
300 cros_settings_provider_
.reset(new StubCrosSettingsProvider());
301 cros_settings_provider_
->Set(kDeviceOwner
, base::StringValue(kTestManager
));
305 scoped_ptr
<StubCrosSettingsProvider
> cros_settings_provider_
;
306 DISALLOW_COPY_AND_ASSIGN(SupervisedUserOwnerCreationTest
);
309 IN_PROC_BROWSER_TEST_F(SupervisedUserCreationTest
,
310 PRE_PRE_PRE_CreateAndRemoveSupervisedUser
) {
314 IN_PROC_BROWSER_TEST_F(SupervisedUserCreationTest
,
315 PRE_PRE_CreateAndRemoveSupervisedUser
) {
316 CreateSupervisedUser();
319 IN_PROC_BROWSER_TEST_F(SupervisedUserCreationTest
,
320 PRE_CreateAndRemoveSupervisedUser
) {
321 SigninAsSupervisedUser();
324 IN_PROC_BROWSER_TEST_F(SupervisedUserCreationTest
,
325 CreateAndRemoveSupervisedUser
) {
326 RemoveSupervisedUser();
329 IN_PROC_BROWSER_TEST_F(SupervisedUserOwnerCreationTest
,
330 PRE_PRE_PRE_CreateAndRemoveSupervisedUser
) {
334 IN_PROC_BROWSER_TEST_F(SupervisedUserOwnerCreationTest
,
335 PRE_PRE_CreateAndRemoveSupervisedUser
) {
336 CreateSupervisedUser();
339 IN_PROC_BROWSER_TEST_F(SupervisedUserOwnerCreationTest
,
340 PRE_CreateAndRemoveSupervisedUser
) {
341 SigninAsSupervisedUser();
344 IN_PROC_BROWSER_TEST_F(SupervisedUserOwnerCreationTest
,
345 CreateAndRemoveSupervisedUser
) {
346 RemoveSupervisedUser();
349 IN_PROC_BROWSER_TEST_F(SupervisedUserTransactionCleanupTest
,
350 PRE_PRE_CreateAndCancelSupervisedUser
) {
354 IN_PROC_BROWSER_TEST_F(SupervisedUserTransactionCleanupTest
,
355 PRE_CreateAndCancelSupervisedUser
) {
356 LogInAsManagerAndFillUserData();
358 EXPECT_CALL(*mock_async_method_caller_
, AsyncMount(_
, _
, _
, _
))
360 EXPECT_CALL(*mock_async_method_caller_
, AsyncGetSanitizedUsername(_
, _
))
362 EXPECT_CALL(*mock_async_method_caller_
, AsyncAddKey(_
, _
, _
, _
))
365 JSEval("$('managed-user-creation-next-button').click()");
367 testing::Mock::VerifyAndClearExpectations(mock_async_method_caller_
);
369 EXPECT_TRUE(registration_utility_stub_
->register_was_called());
370 EXPECT_EQ(registration_utility_stub_
->display_name(),
371 base::UTF8ToUTF16(kSupervisedUserDisplayName
));
373 std::string user_id
= registration_utility_stub_
->managed_user_id();
374 // Make sure user is already in list.
375 ASSERT_EQ(3UL, UserManager::Get()->GetUsers().size());
376 // We wait for token now. Press cancel button at this point.
377 JSEval("$('cancel-add-user-button').click()");
380 IN_PROC_BROWSER_TEST_F(SupervisedUserTransactionCleanupTest
,
381 CreateAndCancelSupervisedUser
) {
382 // Make sure there is no supervised user in list.
383 ASSERT_EQ(2UL, UserManager::Get()->GetUsers().size());
386 } // namespace chromeos