root/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ForceSignOut
  2. Build
  3. BuildCloudPolicyManager
  4. register_completed_
  5. OnRegisterCompleted
  6. RegisterPolicyClientWithCallback
  7. SetUp
  8. TearDown
  9. AddProfile
  10. GetTokenService
  11. IsRequestActive
  12. MakeOAuthTokenFetchSucceed
  13. ReportHostedDomainStatus
  14. TestSuccessfulSignin
  15. AddProfile
  16. TEST_F
  17. TEST_F
  18. TEST_F
  19. TEST_F
  20. TEST_F
  21. TEST_F
  22. TEST_F
  23. TEST_F
  24. TEST_F
  25. TEST_F
  26. TEST_F
  27. TEST_F
  28. TEST_F
  29. TEST_F
  30. TEST_F
  31. TEST_F
  32. TEST_F

// Copyright (c) 2012 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 "base/files/file_path.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/prefs/pref_service.h"
#include "base/run_loop.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
#include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
#include "chrome/browser/prefs/browser_prefs.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/fake_signin_manager.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_pref_service_syncable.h"
#include "chrome/test/base/testing_profile.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/cloud/cloud_external_data_manager.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/mock_device_management_service.h"
#include "components/policy/core/common/cloud/mock_user_cloud_policy_store.h"
#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
#include "components/policy/core/common/schema_registry.h"
#include "components/signin/core/browser/signin_manager.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_ANDROID)
#include "chrome/browser/policy/cloud/user_policy_signin_service_android.h"
#else
#include "chrome/browser/policy/cloud/user_policy_signin_service.h"
#endif

namespace em = enterprise_management;

using testing::AnyNumber;
using testing::Mock;
using testing::_;

namespace policy {

namespace {

const char kTestUser[] = "testuser@test.com";

#if !defined(OS_ANDROID)
const char kValidTokenResponse[] =
    "{"
    "  \"access_token\": \"at1\","
    "  \"expires_in\": 3600,"
    "  \"token_type\": \"Bearer\""
    "}";
#endif

const char kHostedDomainResponse[] =
    "{"
    "  \"hd\": \"test.com\""
    "}";

class SigninManagerFake : public FakeSigninManager {
 public:
  explicit SigninManagerFake(Profile* profile)
      : FakeSigninManager(profile) {
    Initialize(NULL);
  }

  void ForceSignOut() {
    // Allow signing out now.
    prohibit_signout_ = false;
    SignOut();
  }

  static KeyedService* Build(content::BrowserContext* profile) {
    return new SigninManagerFake(static_cast<Profile*>(profile));
  }
};

UserCloudPolicyManager* BuildCloudPolicyManager(
    content::BrowserContext* context) {
  MockUserCloudPolicyStore *store = new MockUserCloudPolicyStore();
  EXPECT_CALL(*store, Load()).Times(AnyNumber());

  return new UserCloudPolicyManager(
      scoped_ptr<UserCloudPolicyStore>(store),
      base::FilePath(),
      scoped_ptr<CloudExternalDataManager>(),
      base::MessageLoopProxy::current(),
      base::MessageLoopProxy::current(),
      base::MessageLoopProxy::current());
}

class UserPolicySigninServiceTest : public testing::Test {
 public:
  UserPolicySigninServiceTest()
      : mock_store_(NULL),
        thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
        register_completed_(false) {}

  MOCK_METHOD1(OnPolicyRefresh, void(bool));

  void OnRegisterCompleted(const std::string& dm_token,
                           const std::string& client_id) {
    register_completed_ = true;
    dm_token_ = dm_token;
    client_id_ = client_id;
  }

  void RegisterPolicyClientWithCallback(UserPolicySigninService* service) {
    // Policy client registration on Android depends on Token Service having
    // a valid login token, while on other platforms, the login refresh token
    // is specified directly.
#if defined(OS_ANDROID)
    GetTokenService()->IssueRefreshTokenForUser(kTestUser,
                                                "oauth2_login_refresh_token");
#endif
    service->RegisterForPolicy(
        kTestUser,
#if !defined(OS_ANDROID)
        "mock_oauth_token",
#endif
        base::Bind(&UserPolicySigninServiceTest::OnRegisterCompleted,
                   base::Unretained(this)));
    ASSERT_TRUE(IsRequestActive());
  }

