#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/pref_service.h"
#include "base/prefs/testing_pref_service.h"
+#include "base/run_loop.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/login/users/mock_user_manager.h"
+#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h"
+#include "chrome/browser/chromeos/policy/device_policy_builder.h"
+#include "chrome/browser/chromeos/policy/enrollment_status_chromeos.h"
+#include "chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.h"
+#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
+#include "chrome/browser/notifications/notification_ui_manager.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
+#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/common/pref_names.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/scoped_testing_local_state.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 "chromeos/dbus/cryptohome/rpc.pb.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/mock_cryptohome_client.h"
+#include "components/signin/core/browser/profile_oauth2_token_service.h"
+#include "components/signin/core/browser/signin_manager_base.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+#include "policy/proto/device_management_backend.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::Invoke;
using testing::NiceMock;
+using testing::Return;
using testing::_;
+namespace em = enterprise_management;
+
namespace {
const char* kAttributeOwnerId = "consumer_management.owner_id";
const char* kTestOwner = "test@chromium.org.test";
namespace policy {
-class ConsumerManagementServiceTest : public testing::Test {
+class ConsumerManagementServiceTest : public BrowserWithTestWindowTest {
public:
ConsumerManagementServiceTest()
- : testing_local_state_(TestingBrowserProcess::GetGlobal()),
- service_(new ConsumerManagementService(&mock_cryptohome_client_)),
- cryptohome_result_(false),
+ : cryptohome_result_(false),
set_owner_status_(false) {
ON_CALL(mock_cryptohome_client_, GetBootAttribute(_, _))
.WillByDefault(
MockFlushAndSignBootAttributes));
}
+ virtual void SetUp() OVERRIDE {
+ BrowserWithTestWindowTest::SetUp();
+
+ testing_profile_manager_.reset(new TestingProfileManager(
+ TestingBrowserProcess::GetGlobal()));
+ ASSERT_TRUE(testing_profile_manager_->SetUp());
+
+ service_.reset(new ConsumerManagementService(&mock_cryptohome_client_,
+ NULL));
+ }
+
+ virtual void TearDown() OVERRIDE {
+ testing_profile_manager_.reset();
+
+ service_.reset();
+
+ BrowserWithTestWindowTest::TearDown();
+ }
+
+ ConsumerManagementService::EnrollmentStage GetEnrollmentStage() {
+ return static_cast<ConsumerManagementService::EnrollmentStage>(
+ g_browser_process->local_state()->GetInteger(
+ prefs::kConsumerManagementEnrollmentStage));
+ }
+
+ void SetEnrollmentStage(ConsumerManagementService::EnrollmentStage stage) {
+ g_browser_process->local_state()->SetInteger(
+ prefs::kConsumerManagementEnrollmentStage, stage);
+ }
+
void MockGetBootAttribute(
const cryptohome::GetBootAttributeRequest& request,
const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) {
set_owner_status_ = status;
}
- ScopedTestingLocalState testing_local_state_;
+ // Variables for building the service.
NiceMock<chromeos::MockCryptohomeClient> mock_cryptohome_client_;
scoped_ptr<ConsumerManagementService> service_;
+ scoped_ptr<TestingProfileManager> testing_profile_manager_;
+
+ // Variables for setting the return value or catching the arguments of mock
+ // functions.
chromeos::DBusMethodCallStatus cryptohome_status_;
bool cryptohome_result_;
cryptohome::BaseReply cryptohome_reply_;
cryptohome::GetBootAttributeRequest get_boot_attribute_request_;
cryptohome::SetBootAttributeRequest set_boot_attribute_request_;
-
std::string owner_;
bool set_owner_status_;
};
-TEST_F(ConsumerManagementServiceTest, CanGetEnrollmentState) {
- EXPECT_EQ(ConsumerManagementService::ENROLLMENT_NONE,
- service_->GetEnrollmentState());
+TEST_F(ConsumerManagementServiceTest, CanGetEnrollmentStage) {
+ EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_NONE,
+ service_->GetEnrollmentStage());
- testing_local_state_.Get()->SetInteger(
- prefs::kConsumerManagementEnrollmentState,
- ConsumerManagementService::ENROLLMENT_ENROLLING);
+ SetEnrollmentStage(ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED);
- EXPECT_EQ(ConsumerManagementService::ENROLLMENT_ENROLLING,
- service_->GetEnrollmentState());
+ EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED,
+ service_->GetEnrollmentStage());
}
-TEST_F(ConsumerManagementServiceTest, CanSetEnrollmentState) {
- EXPECT_EQ(ConsumerManagementService::ENROLLMENT_NONE,
- testing_local_state_.Get()->GetInteger(
- prefs::kConsumerManagementEnrollmentState));
+TEST_F(ConsumerManagementServiceTest, CanSetEnrollmentStage) {
+ EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_NONE,
+ GetEnrollmentStage());
- service_->SetEnrollmentState(ConsumerManagementService::ENROLLMENT_ENROLLING);
+ service_->SetEnrollmentStage(
+ ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED);
- EXPECT_EQ(ConsumerManagementService::ENROLLMENT_ENROLLING,
- testing_local_state_.Get()->GetInteger(
- prefs::kConsumerManagementEnrollmentState));
+ EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED,
+ GetEnrollmentStage());
}
TEST_F(ConsumerManagementServiceTest, CanGetOwner) {
EXPECT_FALSE(set_owner_status_);
}
+class ConsumerManagementServiceEnrollmentTest
+ : public ConsumerManagementServiceTest {
+ public:
+ ConsumerManagementServiceEnrollmentTest()
+ : mock_user_manager_(new NiceMock<chromeos::MockUserManager>()),
+ scoped_user_manager_enabler_(mock_user_manager_),
+ fake_initializer_(new FakeDeviceCloudPolicyInitializer()),
+ enrollment_status_(EnrollmentStatus::ForStatus(
+ EnrollmentStatus::STATUS_SUCCESS)) {
+ // Set up MockUserManager. The first user will be the owner.
+ mock_user_manager_->AddUser(kTestOwner);
+
+ // Return false for IsCurrentUserOwner() so that the enrollment stage is not
+ // reset.
+ ON_CALL(*mock_user_manager_, IsCurrentUserOwner())
+ .WillByDefault(Return(false));
+
+ // Inject FakeDeviceCloudPolicyInitializer.
+ BrowserPolicyConnectorChromeOS* connector =
+ g_browser_process->platform_part()->browser_policy_connector_chromeos();
+ connector->SetDeviceCloudPolicyInitializerForTesting(
+ scoped_ptr<DeviceCloudPolicyInitializer>(fake_initializer_));
+ }
+
+ virtual void SetUp() OVERRIDE {
+ ConsumerManagementServiceTest::SetUp();
+
+ // Set up the testing profile.
+ profile()->set_profile_name(kTestOwner);
+
+ // Set up FakeProfileOAuth2TokenService and issue a fake refresh token.
+ ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
+ profile(), &BuildAutoIssuingFakeProfileOAuth2TokenService);
+ GetFakeProfileOAuth2TokenService()->
+ IssueRefreshTokenForUser(kTestOwner, "fake_token");
+
+ // Set up the authenticated user name and ID.
+ SigninManagerFactory::GetForProfile(profile())->
+ SetAuthenticatedUsername(kTestOwner);
+
+ // The service should continue the enrollment process if the stage is
+ // ENROLLMENT_STAGE_OWNER_STORED.
+ SetEnrollmentStage(
+ ConsumerManagementService::ENROLLMENT_STAGE_OWNER_STORED);
+ }
+
+ virtual void TearDown() OVERRIDE {
+ g_browser_process->notification_ui_manager()->CancelAll();
+
+ ConsumerManagementServiceTest::TearDown();
+ }
+
+ FakeProfileOAuth2TokenService* GetFakeProfileOAuth2TokenService() {
+ return static_cast<FakeProfileOAuth2TokenService*>(
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile()));
+ }
+
+ bool HasEnrollmentNotification() {
+ return g_browser_process->notification_ui_manager()->
+ FindById("consumer_management.enroll");
+ }
+
+ void RunEnrollmentTest() {
+ // Send the profile prepared notification to continue the enrollment.
+ service_->Observe(chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
+ content::Source<void>(NULL), // Not used.
+ content::Details<Profile>(profile()));
+ base::RunLoop().RunUntilIdle();
+ }
+
+ NiceMock<chromeos::MockUserManager>* mock_user_manager_;
+ chromeos::ScopedUserManagerEnabler scoped_user_manager_enabler_;
+ FakeDeviceCloudPolicyInitializer* fake_initializer_;
+ EnrollmentStatus enrollment_status_;
+};
+
+TEST_F(ConsumerManagementServiceEnrollmentTest, EnrollsSuccessfully) {
+ EXPECT_FALSE(fake_initializer_->was_start_enrollment_called());
+
+ RunEnrollmentTest();
+
+ EXPECT_TRUE(fake_initializer_->was_start_enrollment_called());
+ EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_SUCCESS,
+ GetEnrollmentStage());
+ EXPECT_FALSE(HasEnrollmentNotification());
+}
+
+TEST_F(ConsumerManagementServiceEnrollmentTest,
+ ShowsDesktopNotificationAndResetsEnrollmentStageIfCurrentUserIsOwner) {
+ EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_OWNER_STORED,
+ GetEnrollmentStage());
+ EXPECT_FALSE(HasEnrollmentNotification());
+ EXPECT_CALL(*mock_user_manager_, IsCurrentUserOwner())
+ .WillOnce(Return(true));
+
+ RunEnrollmentTest();
+
+ EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_NONE,
+ GetEnrollmentStage());
+ EXPECT_TRUE(HasEnrollmentNotification());
+}
+
+TEST_F(ConsumerManagementServiceEnrollmentTest, FailsToGetAccessToken) {
+ // Disable auto-posting so that RunEnrollmentTest() should stop and wait for
+ // the access token to be available.
+ GetFakeProfileOAuth2TokenService()->
+ set_auto_post_fetch_response_on_message_loop(false);
+
+ RunEnrollmentTest();
+
+ // The service should have a pending token request.
+ OAuth2TokenService::Request* token_request =
+ service_->GetTokenRequestForTesting();
+ EXPECT_TRUE(token_request);
+
+ // Tell the service that the access token is not available because of some
+ // backend issue.
+ service_->OnGetTokenFailure(
+ token_request,
+ GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR));
+
+ EXPECT_FALSE(fake_initializer_->was_start_enrollment_called());
+ EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_GET_TOKEN_FAILED,
+ GetEnrollmentStage());
+}
+
+TEST_F(ConsumerManagementServiceEnrollmentTest, FailsToRegister) {
+ EXPECT_FALSE(fake_initializer_->was_start_enrollment_called());
+ fake_initializer_->set_enrollment_status(EnrollmentStatus::ForStatus(
+ EnrollmentStatus::STATUS_REGISTRATION_FAILED));
+
+ RunEnrollmentTest();
+
+ EXPECT_TRUE(fake_initializer_->was_start_enrollment_called());
+ EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_DM_SERVER_FAILED,
+ GetEnrollmentStage());
+}
+
+TEST_F(ConsumerManagementServiceEnrollmentTest,
+ ShowsDesktopNotificationOnlyIfEnrollmentIsAlreadyCompleted) {
+ SetEnrollmentStage(ConsumerManagementService::ENROLLMENT_STAGE_CANCELED);
+ EXPECT_FALSE(HasEnrollmentNotification());
+
+ RunEnrollmentTest();
+
+ EXPECT_FALSE(fake_initializer_->was_start_enrollment_called());
+ EXPECT_EQ(ConsumerManagementService::ENROLLMENT_STAGE_NONE,
+ GetEnrollmentStage());
+ EXPECT_TRUE(HasEnrollmentNotification());
+}
+
+class ConsumerManagementServiceStatusTest
+ : public chromeos::DeviceSettingsTestBase {
+ public:
+ ConsumerManagementServiceStatusTest()
+ : testing_local_state_(TestingBrowserProcess::GetGlobal()),
+ service_(NULL, &device_settings_service_) {
+ }
+
+ void SetEnrollmentStage(ConsumerManagementService::EnrollmentStage stage) {
+ testing_local_state_.Get()->SetInteger(
+ prefs::kConsumerManagementEnrollmentStage, stage);
+ }
+
+ void SetManagementMode(em::PolicyData::ManagementMode mode) {
+ device_policy_.policy_data().set_management_mode(mode);
+ device_policy_.Build();
+ device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
+ ReloadDeviceSettings();
+ }
+
+ ScopedTestingLocalState testing_local_state_;
+ ConsumerManagementService service_;
+};
+
+TEST_F(ConsumerManagementServiceStatusTest, GetStatusAndGetStatusStringWork) {
+ EXPECT_EQ(ConsumerManagementService::STATUS_UNKNOWN, service_.GetStatus());
+ EXPECT_EQ("StatusUnknown", service_.GetStatusString());
+
+ SetManagementMode(em::PolicyData::NOT_MANAGED);
+ SetEnrollmentStage(ConsumerManagementService::ENROLLMENT_STAGE_NONE);
+
+ EXPECT_EQ(ConsumerManagementService::STATUS_UNENROLLED, service_.GetStatus());
+ EXPECT_EQ("StatusUnenrolled", service_.GetStatusString());
+
+ SetEnrollmentStage(ConsumerManagementService::ENROLLMENT_STAGE_REQUESTED);
+
+ EXPECT_EQ(ConsumerManagementService::STATUS_ENROLLING, service_.GetStatus());
+ EXPECT_EQ("StatusEnrolling", service_.GetStatusString());
+
+ SetManagementMode(em::PolicyData::CONSUMER_MANAGED);
+ SetEnrollmentStage(ConsumerManagementService::ENROLLMENT_STAGE_SUCCESS);
+
+ EXPECT_EQ(ConsumerManagementService::STATUS_ENROLLED, service_.GetStatus());
+ EXPECT_EQ("StatusEnrolled", service_.GetStatusString());
+
+ // TODO(davidyu): Test for STATUS_UNENROLLING when it is implemented.
+ // http://crbug.com/353050.
+}
+
} // namespace policy