Home | History | Annotate | Download | only in cloud
      1 // Copyright (c) 2012 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.
      4 
      5 #include "components/policy/core/common/cloud/cloud_policy_client.h"
      6 
      7 #include <map>
      8 #include <set>
      9 
     10 #include "base/bind.h"
     11 #include "base/compiler_specific.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/message_loop/message_loop.h"
     14 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
     15 #include "components/policy/core/common/cloud/mock_device_management_service.h"
     16 #include "net/url_request/url_request_context_getter.h"
     17 #include "net/url_request/url_request_test_util.h"
     18 #include "policy/proto/device_management_backend.pb.h"
     19 #include "testing/gmock/include/gmock/gmock.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 
     22 using testing::Mock;
     23 using testing::Return;
     24 using testing::SaveArg;
     25 using testing::StrictMock;
     26 using testing::_;
     27 
     28 namespace em = enterprise_management;
     29 
     30 namespace policy {
     31 
     32 namespace {
     33 
     34 const char kClientID[] = "fake-client-id";
     35 const char kMachineID[] = "fake-machine-id";
     36 const char kMachineModel[] = "fake-machine-model";
     37 const char kOAuthToken[] = "fake-oauth-token";
     38 const char kDMToken[] = "fake-dm-token";
     39 const char kDeviceCertificate[] = "fake-device-certificate";
     40 const char kRequisition[] = "fake-requisition";
     41 const char kStateKey[] = "fake-state-key";
     42 
     43 class MockStatusProvider : public CloudPolicyClient::StatusProvider {
     44  public:
     45   MockStatusProvider() {}
     46   virtual ~MockStatusProvider() {}
     47 
     48   MOCK_METHOD1(GetDeviceStatus, bool(em::DeviceStatusReportRequest* status));
     49   MOCK_METHOD1(GetSessionStatus, bool(em::SessionStatusReportRequest* status));
     50   MOCK_METHOD0(OnSubmittedSuccessfully, void(void));
     51 
     52  private:
     53   DISALLOW_COPY_AND_ASSIGN(MockStatusProvider);
     54 };
     55 
     56 MATCHER_P(MatchProto, expected, "matches protobuf") {
     57   return arg.SerializePartialAsString() == expected.SerializePartialAsString();
     58 }
     59 
     60 // A mock class to allow us to set expectations on upload certificate callbacks.
     61 class MockUploadCertificateObserver {
     62  public:
     63   MockUploadCertificateObserver() {}
     64   virtual ~MockUploadCertificateObserver() {}
     65 
     66   MOCK_METHOD1(OnUploadComplete, void(bool));
     67 };
     68 
     69 }  // namespace
     70 
     71 class CloudPolicyClientTest : public testing::Test {
     72  protected:
     73   CloudPolicyClientTest()
     74       : client_id_(kClientID),
     75         policy_ns_key_(dm_protocol::kChromeUserPolicyType, std::string()) {
     76     em::DeviceRegisterRequest* register_request =
     77         registration_request_.mutable_register_request();
     78     register_request->set_type(em::DeviceRegisterRequest::USER);
     79     register_request->set_machine_id(kMachineID);
     80     register_request->set_machine_model(kMachineModel);
     81     registration_response_.mutable_register_response()->
     82         set_device_management_token(kDMToken);
     83 
     84     em::PolicyFetchRequest* policy_fetch_request =
     85         policy_request_.mutable_policy_request()->add_request();
     86     policy_fetch_request->set_policy_type(dm_protocol::kChromeUserPolicyType);
     87     policy_fetch_request->set_signature_type(em::PolicyFetchRequest::SHA1_RSA);
     88     policy_fetch_request->set_verification_key_hash(kPolicyVerificationKeyHash);
     89     policy_response_.mutable_policy_response()->add_response()->set_policy_data(
     90         CreatePolicyData("fake-policy-data"));
     91 
     92     unregistration_request_.mutable_unregister_request();
     93     unregistration_response_.mutable_unregister_response();
     94     upload_certificate_request_.mutable_cert_upload_request()->
     95         set_device_certificate(kDeviceCertificate);
     96     upload_certificate_response_.mutable_cert_upload_response();
     97   }
     98 
     99   virtual void SetUp() OVERRIDE {
    100     EXPECT_CALL(status_provider_, GetDeviceStatus(_))
    101         .WillRepeatedly(Return(false));
    102     EXPECT_CALL(status_provider_, GetSessionStatus(_))
    103         .WillRepeatedly(Return(false));
    104     CreateClient(USER_AFFILIATION_NONE);
    105   }
    106 
    107   virtual void TearDown() OVERRIDE {
    108     client_->RemoveObserver(&observer_);
    109   }
    110 
    111   void Register() {
    112     EXPECT_CALL(observer_, OnRegistrationStateChanged(_));
    113     client_->SetupRegistration(kDMToken, client_id_);
    114   }
    115 
    116   void CreateClient(UserAffiliation user_affiliation) {
    117     if (client_.get())
    118       client_->RemoveObserver(&observer_);
    119 
    120     request_context_ = new net::TestURLRequestContextGetter(
    121         loop_.message_loop_proxy());
    122     client_.reset(new CloudPolicyClient(kMachineID, kMachineModel,
    123                                         kPolicyVerificationKeyHash,
    124                                         user_affiliation, &status_provider_,
    125                                         &service_,
    126                                         request_context_));
    127     client_->AddNamespaceToFetch(policy_ns_key_);
    128     client_->AddObserver(&observer_);
    129   }
    130 
    131   void ExpectRegistration(const std::string& oauth_token) {
    132     EXPECT_CALL(service_,
    133                 CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION,
    134                           request_context_))
    135         .WillOnce(service_.SucceedJob(registration_response_));
    136     EXPECT_CALL(service_, StartJob(dm_protocol::kValueRequestRegister,
    137                                    "", oauth_token, "", "", _,
    138                                    MatchProto(registration_request_)))
    139         .WillOnce(SaveArg<5>(&client_id_));
    140   }
    141 
    142   void ExpectPolicyFetch(const std::string& dm_token,
    143                          const std::string& user_affiliation) {
    144     EXPECT_CALL(service_,
    145                 CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH,
    146                           request_context_))
    147         .WillOnce(service_.SucceedJob(policy_response_));
    148     EXPECT_CALL(service_, StartJob(dm_protocol::kValueRequestPolicy,
    149                                    "", "", dm_token, user_affiliation,
    150                                    client_id_,
    151                                    MatchProto(policy_request_)));
    152   }
    153 
    154   void ExpectUnregistration(const std::string& dm_token) {
    155     EXPECT_CALL(service_,
    156                 CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION,
    157                           request_context_))
    158         .WillOnce(service_.SucceedJob(unregistration_response_));
    159     EXPECT_CALL(service_, StartJob(dm_protocol::kValueRequestUnregister,
    160                                    "", "", dm_token, "", client_id_,
    161                                    MatchProto(unregistration_request_)));
    162   }
    163 
    164   void ExpectUploadCertificate() {
    165     EXPECT_CALL(service_,
    166                 CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_CERTIFICATE,
    167                           request_context_))
    168         .WillOnce(service_.SucceedJob(upload_certificate_response_));
    169     EXPECT_CALL(service_, StartJob(dm_protocol::kValueRequestUploadCertificate,
    170                                    "", "", kDMToken, "", client_id_,
    171                                    MatchProto(upload_certificate_request_)));
    172   }
    173 
    174   void CheckPolicyResponse() {
    175     ASSERT_TRUE(client_->GetPolicyFor(policy_ns_key_));
    176     EXPECT_THAT(*client_->GetPolicyFor(policy_ns_key_),
    177                 MatchProto(policy_response_.policy_response().response(0)));
    178   }
    179 
    180   std::string CreatePolicyData(const std::string& policy_value) {
    181     em::PolicyData policy_data;
    182     policy_data.set_policy_type(dm_protocol::kChromeUserPolicyType);
    183     policy_data.set_policy_value(policy_value);
    184     return policy_data.SerializeAsString();
    185   }
    186 
    187   // Request protobufs used as expectations for the client requests.
    188   em::DeviceManagementRequest registration_request_;
    189   em::DeviceManagementRequest policy_request_;
    190   em::DeviceManagementRequest unregistration_request_;
    191   em::DeviceManagementRequest upload_certificate_request_;
    192 
    193   // Protobufs used in successful responses.
    194   em::DeviceManagementResponse registration_response_;
    195   em::DeviceManagementResponse policy_response_;
    196   em::DeviceManagementResponse unregistration_response_;
    197   em::DeviceManagementResponse upload_certificate_response_;
    198 
    199   base::MessageLoop loop_;
    200   std::string client_id_;
    201   PolicyNamespaceKey policy_ns_key_;
    202   MockDeviceManagementService service_;
    203   StrictMock<MockStatusProvider> status_provider_;
    204   StrictMock<MockCloudPolicyClientObserver> observer_;
    205   StrictMock<MockUploadCertificateObserver> upload_certificate_observer_;
    206   scoped_ptr<CloudPolicyClient> client_;
    207   // Cached weak pointer to the client's request context.
    208   net::URLRequestContextGetter* request_context_;
    209 };
    210 
    211 TEST_F(CloudPolicyClientTest, Init) {
    212   EXPECT_CALL(service_, CreateJob(_, _)).Times(0);
    213   EXPECT_FALSE(client_->is_registered());
    214   EXPECT_FALSE(client_->GetPolicyFor(policy_ns_key_));
    215   EXPECT_EQ(0, client_->fetched_invalidation_version());
    216 }
    217 
    218 TEST_F(CloudPolicyClientTest, SetupRegistrationAndPolicyFetch) {
    219   EXPECT_CALL(service_, CreateJob(_, _)).Times(0);
    220   EXPECT_CALL(observer_, OnRegistrationStateChanged(_));
    221   client_->SetupRegistration(kDMToken, client_id_);
    222   EXPECT_TRUE(client_->is_registered());
    223   EXPECT_FALSE(client_->GetPolicyFor(policy_ns_key_));
    224 
    225   ExpectPolicyFetch(kDMToken, dm_protocol::kValueUserAffiliationNone);
    226   EXPECT_CALL(observer_, OnPolicyFetched(_));
    227   EXPECT_CALL(status_provider_, OnSubmittedSuccessfully());
    228   client_->FetchPolicy();
    229   EXPECT_EQ(DM_STATUS_SUCCESS, client_->status());
    230   CheckPolicyResponse();
    231 }
    232 
    233 TEST_F(CloudPolicyClientTest, RegistrationAndPolicyFetch) {
    234   ExpectRegistration(kOAuthToken);
    235   EXPECT_CALL(observer_, OnRegistrationStateChanged(_));
    236   client_->Register(em::DeviceRegisterRequest::USER, kOAuthToken, std::string(),
    237                     false, std::string(), std::string());
    238   EXPECT_TRUE(client_->is_registered());
    239   EXPECT_FALSE(client_->GetPolicyFor(policy_ns_key_));
    240   EXPECT_EQ(DM_STATUS_SUCCESS, client_->status());
    241 
    242   ExpectPolicyFetch(kDMToken, dm_protocol::kValueUserAffiliationNone);
    243   EXPECT_CALL(observer_, OnPolicyFetched(_));
    244   EXPECT_CALL(status_provider_, OnSubmittedSuccessfully());
    245   client_->FetchPolicy();
    246   EXPECT_EQ(DM_STATUS_SUCCESS, client_->status());
    247   CheckPolicyResponse();
    248 }
    249 
    250 TEST_F(CloudPolicyClientTest, RegistrationParameters) {
    251   registration_request_.mutable_register_request()->set_reregister(true);
    252   registration_request_.mutable_register_request()->set_auto_enrolled(true);
    253   registration_request_.mutable_register_request()->set_requisition(
    254       kRequisition);
    255   registration_request_.mutable_register_request()->set_server_backed_state_key(
    256       kStateKey);
    257   ExpectRegistration(kOAuthToken);
    258   EXPECT_CALL(observer_, OnRegistrationStateChanged(_));
    259   client_->Register(em::DeviceRegisterRequest::USER, kOAuthToken, kClientID,
    260                     true, kRequisition, kStateKey);
    261   EXPECT_EQ(kClientID, client_id_);
    262 }
    263 
    264 TEST_F(CloudPolicyClientTest, RegistrationNoToken) {
    265   registration_response_.mutable_register_response()->
    266       clear_device_management_token();
    267   ExpectRegistration(kOAuthToken);
    268   EXPECT_CALL(observer_, OnClientError(_));
    269   client_->Register(em::DeviceRegisterRequest::USER, kOAuthToken, std::string(),
    270                     false, std::string(), std::string());
    271   EXPECT_FALSE(client_->is_registered());
    272   EXPECT_FALSE(client_->GetPolicyFor(policy_ns_key_));
    273   EXPECT_EQ(DM_STATUS_RESPONSE_DECODING_ERROR, client_->status());
    274 }
    275 
    276 TEST_F(CloudPolicyClientTest, RegistrationFailure) {
    277   EXPECT_CALL(service_,
    278               CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION,
    279                         request_context_))
    280       .WillOnce(service_.FailJob(DM_STATUS_REQUEST_FAILED));
    281   EXPECT_CALL(service_, StartJob(_, _, _, _, _, _, _));
    282   EXPECT_CALL(observer_, OnClientError(_));
    283   client_->Register(em::DeviceRegisterRequest::USER, kOAuthToken, std::string(),
    284                     false, std::string(), std::string());
    285   EXPECT_FALSE(client_->is_registered());
    286   EXPECT_FALSE(client_->GetPolicyFor(policy_ns_key_));
    287   EXPECT_EQ(DM_STATUS_REQUEST_FAILED, client_->status());
    288 }
    289 
    290 TEST_F(CloudPolicyClientTest, RetryRegistration) {
    291   // First registration does not set the re-register flag.
    292   EXPECT_FALSE(
    293       registration_request_.mutable_register_request()->has_reregister());
    294   MockDeviceManagementJob* register_job = NULL;
    295   EXPECT_CALL(service_,
    296               CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION,
    297                         request_context_))
    298       .WillOnce(service_.CreateAsyncJob(&register_job));
    299   EXPECT_CALL(service_, StartJob(dm_protocol::kValueRequestRegister,
    300                                  "", kOAuthToken, "", "", _,
    301                                  MatchProto(registration_request_)));
    302   client_->Register(em::DeviceRegisterRequest::USER, kOAuthToken, std::string(),
    303                     false, std::string(), std::string());
    304   EXPECT_FALSE(client_->is_registered());
    305   Mock::VerifyAndClearExpectations(&service_);
    306 
    307   // Simulate a retry callback before proceeding; the re-register flag is set.
    308   registration_request_.mutable_register_request()->set_reregister(true);
    309   EXPECT_CALL(service_, StartJob(dm_protocol::kValueRequestRegister,
    310                                  "", kOAuthToken, "", "", _,
    311                                  MatchProto(registration_request_)));
    312   register_job->RetryJob();
    313   Mock::VerifyAndClearExpectations(&service_);
    314 
    315   // Subsequent retries keep the flag set.
    316   EXPECT_CALL(service_, StartJob(dm_protocol::kValueRequestRegister,
    317                                  "", kOAuthToken, "", "", _,
    318                                  MatchProto(registration_request_)));
    319   register_job->RetryJob();
    320   Mock::VerifyAndClearExpectations(&service_);
    321 }
    322 
    323 TEST_F(CloudPolicyClientTest, PolicyUpdate) {
    324   Register();
    325 
    326   ExpectPolicyFetch(kDMToken, dm_protocol::kValueUserAffiliationNone);
    327   EXPECT_CALL(observer_, OnPolicyFetched(_));
    328   EXPECT_CALL(status_provider_, OnSubmittedSuccessfully());
    329   client_->FetchPolicy();
    330   CheckPolicyResponse();
    331 
    332   policy_response_.mutable_policy_response()->clear_response();
    333   policy_response_.mutable_policy_response()->add_response()->set_policy_data(
    334       CreatePolicyData("updated-fake-policy-data"));
    335   ExpectPolicyFetch(kDMToken, dm_protocol::kValueUserAffiliationNone);
    336   EXPECT_CALL(observer_, OnPolicyFetched(_));
    337   EXPECT_CALL(status_provider_, OnSubmittedSuccessfully());
    338   client_->FetchPolicy();
    339   EXPECT_EQ(DM_STATUS_SUCCESS, client_->status());
    340   CheckPolicyResponse();
    341 }
    342 
    343 TEST_F(CloudPolicyClientTest, PolicyFetchWithMetaData) {
    344   Register();
    345 
    346   const base::Time timestamp(
    347       base::Time::UnixEpoch() + base::TimeDelta::FromDays(20));
    348   client_->set_submit_machine_id(true);
    349   client_->set_last_policy_timestamp(timestamp);
    350   client_->set_public_key_version(42);
    351   em::PolicyFetchRequest* policy_fetch_request =
    352       policy_request_.mutable_policy_request()->mutable_request(0);
    353   policy_fetch_request->set_machine_id(kMachineID);
    354   policy_fetch_request->set_timestamp(
    355       (timestamp - base::Time::UnixEpoch()).InMilliseconds());
    356   policy_fetch_request->set_public_key_version(42);
    357 
    358   ExpectPolicyFetch(kDMToken, dm_protocol::kValueUserAffiliationNone);
    359   EXPECT_CALL(observer_, OnPolicyFetched(_));
    360   EXPECT_CALL(status_provider_, OnSubmittedSuccessfully());
    361   client_->FetchPolicy();
    362   CheckPolicyResponse();
    363 }
    364 
    365 TEST_F(CloudPolicyClientTest, PolicyFetchWithInvalidation) {
    366   Register();
    367 
    368   int64 previous_version = client_->fetched_invalidation_version();
    369   client_->SetInvalidationInfo(12345, "12345");
    370   EXPECT_EQ(previous_version, client_->fetched_invalidation_version());
    371   em::PolicyFetchRequest* policy_fetch_request =
    372       policy_request_.mutable_policy_request()->mutable_request(0);
    373   policy_fetch_request->set_invalidation_version(12345);
    374   policy_fetch_request->set_invalidation_payload("12345");
    375 
    376   ExpectPolicyFetch(kDMToken, dm_protocol::kValueUserAffiliationNone);
    377   EXPECT_CALL(observer_, OnPolicyFetched(_));
    378   EXPECT_CALL(status_provider_, OnSubmittedSuccessfully());
    379   client_->FetchPolicy();
    380   CheckPolicyResponse();
    381   EXPECT_EQ(12345, client_->fetched_invalidation_version());
    382 }
    383 
    384 TEST_F(CloudPolicyClientTest, PolicyFetchWithInvalidationNoPayload) {
    385   Register();
    386 
    387   int64 previous_version = client_->fetched_invalidation_version();
    388   client_->SetInvalidationInfo(-12345, std::string());
    389   EXPECT_EQ(previous_version, client_->fetched_invalidation_version());
    390 
    391   ExpectPolicyFetch(kDMToken, dm_protocol::kValueUserAffiliationNone);
    392   EXPECT_CALL(observer_, OnPolicyFetched(_));
    393   EXPECT_CALL(status_provider_, OnSubmittedSuccessfully());
    394   client_->FetchPolicy();
    395   CheckPolicyResponse();
    396   EXPECT_EQ(-12345, client_->fetched_invalidation_version());
    397 }
    398 
    399 TEST_F(CloudPolicyClientTest, BadPolicyResponse) {
    400   Register();
    401 
    402   policy_response_.clear_policy_response();
    403   ExpectPolicyFetch(kDMToken, dm_protocol::kValueUserAffiliationNone);
    404   EXPECT_CALL(observer_, OnClientError(_));
    405   client_->FetchPolicy();
    406   EXPECT_FALSE(client_->GetPolicyFor(policy_ns_key_));
    407   EXPECT_EQ(DM_STATUS_RESPONSE_DECODING_ERROR, client_->status());
    408 
    409   policy_response_.mutable_policy_response()->add_response()->set_policy_data(
    410       CreatePolicyData("fake-policy-data"));
    411   policy_response_.mutable_policy_response()->add_response()->set_policy_data(
    412       CreatePolicyData("excess-fake-policy-data"));
    413   ExpectPolicyFetch(kDMToken, dm_protocol::kValueUserAffiliationNone);
    414   EXPECT_CALL(observer_, OnPolicyFetched(_));
    415   EXPECT_CALL(status_provider_, OnSubmittedSuccessfully());
    416   client_->FetchPolicy();
    417   EXPECT_EQ(DM_STATUS_SUCCESS, client_->status());
    418   CheckPolicyResponse();
    419 }
    420 
    421 TEST_F(CloudPolicyClientTest, PolicyRequestFailure) {
    422   Register();
    423 
    424   EXPECT_CALL(service_,
    425               CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH,
    426                         request_context_))
    427       .WillOnce(service_.FailJob(DM_STATUS_REQUEST_FAILED));
    428   EXPECT_CALL(service_, StartJob(_, _, _, _, _, _, _));
    429   EXPECT_CALL(observer_, OnClientError(_));
    430   EXPECT_CALL(status_provider_, OnSubmittedSuccessfully()).Times(0);
    431   client_->FetchPolicy();
    432   EXPECT_EQ(DM_STATUS_REQUEST_FAILED, client_->status());
    433   EXPECT_FALSE(client_->GetPolicyFor(policy_ns_key_));
    434 }
    435 
    436 TEST_F(CloudPolicyClientTest, Unregister) {
    437   Register();
    438 
    439   ExpectUnregistration(kDMToken);
    440   EXPECT_CALL(observer_, OnRegistrationStateChanged(_));
    441   client_->Unregister();
    442   EXPECT_FALSE(client_->is_registered());
    443   EXPECT_EQ(DM_STATUS_SUCCESS, client_->status());
    444 }
    445 
    446 TEST_F(CloudPolicyClientTest, UnregisterEmpty) {
    447   Register();
    448 
    449   unregistration_response_.clear_unregister_response();
    450   EXPECT_CALL(service_,
    451               CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION,
    452                         request_context_))
    453       .WillOnce(service_.SucceedJob(unregistration_response_));
    454   EXPECT_CALL(service_, StartJob(_, _, _, _, _, _, _));
    455   EXPECT_CALL(observer_, OnRegistrationStateChanged(_));
    456   client_->Unregister();
    457   EXPECT_FALSE(client_->is_registered());
    458   EXPECT_EQ(DM_STATUS_SUCCESS, client_->status());
    459 }
    460 
    461 TEST_F(CloudPolicyClientTest, UnregisterFailure) {
    462   Register();
    463 
    464   EXPECT_CALL(service_,
    465               CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION,
    466                         request_context_))
    467       .WillOnce(service_.FailJob(DM_STATUS_REQUEST_FAILED));
    468   EXPECT_CALL(service_, StartJob(_, _, _, _, _, _, _));
    469   EXPECT_CALL(observer_, OnClientError(_));
    470   client_->Unregister();
    471   EXPECT_TRUE(client_->is_registered());
    472   EXPECT_EQ(DM_STATUS_REQUEST_FAILED, client_->status());
    473 }
    474 
    475 TEST_F(CloudPolicyClientTest, PolicyFetchWithExtensionPolicy) {
    476   Register();
    477 
    478   // Setup the |expected_responses| and |policy_response_|.
    479   static const char* kExtensions[] = {
    480     "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    481     "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    482     "cccccccccccccccccccccccccccccccc",
    483   };
    484   typedef std::map<PolicyNamespaceKey, em::PolicyFetchResponse> ResponseMap;
    485   ResponseMap expected_responses;
    486   std::set<PolicyNamespaceKey> expected_namespaces;
    487   PolicyNamespaceKey key(dm_protocol::kChromeUserPolicyType, std::string());
    488   // Copy the user policy fetch request.
    489   expected_responses[key].CopyFrom(
    490       policy_response_.policy_response().response(0));
    491   expected_namespaces.insert(key);
    492   key.first = dm_protocol::kChromeExtensionPolicyType;
    493   for (size_t i = 0; i < arraysize(kExtensions); ++i) {
    494     key.second = kExtensions[i];
    495     em::PolicyData policy_data;
    496     policy_data.set_policy_type(key.first);
    497     policy_data.set_settings_entity_id(key.second);
    498     expected_responses[key].set_policy_data(policy_data.SerializeAsString());
    499     policy_response_.mutable_policy_response()->add_response()->CopyFrom(
    500         expected_responses[key]);
    501     expected_namespaces.insert(key);
    502   }
    503 
    504   // Make a policy fetch.
    505   EXPECT_CALL(service_,
    506               CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH,
    507                         request_context_))
    508       .WillOnce(service_.SucceedJob(policy_response_));
    509   EXPECT_CALL(service_, StartJob(dm_protocol::kValueRequestPolicy, "", "",
    510                                  kDMToken,
    511                                  dm_protocol::kValueUserAffiliationNone,
    512                                  client_id_, _))
    513       .WillOnce(SaveArg<6>(&policy_request_));
    514   EXPECT_CALL(observer_, OnPolicyFetched(_));
    515   EXPECT_CALL(status_provider_, OnSubmittedSuccessfully());
    516   for (size_t i = 0; i < arraysize(kExtensions); ++i) {
    517     client_->AddNamespaceToFetch(PolicyNamespaceKey(
    518         dm_protocol::kChromeExtensionPolicyType, kExtensions[i]));
    519   }
    520   client_->FetchPolicy();
    521 
    522   // Verify that the request includes the expected namespaces.
    523   ASSERT_TRUE(policy_request_.has_policy_request());
    524   const em::DevicePolicyRequest& policy_request =
    525       policy_request_.policy_request();
    526   ASSERT_EQ(static_cast<int>(1 + arraysize(kExtensions)),
    527             policy_request.request_size());
    528   for (int i = 0; i < policy_request.request_size(); ++i) {
    529     const em::PolicyFetchRequest& fetch_request = policy_request.request(i);
    530     ASSERT_TRUE(fetch_request.has_policy_type());
    531     std::string entity_id;
    532     if (fetch_request.has_settings_entity_id())
    533       entity_id = fetch_request.settings_entity_id();
    534     PolicyNamespaceKey key(fetch_request.policy_type(), entity_id);
    535     EXPECT_EQ(1u, expected_namespaces.erase(key));
    536   }
    537   EXPECT_TRUE(expected_namespaces.empty());
    538 
    539   // Verify that the client got all the responses mapped to their namespaces.
    540   for (ResponseMap::iterator it = expected_responses.begin();
    541        it != expected_responses.end(); ++it) {
    542     const em::PolicyFetchResponse* response = client_->GetPolicyFor(it->first);
    543     ASSERT_TRUE(response);
    544     EXPECT_EQ(it->second.SerializeAsString(), response->SerializeAsString());
    545   }
    546 }
    547 
    548 TEST_F(CloudPolicyClientTest, UploadCertificate) {
    549   Register();
    550 
    551   ExpectUploadCertificate();
    552   EXPECT_CALL(upload_certificate_observer_, OnUploadComplete(true)).Times(1);
    553   CloudPolicyClient::StatusCallback callback = base::Bind(
    554       &MockUploadCertificateObserver::OnUploadComplete,
    555       base::Unretained(&upload_certificate_observer_));
    556   client_->UploadCertificate(kDeviceCertificate, callback);
    557   EXPECT_EQ(DM_STATUS_SUCCESS, client_->status());
    558 }
    559 
    560 TEST_F(CloudPolicyClientTest, UploadCertificateEmpty) {
    561   Register();
    562 
    563   upload_certificate_response_.clear_cert_upload_response();
    564   ExpectUploadCertificate();
    565   EXPECT_CALL(upload_certificate_observer_, OnUploadComplete(false)).Times(1);
    566   CloudPolicyClient::StatusCallback callback = base::Bind(
    567       &MockUploadCertificateObserver::OnUploadComplete,
    568       base::Unretained(&upload_certificate_observer_));
    569   client_->UploadCertificate(kDeviceCertificate, callback);
    570   EXPECT_EQ(DM_STATUS_SUCCESS, client_->status());
    571 }
    572 
    573 TEST_F(CloudPolicyClientTest, UploadCertificateFailure) {
    574   Register();
    575 
    576   EXPECT_CALL(upload_certificate_observer_, OnUploadComplete(false)).Times(1);
    577   EXPECT_CALL(service_,
    578               CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_CERTIFICATE,
    579                         request_context_))
    580       .WillOnce(service_.FailJob(DM_STATUS_REQUEST_FAILED));
    581   EXPECT_CALL(service_, StartJob(_, _, _, _, _, _, _));
    582   EXPECT_CALL(observer_, OnClientError(_));
    583   CloudPolicyClient::StatusCallback callback = base::Bind(
    584       &MockUploadCertificateObserver::OnUploadComplete,
    585       base::Unretained(&upload_certificate_observer_));
    586   client_->UploadCertificate(kDeviceCertificate, callback);
    587   EXPECT_EQ(DM_STATUS_REQUEST_FAILED, client_->status());
    588 }
    589 
    590 }  // namespace policy
    591