  virtual void SetUp() OVERRIDE {
    UserPolicySigninServiceFactory::SetDeviceManagementServiceForTesting(
        &device_management_service_);

    local_state_.reset(new TestingPrefServiceSimple);
    chrome::RegisterLocalState(local_state_->registry());
    system_request_context_getter_ = new net::TestURLRequestContextGetter(
        base::MessageLoopProxy::current());
    TestingBrowserProcess::GetGlobal()->SetSystemRequestContext(
        system_request_context_getter_.get());
    TestingBrowserProcess::GetGlobal()->SetLocalState(local_state_.get());

    g_browser_process->browser_policy_connector()->Init(
        local_state_.get(), system_request_context_getter_);

    // Create a testing profile with cloud-policy-on-signin enabled, and bring
    // up a UserCloudPolicyManager with a MockUserCloudPolicyStore.
    scoped_ptr<TestingPrefServiceSyncable> prefs(
        new TestingPrefServiceSyncable());
    chrome::RegisterUserProfilePrefs(prefs->registry());

    // UserCloudPolicyManagerFactory isn't a real
    // BrowserContextKeyedServiceFactory (it derives from
    // BrowserContextKeyedBaseFactory and exposes its own APIs to get
    // instances) so we have to inject our testing factory via a special
    // API before creating the profile.
    UserCloudPolicyManagerFactory::GetInstance()->RegisterTestingFactory(
        BuildCloudPolicyManager);
    TestingProfile::Builder builder;
    builder.SetPrefService(scoped_ptr<PrefServiceSyncable>(prefs.Pass()));
    builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
                              SigninManagerFake::Build);
    builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
                              BuildFakeProfileOAuth2TokenService);

    profile_ = builder.Build().Pass();
    url_factory_.set_remove_fetcher_on_delete(true);

    signin_manager_ = static_cast<SigninManagerFake*>(
        SigninManagerFactory::GetForProfile(profile_.get()));
    // Tests are responsible for freeing the UserCloudPolicyManager instances
    // they inject.
    manager_.reset(UserCloudPolicyManagerFactory::GetForBrowserContext(
        profile_.get()));
    manager_->Init(&schema_registry_);
    mock_store_ = static_cast<MockUserCloudPolicyStore*>(
        manager_->core()->store());
    DCHECK(mock_store_);
    AddProfile();

    Mock::VerifyAndClearExpectations(mock_store_);
  }

  virtual void TearDown() OVERRIDE {
    UserPolicySigninServiceFactory::SetDeviceManagementServiceForTesting(NULL);
    UserCloudPolicyManagerFactory::GetInstance()->ClearTestingFactory();
    // Free the profile before we clear out the browser prefs.
    profile_.reset();
    TestingBrowserProcess* testing_browser_process =
        TestingBrowserProcess::GetGlobal();
    testing_browser_process->SetLocalState(NULL);
    local_state_.reset();
    testing_browser_process->SetBrowserPolicyConnector(NULL);
    base::RunLoop run_loop;
    run_loop.RunUntilIdle();
  }

  virtual void AddProfile() {
    // For this test, the user should not be signed in yet.
    DCHECK(signin_manager_->GetAuthenticatedUsername().empty());

    // Initializing UserPolicySigninService while the user is not signed in
    // should result in the store being cleared to remove any lingering policy.
    EXPECT_CALL(*mock_store_, Clear());

    // Let the SigninService know that the profile has been created.
    content::NotificationService::current()->Notify(
        chrome::NOTIFICATION_PROFILE_ADDED,
        content::Source<Profile>(profile_.get()),
        content::NotificationService::NoDetails());
  }

