blob: 357bfcef08d89a7f3eea8665794b7f42f896b133 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/signin/signin_supervised_user_import_handler.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/signin/fake_signin_manager_builder.h"
#include "chrome/browser/signin/signin_error_controller_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/supervised_user/legacy/supervised_user_sync_service.h"
#include "chrome/browser/supervised_user/legacy/supervised_user_sync_service_factory.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/signin/core/browser/fake_auth_status_provider.h"
#include "components/syncable_prefs/pref_service_syncable.h"
#include "content/public/test/test_web_ui.h"
#include "sync/api/attachments/attachment_id.h"
#include "sync/api/fake_sync_change_processor.h"
#include "sync/api/sync_error_factory_mock.h"
#include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
#include "sync/protocol/sync.pb.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
const char kTestGaiaId[] = "test-gaia-id";
const char kTestEmail[] = "foo@bar.com";
const char kTestWebUIResponse[] = "cr.webUIResponse";
const char kTestCallbackId[] = "test-callback-id";
const char kSupervisedUserId[] = "test-supervised-id";
const char kSupervisedUsername[] = "test-supervised-username";
const char kSupervisedUserAvatarName[] = "chrome-avatar-index:0";
const char kSupervisedUserAvatarUrl[] = "chrome://theme/IDR_PROFILE_AVATAR_0";
syncer::SyncData CreateSyncData(const std::string& id,
const std::string& name,
const std::string& chrome_avatar) {
sync_pb::EntitySpecifics specifics;
specifics.mutable_managed_user()->set_id(id);
specifics.mutable_managed_user()->set_name(name);
specifics.mutable_managed_user()->set_acknowledged(true);
specifics.mutable_managed_user()->set_chrome_avatar(chrome_avatar);
return syncer::SyncData::CreateRemoteData(
1,
specifics,
base::Time(),
syncer::AttachmentIdList(),
syncer::AttachmentServiceProxyForTest::Create());
}
} // namespace
class TestSigninSupervisedUserImportHandler :
public SigninSupervisedUserImportHandler {
public:
explicit TestSigninSupervisedUserImportHandler(content::WebUI* web_ui) {
set_web_ui(web_ui);
}
};
class SigninSupervisedUserImportHandlerTest : public BrowserWithTestWindowTest {
public:
SigninSupervisedUserImportHandlerTest() : web_ui_(new content::TestWebUI) {}
void SetUp() override {
BrowserWithTestWindowTest::SetUp();
handler_.reset(new TestSigninSupervisedUserImportHandler(web_ui()));
// Build a test profile.
profile_manager_.reset(
new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
ASSERT_TRUE(profile_manager_->SetUp());
TestingProfile::TestingFactories factories;
factories.push_back(std::make_pair(SigninManagerFactory::GetInstance(),
BuildFakeSigninManagerBase));
profile_ = profile_manager_.get()->CreateTestingProfile(
"test-profile",
std::unique_ptr<syncable_prefs::PrefServiceSyncable>(),
base::UTF8ToUTF16("test-profile"),
0,
std::string(),
factories);
// Authenticate the test profile.
fake_signin_manager_ = static_cast<FakeSigninManagerForTesting*>(
SigninManagerFactory::GetForProfile(profile_));
fake_signin_manager_->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
// Add supervised users to the profile.
SupervisedUserSyncService* sync_service_ =
SupervisedUserSyncServiceFactory::GetForProfile(profile_);
syncer::SyncDataList sync_data;
sync_data.push_back(CreateSyncData(kSupervisedUserId,
kSupervisedUsername,
kSupervisedUserAvatarName));
syncer::SyncMergeResult result = sync_service_->MergeDataAndStartSyncing(
syncer::SUPERVISED_USERS,
sync_data,
std::unique_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor()),
std::unique_ptr<syncer::SyncErrorFactory>(
new syncer::SyncErrorFactoryMock()));
EXPECT_FALSE(result.error().IsSet());
EXPECT_EQ(1u, sync_service_->GetSupervisedUsers()->size());
}
void TearDown() override {
profile_manager_.reset();
handler_.reset();
web_ui_.reset();
BrowserWithTestWindowTest::TearDown();
}
content::TestWebUI* web_ui() {
return web_ui_.get();
}
TestSigninSupervisedUserImportHandler* handler() {
return handler_.get();
}
TestingProfileManager* profile_manager() {
return profile_manager_.get();
}
TestingProfile* profile() {
return profile_;
}
FakeSigninManagerForTesting* signin_manager() {
return fake_signin_manager_;
}
void VerifyResponse(size_t expected_total_calls,
const std::string& expected_callback_id,
bool expected_fulfilled) {
EXPECT_EQ(expected_total_calls, web_ui()->call_data().size());
EXPECT_EQ(kTestWebUIResponse, web_ui()->call_data()[0]->function_name());
std::string callback_id;
ASSERT_TRUE(web_ui()->call_data()[0]->arg1()->GetAsString(&callback_id));
EXPECT_EQ(expected_callback_id, callback_id);
bool fulfilled;
ASSERT_TRUE(web_ui()->call_data()[0]->arg2()->GetAsBoolean(&fulfilled));
EXPECT_EQ(expected_fulfilled, fulfilled);
}
private:
std::unique_ptr<content::TestWebUI> web_ui_;
std::unique_ptr<TestSigninSupervisedUserImportHandler> handler_;
std::unique_ptr<TestingProfileManager> profile_manager_;
TestingProfile* profile_;
FakeSigninManagerForTesting* fake_signin_manager_;
};
TEST_F(SigninSupervisedUserImportHandlerTest, NotAuthenticated) {
// Stop Sync before signing out.
SupervisedUserSyncService* sync_service_ =
SupervisedUserSyncServiceFactory::GetForProfile(profile());
sync_service_->StopSyncing(syncer::SUPERVISED_USERS);
// Sign out the user.
signin_manager()->ForceSignOut();
// Test the JS -> C++ -> JS callback path.
base::ListValue list_args;
list_args.AppendString(kTestCallbackId);
list_args.AppendString(profile()->GetPath().AsUTF16Unsafe());
handler()->GetExistingSupervisedUsers(&list_args);
// Expect an error response.
VerifyResponse(1U, kTestCallbackId, false);
base::string16 expected_error_message = l10n_util::GetStringUTF16(
IDS_PROFILES_CREATE_CUSTODIAN_ACCOUNT_DETAILS_OUT_OF_DATE_ERROR);
base::string16 error_message;
ASSERT_TRUE(web_ui()->call_data()[0]->arg3()->GetAsString(&error_message));
EXPECT_EQ(expected_error_message, error_message);
}
TEST_F(SigninSupervisedUserImportHandlerTest, AuthError) {
// Set Auth Error.
const GoogleServiceAuthError error(
GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
FakeAuthStatusProvider provider(
SigninErrorControllerFactory::GetForProfile(profile()));
provider.SetAuthError(kTestGaiaId, error);
// Test the JS -> C++ -> JS callback path.
base::ListValue list_args;
list_args.AppendString(kTestCallbackId);
list_args.AppendString(profile()->GetPath().AsUTF16Unsafe());
handler()->GetExistingSupervisedUsers(&list_args);
// Expect an error response.
VerifyResponse(1U, kTestCallbackId, false);
base::string16 expected_error_message = l10n_util::GetStringUTF16(
IDS_PROFILES_CREATE_CUSTODIAN_ACCOUNT_DETAILS_OUT_OF_DATE_ERROR);
base::string16 error_message;
ASSERT_TRUE(web_ui()->call_data()[0]->arg3()->GetAsString(&error_message));
EXPECT_EQ(expected_error_message, error_message);
}
TEST_F(SigninSupervisedUserImportHandlerTest, CustodianIsSupervised) {
// Build a supervised test profile.
TestingProfile* profile_ = profile_manager()->CreateTestingProfile(
"supervised-test-profile",
std::unique_ptr<syncable_prefs::PrefServiceSyncable>(),
base::UTF8ToUTF16("supervised-test-profile"),
0,
"12345", // supervised_user_id
TestingProfile::TestingFactories());
// Test the JS -> C++ -> JS callback path.
base::ListValue list_args;
list_args.AppendString(kTestCallbackId);
list_args.AppendString(profile_->GetPath().AsUTF16Unsafe());
handler()->GetExistingSupervisedUsers(&list_args);
// Expect to do nothing.
EXPECT_EQ(0U, web_ui()->call_data().size());
}
TEST_F(SigninSupervisedUserImportHandlerTest, SendExistingSupervisedUsers) {
// Test the JS -> C++ -> JS callback path.
base::ListValue list_args;
list_args.AppendString(kTestCallbackId);
list_args.AppendString(profile()->GetPath().AsUTF16Unsafe());
handler()->GetExistingSupervisedUsers(&list_args);
// Expect a success response.
VerifyResponse(1U, kTestCallbackId, true);
const base::ListValue* supervised_users;
ASSERT_TRUE(web_ui()->call_data()[0]->arg3()->GetAsList(&supervised_users));
EXPECT_EQ(1U, supervised_users->GetSize());
const base::DictionaryValue* supervised_user;
ASSERT_TRUE(supervised_users->GetDictionary(0, &supervised_user));
std::string id;
ASSERT_TRUE(supervised_user->GetString("id", &id));
EXPECT_EQ(kSupervisedUserId, id);
std::string name;
ASSERT_TRUE(supervised_user->GetString("name", &name));
EXPECT_EQ(kSupervisedUsername, name);
std::string iconURL;
ASSERT_TRUE(supervised_user->GetString("iconURL", &iconURL));
EXPECT_EQ(kSupervisedUserAvatarUrl, iconURL);
bool onCurrentDevice;
ASSERT_TRUE(supervised_user->GetBoolean("onCurrentDevice", &onCurrentDevice));
ASSERT_FALSE(onCurrentDevice);
}