  FakeProfileOAuth2TokenService* GetTokenService() {
    ProfileOAuth2TokenService* service =
        ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get());
    return static_cast<FakeProfileOAuth2TokenService*>(service);
  }

  bool IsRequestActive() {
    if (!GetTokenService()->GetPendingRequests().empty())
      return true;
    return url_factory_.GetFetcherByID(0);
  }

  void MakeOAuthTokenFetchSucceed() {
    ASSERT_TRUE(IsRequestActive());
#if defined(OS_ANDROID)
    GetTokenService()->IssueTokenForAllPendingRequests("access_token",
                                                       base::Time::Now());
#else
    net::TestURLFetcher* fetcher = url_factory_.GetFetcherByID(0);
    fetcher->set_response_code(net::HTTP_OK);
    fetcher->SetResponseString(kValidTokenResponse);
    fetcher->delegate()->OnURLFetchComplete(fetcher);
#endif
  }

  void ReportHostedDomainStatus(bool is_hosted_domain) {
    ASSERT_TRUE(IsRequestActive());
    net::TestURLFetcher* fetcher = url_factory_.GetFetcherByID(0);
    fetcher->set_response_code(net::HTTP_OK);
    fetcher->SetResponseString(is_hosted_domain ? kHostedDomainResponse : "{}");
    fetcher->delegate()->OnURLFetchComplete(fetcher);
  }

  void TestSuccessfulSignin() {
    UserPolicySigninService* signin_service =
        UserPolicySigninServiceFactory::GetForProfile(profile_.get());
    EXPECT_CALL(*this, OnPolicyRefresh(true)).Times(0);
    RegisterPolicyClientWithCallback(signin_service);

    // Mimic successful oauth token fetch.
    MakeOAuthTokenFetchSucceed();

    // When the user is from a hosted domain, this should kick off client
    // registration.
    MockDeviceManagementJob* register_request = NULL;
    EXPECT_CALL(device_management_service_,
                CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION, _))
        .WillOnce(device_management_service_.CreateAsyncJob(
            &register_request));
    EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
        .Times(1);

    // Now mimic the user being a hosted domain - this should cause a Register()
    // call.
    ReportHostedDomainStatus(true);

    // Should have no more outstanding requests.
    ASSERT_FALSE(IsRequestActive());
    Mock::VerifyAndClearExpectations(this);
    ASSERT_TRUE(register_request);

    // Mimic successful client registration - this should register the client
    // and invoke the callback.
    em::DeviceManagementResponse registration_blob;
    std::string expected_dm_token = "dm_token";
    registration_blob.mutable_register_response()->set_device_management_token(
        expected_dm_token);
    registration_blob.mutable_register_response()->set_enrollment_type(
        em::DeviceRegisterResponse::ENTERPRISE);
    register_request->SendResponse(DM_STATUS_SUCCESS, registration_blob);

    // UserCloudPolicyManager should not be initialized yet.
    ASSERT_FALSE(manager_->core()->service());
    EXPECT_TRUE(register_completed_);
    EXPECT_EQ(dm_token_, expected_dm_token);

    // Now call to fetch policy - this should fire off a fetch request.
    MockDeviceManagementJob* fetch_request = NULL;
    EXPECT_CALL(device_management_service_,
                CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH, _))
        .WillOnce(device_management_service_.CreateAsyncJob(&fetch_request));
    EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
        .Times(1);

    signin_service->FetchPolicyForSignedInUser(
        kTestUser,
        dm_token_,
        client_id_,
        profile_->GetRequestContext(),
        base::Bind(&UserPolicySigninServiceTest::OnPolicyRefresh,
                   base::Unretained(this)));

    Mock::VerifyAndClearExpectations(this);
    ASSERT_TRUE(fetch_request);

    // UserCloudPolicyManager should now be initialized.
    EXPECT_EQ(mock_store_->signin_username_, kTestUser);
    ASSERT_TRUE(manager_->core()->service());

    // Make the policy fetch succeed - this should result in a write to the
    // store and ultimately result in a call to OnPolicyRefresh().
    EXPECT_CALL(*mock_store_, Store(_));
    EXPECT_CALL(*this, OnPolicyRefresh(true)).Times(1);

    // Create a fake policy blob to deliver to the client.
    em::DeviceManagementResponse policy_blob;
    em::PolicyData policy_data;
    policy_data.set_policy_type(dm_protocol::kChromeUserPolicyType);
    em::PolicyFetchResponse* policy_response =
        policy_blob.mutable_policy_response()->add_response();
    ASSERT_TRUE(policy_data.SerializeToString(
        policy_response->mutable_policy_data()));
    fetch_request->SendResponse(DM_STATUS_SUCCESS, policy_blob);

    // Complete the store which should cause the policy fetch callback to be
    // invoked.
    mock_store_->NotifyStoreLoaded();
    Mock::VerifyAndClearExpectations(this);
  }

  scoped_ptr<TestingProfile> profile_;
  MockUserCloudPolicyStore* mock_store_;  // Not owned.
  SchemaRegistry schema_registry_;
  scoped_ptr<UserCloudPolicyManager> manager_;

  // BrowserPolicyConnector and UrlFetcherFactory want to initialize and free
  // various components asynchronously via tasks, so create fake threads here.
  content::TestBrowserThreadBundle thread_bundle_;

  net::TestURLFetcherFactory url_factory_;

  SigninManagerFake* signin_manager_;

  // Used in conjunction with OnRegisterCompleted() to test client registration
  // callbacks.
  std::string dm_token_;
  std::string client_id_;

  // True if OnRegisterCompleted() was called.
  bool register_completed_;

  // Weak ptr to the MockDeviceManagementService (object is owned by the
  // BrowserPolicyConnector).
  MockDeviceManagementService device_management_service_;

  scoped_ptr<TestingPrefServiceSimple> local_state_;
  scoped_refptr<net::URLRequestContextGetter> system_request_context_getter_;
};

class UserPolicySigninServiceSignedInTest : public UserPolicySigninServiceTest {
 public:
  virtual void AddProfile() OVERRIDE {
    // UserCloudPolicyManager should not be initialized.
    ASSERT_FALSE(manager_->core()->service());

    // Set the user as signed in.
    SigninManagerFactory::GetForProfile(profile_.get())->
        SetAuthenticatedUsername(kTestUser);

    // Let the SigninService know that the profile has been created.
    content::NotificationService::current()->Notify(
        chrome::NOTIFICATION_PROFILE_ADDED,
        content::Source<Profile>(profile_.get()),
        content::NotificationService::NoDetails());
  }
};

TEST_F(UserPolicySigninServiceTest, InitWhileSignedOut) {
  // Make sure user is not signed in.
  ASSERT_TRUE(SigninManagerFactory::GetForProfile(profile_.get())->
      GetAuthenticatedUsername().empty());

  // UserCloudPolicyManager should not be initialized.
  ASSERT_FALSE(manager_->core()->service());
}

  // TODO(joaodasilva): these tests rely on issuing the OAuth2 login refresh
  // token after signin. Revisit this after figuring how to handle that on
  // Android.
#if !defined(OS_ANDROID)

TEST_F(UserPolicySigninServiceSignedInTest, InitWhileSignedIn) {
  // UserCloudPolicyManager should be initialized.
  ASSERT_TRUE(manager_->core()->service());

  // Complete initialization of the store.
  mock_store_->NotifyStoreLoaded();

  // No oauth access token yet, so client registration should be deferred.
  ASSERT_FALSE(IsRequestActive());

  // Make oauth token available.
  GetTokenService()->IssueRefreshTokenForUser(kTestUser,
                                              "oauth_login_refresh_token");

  // Client registration should be in progress since we now have an oauth token.
  EXPECT_EQ(mock_store_->signin_username_, kTestUser);
  ASSERT_TRUE(IsRequestActive());
}

TEST_F(UserPolicySigninServiceSignedInTest, InitWhileSignedInOAuthError) {
  // UserCloudPolicyManager should be initialized.
  ASSERT_TRUE(manager_->core()->service());

  // Complete initialization of the store.
  mock_store_->NotifyStoreLoaded();

  // No oauth access token yet, so client registration should be deferred.
  ASSERT_FALSE(IsRequestActive());

  // Make oauth token available.
  GetTokenService()->IssueRefreshTokenForUser(kTestUser,
                                              "oauth_login_refresh_token");

  // Client registration should be in progress since we now have an oauth token.
  ASSERT_TRUE(IsRequestActive());

  // Now fail the access token fetch.
  GoogleServiceAuthError error(
      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
  GetTokenService()->IssueErrorForAllPendingRequests(error);
  ASSERT_FALSE(IsRequestActive());
}

TEST_F(UserPolicySigninServiceTest, SignInAfterInit) {
  // UserCloudPolicyManager should not be initialized since there is no
  // signed-in user.
  ASSERT_FALSE(manager_->core()->service());

  // Now sign in the user.
  SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
      kTestUser);

  // Complete initialization of the store.
  mock_store_->NotifyStoreLoaded();

  // Make oauth token available.
  GetTokenService()->IssueRefreshTokenForUser(kTestUser,
                                              "oauth_login_refresh_token");

  // UserCloudPolicyManager should be initialized.
  EXPECT_EQ(mock_store_->signin_username_, kTestUser);
  ASSERT_TRUE(manager_->core()->service());

  // Client registration should be in progress since we have an oauth token.
  ASSERT_TRUE(IsRequestActive());
}

TEST_F(UserPolicySigninServiceTest, SignInWithNonEnterpriseUser) {
  // UserCloudPolicyManager should not be initialized since there is no
  // signed-in user.
  ASSERT_FALSE(manager_->core()->service());

  // Now sign in a non-enterprise user (blacklisted gmail.com domain).
  SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
      "non_enterprise_user@gmail.com");

  // Complete initialization of the store.
  mock_store_->NotifyStoreLoaded();

  // Make oauth token available.
  GetTokenService()->IssueRefreshTokenForUser(kTestUser,
                                              "oauth_login_refresh_token");

  // UserCloudPolicyManager should not be initialized and there should be no
  // DMToken request active.
  ASSERT_TRUE(!manager_->core()->service());
  ASSERT_FALSE(IsRequestActive());
}

TEST_F(UserPolicySigninServiceTest, UnregisteredClient) {
  // UserCloudPolicyManager should not be initialized since there is no
  // signed-in user.
  ASSERT_FALSE(manager_->core()->service());

  // Now sign in the user.
  SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
      kTestUser);

  // Make oauth token available.
  GetTokenService()->IssueRefreshTokenForUser(kTestUser,
                                              "oauth_login_refresh_token");

  // UserCloudPolicyManager should be initialized.
  EXPECT_EQ(mock_store_->signin_username_, kTestUser);
  ASSERT_TRUE(manager_->core()->service());

  // Client registration should not be in progress since the store is not
  // yet initialized.
  ASSERT_FALSE(IsRequestActive());

  // Complete initialization of the store with no policy (unregistered client).
  mock_store_->NotifyStoreLoaded();

  // Client registration should be in progress since we have an oauth token.
  ASSERT_TRUE(IsRequestActive());
}

TEST_F(UserPolicySigninServiceTest, RegisteredClient) {
  // UserCloudPolicyManager should not be initialized since there is no
  // signed-in user.
  ASSERT_FALSE(manager_->core()->service());

  // Now sign in the user.
  SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
      kTestUser);

  // Make oauth token available.
  GetTokenService()->IssueRefreshTokenForUser(kTestUser,
                                              "oauth_login_refresh_token");

  // UserCloudPolicyManager should be initialized.
  EXPECT_EQ(mock_store_->signin_username_, kTestUser);
  ASSERT_TRUE(manager_->core()->service());

  // Client registration should not be in progress since the store is not
  // yet initialized.
  ASSERT_FALSE(manager_->IsClientRegistered());
  ASSERT_FALSE(IsRequestActive());

  mock_store_->policy_.reset(new enterprise_management::PolicyData());
  mock_store_->policy_->set_request_token("fake token");
  mock_store_->policy_->set_device_id("fake client id");

  // Complete initialization of the store.
  mock_store_->NotifyStoreLoaded();

  // Client registration should not be in progress since the client should be
  // already registered.
  ASSERT_TRUE(manager_->IsClientRegistered());
  ASSERT_FALSE(IsRequestActive());
}

#endif  // !defined(OS_ANDROID)

TEST_F(UserPolicySigninServiceSignedInTest, SignOutAfterInit) {
  // UserCloudPolicyManager should be initialized.
  EXPECT_EQ(mock_store_->signin_username_, kTestUser);
  ASSERT_TRUE(manager_->core()->service());

  // Signing out will clear the policy from the store.
  EXPECT_CALL(*mock_store_, Clear());

  // Now sign out.
  SigninManagerFactory::GetForProfile(profile_.get())->SignOut();

  // UserCloudPolicyManager should be shut down.
  ASSERT_FALSE(manager_->core()->service());
}

TEST_F(UserPolicySigninServiceTest, RegisterPolicyClientOAuthFailure) {
  UserPolicySigninService* signin_service =
      UserPolicySigninServiceFactory::GetForProfile(profile_.get());
  RegisterPolicyClientWithCallback(signin_service);
  Mock::VerifyAndClearExpectations(this);

  // UserCloudPolicyManager should not be initialized.
  ASSERT_FALSE(manager_->core()->service());
  ASSERT_TRUE(IsRequestActive());
  EXPECT_FALSE(register_completed_);

  // Cause the access token fetch to fail - callback should be invoked.
#if defined(OS_ANDROID)
  ASSERT_TRUE(!GetTokenService()->GetPendingRequests().empty());
  GetTokenService()->IssueErrorForAllPendingRequests(
      GoogleServiceAuthError::FromServiceError("fail"));
#else
  net::TestURLFetcher* fetcher = url_factory_.GetFetcherByID(0);
  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, -1));
  fetcher->delegate()->OnURLFetchComplete(fetcher);
#endif

  EXPECT_TRUE(register_completed_);
  EXPECT_TRUE(dm_token_.empty());
  EXPECT_FALSE(IsRequestActive());
}

TEST_F(UserPolicySigninServiceTest, RegisterPolicyClientNonHostedDomain) {
  UserPolicySigninService* signin_service =
      UserPolicySigninServiceFactory::GetForProfile(profile_.get());
  RegisterPolicyClientWithCallback(signin_service);

  // UserCloudPolicyManager should not be initialized.
  ASSERT_FALSE(manager_->core()->service());
  ASSERT_TRUE(IsRequestActive());

  // Cause the access token request to succeed.
  MakeOAuthTokenFetchSucceed();

  // Should be a follow-up fetch to check the hosted-domain status.
  ASSERT_TRUE(IsRequestActive());
  Mock::VerifyAndClearExpectations(this);

  EXPECT_FALSE(register_completed_);

  // Report that the user is not on a hosted domain - callback should be
  // invoked reporting a failed fetch.
  ReportHostedDomainStatus(false);

  // Since this is not a hosted domain, we should not issue a request for a
  // DMToken.
  EXPECT_TRUE(register_completed_);
  EXPECT_TRUE(dm_token_.empty());
  ASSERT_FALSE(IsRequestActive());
}

TEST_F(UserPolicySigninServiceTest, RegisterPolicyClientFailedRegistration) {
  UserPolicySigninService* signin_service =
      UserPolicySigninServiceFactory::GetForProfile(profile_.get());
  RegisterPolicyClientWithCallback(signin_service);

  // UserCloudPolicyManager should not be initialized.
  ASSERT_FALSE(manager_->core()->service());

  // Mimic successful oauth token fetch.
  MakeOAuthTokenFetchSucceed();

  EXPECT_FALSE(register_completed_);

  // When the user is from a hosted domain, this should kick off client
  // registration.
  MockDeviceManagementJob* register_request = NULL;
  EXPECT_CALL(device_management_service_,
              CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION, _))
      .WillOnce(device_management_service_.CreateAsyncJob(&register_request));
  EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
        .Times(1);

  // Now mimic the user being a hosted domain - this should cause a Register()
  // call.
  ReportHostedDomainStatus(true);

  // Should have no more outstanding requests.
  ASSERT_FALSE(IsRequestActive());
  Mock::VerifyAndClearExpectations(this);
  ASSERT_TRUE(register_request);
  EXPECT_FALSE(register_completed_);

  // Make client registration fail (hosted domain user that is not managed).
  register_request->SendResponse(DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED,
                                 em::DeviceManagementResponse());
  EXPECT_TRUE(register_completed_);
  EXPECT_TRUE(dm_token_.empty());
}

TEST_F(UserPolicySigninServiceTest, RegisterPolicyClientSucceeded) {
  UserPolicySigninService* signin_service =
      UserPolicySigninServiceFactory::GetForProfile(profile_.get());
  RegisterPolicyClientWithCallback(signin_service);

  // Mimic successful oauth token fetch.
  MakeOAuthTokenFetchSucceed();

  // When the user is from a hosted domain, this should kick off client
  // registration.
  MockDeviceManagementJob* register_request = NULL;
  EXPECT_CALL(device_management_service_,
              CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION, _))
      .WillOnce(device_management_service_.CreateAsyncJob(&register_request));
  EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
      .Times(1);

  // Now mimic the user being a hosted domain - this should cause a Register()
  // call.
  ReportHostedDomainStatus(true);

  // Should have no more outstanding requests.
  ASSERT_FALSE(IsRequestActive());
  Mock::VerifyAndClearExpectations(this);
  ASSERT_TRUE(register_request);
  EXPECT_FALSE(register_completed_);

  em::DeviceManagementResponse registration_blob;
  std::string expected_dm_token = "dm_token";
  registration_blob.mutable_register_response()->set_device_management_token(
      expected_dm_token);
  registration_blob.mutable_register_response()->set_enrollment_type(
      em::DeviceRegisterResponse::ENTERPRISE);
  register_request->SendResponse(DM_STATUS_SUCCESS, registration_blob);
  Mock::VerifyAndClearExpectations(this);
  EXPECT_TRUE(register_completed_);
  EXPECT_EQ(dm_token_, expected_dm_token);
  // UserCloudPolicyManager should not be initialized.
  ASSERT_FALSE(manager_->core()->service());
}

TEST_F(UserPolicySigninServiceTest, FetchPolicyFailed) {
  // Initiate a policy fetch request.
  MockDeviceManagementJob* fetch_request = NULL;
  EXPECT_CALL(device_management_service_,
              CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH, _))
      .WillOnce(device_management_service_.CreateAsyncJob(&fetch_request));
  EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
      .Times(1);
  UserPolicySigninService* signin_service =
      UserPolicySigninServiceFactory::GetForProfile(profile_.get());
  signin_service->FetchPolicyForSignedInUser(
      kTestUser,
      "mock_dm_token",
      "mock_client_id",
      profile_->GetRequestContext(),
      base::Bind(&UserPolicySigninServiceTest::OnPolicyRefresh,
                 base::Unretained(this)));
  ASSERT_TRUE(fetch_request);

  // Make the policy fetch fail.
  EXPECT_CALL(*this, OnPolicyRefresh(false)).Times(1);
  fetch_request->SendResponse(DM_STATUS_REQUEST_FAILED,
                              em::DeviceManagementResponse());

  // UserCloudPolicyManager should be initialized.
  EXPECT_EQ(mock_store_->signin_username_, kTestUser);
  ASSERT_TRUE(manager_->core()->service());
}

TEST_F(UserPolicySigninServiceTest, FetchPolicySuccess) {
  ASSERT_NO_FATAL_FAILURE(TestSuccessfulSignin());
}

TEST_F(UserPolicySigninServiceTest, SignOutThenSignInAgain) {
  ASSERT_NO_FATAL_FAILURE(TestSuccessfulSignin());

  EXPECT_CALL(*mock_store_, Clear());
  signin_manager_->ForceSignOut();
  ASSERT_FALSE(manager_->core()->service());

  // Now sign in again.
  ASSERT_NO_FATAL_FAILURE(TestSuccessfulSignin());
}

TEST_F(UserPolicySigninServiceTest, PolicyFetchFailureTemporary) {
  ASSERT_NO_FATAL_FAILURE(TestSuccessfulSignin());

  ASSERT_TRUE(manager_->IsClientRegistered());

  // Kick off another policy fetch.
  MockDeviceManagementJob* fetch_request = NULL;
  EXPECT_CALL(device_management_service_,
              CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH, _))
      .WillOnce(device_management_service_.CreateAsyncJob(&fetch_request));
  EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
      .Times(1);
  manager_->RefreshPolicies();
  Mock::VerifyAndClearExpectations(this);

  // Now, fake a transient error from the server on this policy fetch. This
  // should have no impact on the cached policy.
  fetch_request->SendResponse(DM_STATUS_REQUEST_FAILED,
                              em::DeviceManagementResponse());
  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(manager_->IsClientRegistered());
}

TEST_F(UserPolicySigninServiceTest, PolicyFetchFailureDisableManagement) {
  ASSERT_NO_FATAL_FAILURE(TestSuccessfulSignin());

  EXPECT_TRUE(manager_->IsClientRegistered());
#if !defined(OS_ANDROID)
  EXPECT_TRUE(signin_manager_->IsSignoutProhibited());
#endif

  // Kick off another policy fetch.
  MockDeviceManagementJob* fetch_request = NULL;
  EXPECT_CALL(device_management_service_,
              CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH, _))
      .WillOnce(device_management_service_.CreateAsyncJob(&fetch_request));
  EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
      .Times(1);
  manager_->RefreshPolicies();
  Mock::VerifyAndClearExpectations(this);

  // Now, fake a SC_FORBIDDEN error from the server on this policy fetch. This
  // indicates that chrome management is disabled and will result in the cached
  // policy being removed and the manager shut down.
  EXPECT_CALL(*mock_store_, Clear());
  fetch_request->SendResponse(DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED,
                              em::DeviceManagementResponse());
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(manager_->IsClientRegistered());
#if !defined(OS_ANDROID)
  EXPECT_FALSE(signin_manager_->IsSignoutProhibited());
#endif
}

}  // namespace

}  // namespace policy

/* [<][>][^][v][top][bottom][index][help] */