Home | History | Annotate | Download | only in network
      1 // Copyright (c) 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.
      4 
      5 #include "chromeos/network/managed_network_configuration_handler.h"
      6 
      7 #include <iostream>
      8 #include <sstream>
      9 
     10 #include "base/message_loop/message_loop.h"
     11 #include "chromeos/dbus/dbus_thread_manager.h"
     12 #include "chromeos/dbus/mock_dbus_thread_manager.h"
     13 #include "chromeos/dbus/mock_shill_manager_client.h"
     14 #include "chromeos/dbus/mock_shill_profile_client.h"
     15 #include "chromeos/dbus/mock_shill_service_client.h"
     16 #include "chromeos/dbus/shill_profile_client_stub.h"
     17 #include "chromeos/network/network_configuration_handler.h"
     18 #include "chromeos/network/network_profile_handler.h"
     19 #include "chromeos/network/onc/onc_test_utils.h"
     20 #include "chromeos/network/onc/onc_utils.h"
     21 #include "dbus/object_path.h"
     22 #include "testing/gmock/include/gmock/gmock.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 #include "third_party/cros_system_api/dbus/service_constants.h"
     25 
     26 using ::testing::AnyNumber;
     27 using ::testing::Invoke;
     28 using ::testing::Mock;
     29 using ::testing::Pointee;
     30 using ::testing::Return;
     31 using ::testing::SaveArg;
     32 using ::testing::StrEq;
     33 using ::testing::StrictMock;
     34 using ::testing::_;
     35 
     36 namespace test_utils = ::chromeos::onc::test_utils;
     37 
     38 namespace chromeos {
     39 
     40 namespace {
     41 
     42 std::string ValueToString(const base::Value* value) {
     43   std::stringstream str;
     44   str << *value;
     45   return str.str();
     46 }
     47 
     48 const char kSharedProfilePath[] = "/profile/default";
     49 const char kUser1[] = "user1";
     50 const char kUser1ProfilePath[] = "/profile/user1/shill";
     51 
     52 // Matcher to match base::Value.
     53 MATCHER_P(IsEqualTo,
     54           value,
     55           std::string(negation ? "isn't" : "is") + " equal to " +
     56           ValueToString(value)) {
     57   return value->Equals(&arg);
     58 }
     59 
     60 class ShillProfileTestClient {
     61  public:
     62   typedef ShillClientHelper::DictionaryValueCallbackWithoutStatus
     63       DictionaryValueCallbackWithoutStatus;
     64   typedef ShillClientHelper::ErrorCallback ErrorCallback;
     65 
     66   void AddProfile(const std::string& profile_path,
     67                   const std::string& userhash) {
     68     if (profile_entries_.HasKey(profile_path))
     69       return;
     70 
     71     base::DictionaryValue* profile = new base::DictionaryValue;
     72     profile_entries_.SetWithoutPathExpansion(profile_path, profile);
     73     profile_to_user_[profile_path] = userhash;
     74   }
     75 
     76   void AddEntry(const std::string& profile_path,
     77                 const std::string& entry_path,
     78                 const base::DictionaryValue& entry) {
     79     base::DictionaryValue* entries = NULL;
     80     profile_entries_.GetDictionaryWithoutPathExpansion(profile_path, &entries);
     81     ASSERT_TRUE(entries);
     82 
     83     base::DictionaryValue* new_entry = entry.DeepCopy();
     84     new_entry->SetStringWithoutPathExpansion(flimflam::kProfileProperty,
     85                                              profile_path);
     86     entries->SetWithoutPathExpansion(entry_path, new_entry);
     87   }
     88 
     89   void GetProperties(const dbus::ObjectPath& profile_path,
     90                      const DictionaryValueCallbackWithoutStatus& callback,
     91                      const ErrorCallback& error_callback) {
     92     base::DictionaryValue* entries = NULL;
     93     profile_entries_.GetDictionaryWithoutPathExpansion(profile_path.value(),
     94                                                        &entries);
     95     ASSERT_TRUE(entries);
     96 
     97     scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
     98     base::ListValue* entry_paths = new base::ListValue;
     99     result->SetWithoutPathExpansion(flimflam::kEntriesProperty,
    100                                     entry_paths);
    101     for (base::DictionaryValue::Iterator it(*entries); !it.IsAtEnd();
    102          it.Advance()) {
    103       entry_paths->AppendString(it.key());
    104     }
    105 
    106     ASSERT_GT(profile_to_user_.count(profile_path.value()), 0UL);
    107     const std::string& userhash = profile_to_user_[profile_path.value()];
    108     result->SetStringWithoutPathExpansion(shill::kUserHashProperty, userhash);
    109 
    110     callback.Run(*result);
    111   }
    112 
    113   void GetEntry(const dbus::ObjectPath& profile_path,
    114                 const std::string& entry_path,
    115                 const DictionaryValueCallbackWithoutStatus& callback,
    116                 const ErrorCallback& error_callback) {
    117     base::DictionaryValue* entries = NULL;
    118     profile_entries_.GetDictionaryWithoutPathExpansion(profile_path.value(),
    119                                                        &entries);
    120     ASSERT_TRUE(entries);
    121 
    122     base::DictionaryValue* entry = NULL;
    123     entries->GetDictionaryWithoutPathExpansion(entry_path, &entry);
    124     ASSERT_TRUE(entry);
    125     callback.Run(*entry);
    126   }
    127 
    128  protected:
    129   base::DictionaryValue profile_entries_;
    130   std::map<std::string, std::string> profile_to_user_;
    131 };
    132 
    133 class TestNetworkProfileHandler : public NetworkProfileHandler {
    134  public:
    135   TestNetworkProfileHandler() {
    136     Init(NULL /* No NetworkStateHandler */);
    137   }
    138   virtual ~TestNetworkProfileHandler() {}
    139 
    140   void AddProfileForTest(const NetworkProfile& profile) {
    141     AddProfile(profile);
    142   }
    143 
    144  private:
    145   DISALLOW_COPY_AND_ASSIGN(TestNetworkProfileHandler);
    146 };
    147 
    148 }  // namespace
    149 
    150 class ManagedNetworkConfigurationHandlerTest : public testing::Test {
    151  public:
    152   ManagedNetworkConfigurationHandlerTest() {
    153   }
    154 
    155   virtual ~ManagedNetworkConfigurationHandlerTest() {
    156   }
    157 
    158   virtual void SetUp() OVERRIDE {
    159     MockDBusThreadManager* dbus_thread_manager = new MockDBusThreadManager;
    160     EXPECT_CALL(*dbus_thread_manager, GetSystemBus())
    161         .WillRepeatedly(Return(static_cast<dbus::Bus*>(NULL)));
    162     DBusThreadManager::InitializeForTesting(dbus_thread_manager);
    163 
    164     SetNetworkConfigurationHandlerExpectations();
    165 
    166     EXPECT_CALL(*dbus_thread_manager, GetShillManagerClient())
    167         .WillRepeatedly(Return(&mock_manager_client_));
    168     EXPECT_CALL(*dbus_thread_manager, GetShillServiceClient())
    169         .WillRepeatedly(Return(&mock_service_client_));
    170     EXPECT_CALL(*dbus_thread_manager, GetShillProfileClient())
    171         .WillRepeatedly(Return(&mock_profile_client_));
    172 
    173     ON_CALL(mock_profile_client_, GetProperties(_,_,_))
    174         .WillByDefault(Invoke(&profiles_stub_,
    175                               &ShillProfileTestClient::GetProperties));
    176 
    177     ON_CALL(mock_profile_client_, GetEntry(_,_,_,_))
    178         .WillByDefault(Invoke(&profiles_stub_,
    179                               &ShillProfileTestClient::GetEntry));
    180 
    181     network_profile_handler_.reset(new TestNetworkProfileHandler());
    182     network_configuration_handler_.reset(
    183         NetworkConfigurationHandler::InitializeForTest(
    184             NULL /* no NetworkStateHandler */));
    185     managed_network_configuration_handler_.reset(
    186         new ManagedNetworkConfigurationHandler());
    187     managed_network_configuration_handler_->Init(
    188         NULL /* no NetworkStateHandler */,
    189         network_profile_handler_.get(),
    190         network_configuration_handler_.get());
    191 
    192     message_loop_.RunUntilIdle();
    193   }
    194 
    195   virtual void TearDown() OVERRIDE {
    196     managed_network_configuration_handler_.reset();
    197     network_configuration_handler_.reset();
    198     network_profile_handler_.reset();
    199     DBusThreadManager::Shutdown();
    200   }
    201 
    202   void VerifyAndClearExpectations() {
    203     Mock::VerifyAndClearExpectations(&mock_manager_client_);
    204     Mock::VerifyAndClearExpectations(&mock_service_client_);
    205     Mock::VerifyAndClearExpectations(&mock_profile_client_);
    206     SetNetworkConfigurationHandlerExpectations();
    207   }
    208 
    209   void InitializeStandardProfiles() {
    210     profiles_stub_.AddProfile(kUser1ProfilePath, kUser1);
    211     network_profile_handler_->
    212         AddProfileForTest(NetworkProfile(kUser1ProfilePath, kUser1));
    213     network_profile_handler_->
    214         AddProfileForTest(NetworkProfile(kSharedProfilePath, std::string()));
    215   }
    216 
    217   void SetUpEntry(const std::string& path_to_shill_json,
    218                   const std::string& profile_path,
    219                   const std::string& entry_path) {
    220     scoped_ptr<base::DictionaryValue> entry =
    221         test_utils::ReadTestDictionary(path_to_shill_json);
    222     profiles_stub_.AddEntry(profile_path, entry_path, *entry);
    223   }
    224 
    225   void SetPolicy(onc::ONCSource onc_source,
    226                  const std::string& userhash,
    227                  const std::string& path_to_onc) {
    228     scoped_ptr<base::DictionaryValue> policy;
    229     if (path_to_onc.empty())
    230       policy = onc::ReadDictionaryFromJson(onc::kEmptyUnencryptedConfiguration);
    231     else
    232       policy = test_utils::ReadTestDictionary(path_to_onc);
    233 
    234     base::ListValue* network_configs = NULL;
    235     policy->GetListWithoutPathExpansion(
    236         onc::toplevel_config::kNetworkConfigurations, &network_configs);
    237 
    238     managed_handler()->SetPolicy(
    239         onc::ONC_SOURCE_USER_POLICY, userhash, *network_configs);
    240   }
    241 
    242   void SetNetworkConfigurationHandlerExpectations() {
    243     // These calls occur in NetworkConfigurationHandler.
    244     EXPECT_CALL(mock_manager_client_, GetProperties(_)).Times(AnyNumber());
    245     EXPECT_CALL(mock_manager_client_,
    246                 AddPropertyChangedObserver(_)).Times(AnyNumber());
    247     EXPECT_CALL(mock_manager_client_,
    248                 RemovePropertyChangedObserver(_)).Times(AnyNumber());
    249   }
    250 
    251   ManagedNetworkConfigurationHandler* managed_handler() {
    252     return managed_network_configuration_handler_.get();
    253   }
    254 
    255  protected:
    256   StrictMock<MockShillManagerClient> mock_manager_client_;
    257   StrictMock<MockShillServiceClient> mock_service_client_;
    258   StrictMock<MockShillProfileClient> mock_profile_client_;
    259   ShillProfileTestClient profiles_stub_;
    260   scoped_ptr<TestNetworkProfileHandler> network_profile_handler_;
    261   scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
    262   scoped_ptr<ManagedNetworkConfigurationHandler>
    263         managed_network_configuration_handler_;
    264   base::MessageLoop message_loop_;
    265 
    266  private:
    267   DISALLOW_COPY_AND_ASSIGN(ManagedNetworkConfigurationHandlerTest);
    268 };
    269 
    270 TEST_F(ManagedNetworkConfigurationHandlerTest, ProfileInitialization) {
    271   InitializeStandardProfiles();
    272   message_loop_.RunUntilIdle();
    273 }
    274 
    275 TEST_F(ManagedNetworkConfigurationHandlerTest, RemoveIrrelevantFields) {
    276   InitializeStandardProfiles();
    277   scoped_ptr<base::DictionaryValue> expected_shill_properties =
    278       test_utils::ReadTestDictionary(
    279           "policy/shill_policy_on_unconfigured_wifi1.json");
    280 
    281   EXPECT_CALL(mock_profile_client_,
    282               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    283 
    284   EXPECT_CALL(mock_manager_client_,
    285               ConfigureServiceForProfile(
    286                   dbus::ObjectPath(kUser1ProfilePath),
    287                   IsEqualTo(expected_shill_properties.get()),
    288                   _, _));
    289 
    290   SetPolicy(onc::ONC_SOURCE_USER_POLICY,
    291             kUser1,
    292             "policy/policy_wifi1_with_redundant_fields.onc");
    293   message_loop_.RunUntilIdle();
    294 }
    295 
    296 TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyManageUnconfigured) {
    297   InitializeStandardProfiles();
    298   scoped_ptr<base::DictionaryValue> expected_shill_properties =
    299       test_utils::ReadTestDictionary(
    300           "policy/shill_policy_on_unconfigured_wifi1.json");
    301 
    302   EXPECT_CALL(mock_profile_client_,
    303               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    304 
    305   EXPECT_CALL(mock_manager_client_,
    306               ConfigureServiceForProfile(
    307                   dbus::ObjectPath(kUser1ProfilePath),
    308                   IsEqualTo(expected_shill_properties.get()),
    309                   _, _));
    310 
    311   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
    312   message_loop_.RunUntilIdle();
    313 }
    314 
    315 TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyIgnoreUnmodified) {
    316   InitializeStandardProfiles();
    317   EXPECT_CALL(mock_profile_client_, GetProperties(_, _, _));
    318 
    319   EXPECT_CALL(mock_manager_client_, ConfigureServiceForProfile(_, _, _, _));
    320 
    321   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
    322   message_loop_.RunUntilIdle();
    323   VerifyAndClearExpectations();
    324 
    325   SetUpEntry("policy/shill_policy_on_unmanaged_user_wifi1.json",
    326              kUser1ProfilePath,
    327              "some_entry_path");
    328 
    329   EXPECT_CALL(mock_profile_client_, GetProperties(_, _, _));
    330 
    331   EXPECT_CALL(mock_profile_client_,
    332               GetEntry(dbus::ObjectPath(kUser1ProfilePath),
    333                        "some_entry_path",
    334                        _, _));
    335 
    336   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
    337   message_loop_.RunUntilIdle();
    338 }
    339 
    340 TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyManageUnmanaged) {
    341   InitializeStandardProfiles();
    342   SetUpEntry("policy/shill_unmanaged_user_wifi1.json",
    343              kUser1ProfilePath,
    344              "old_entry_path");
    345 
    346   scoped_ptr<base::DictionaryValue> expected_shill_properties =
    347       test_utils::ReadTestDictionary(
    348           "policy/shill_policy_on_unmanaged_user_wifi1.json");
    349 
    350   EXPECT_CALL(mock_profile_client_,
    351               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    352 
    353   EXPECT_CALL(
    354       mock_profile_client_,
    355       GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
    356 
    357   EXPECT_CALL(
    358       mock_profile_client_,
    359       DeleteEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
    360 
    361   EXPECT_CALL(mock_manager_client_,
    362               ConfigureServiceForProfile(
    363                   dbus::ObjectPath(kUser1ProfilePath),
    364                   IsEqualTo(expected_shill_properties.get()),
    365                   _, _));
    366 
    367   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
    368   message_loop_.RunUntilIdle();
    369 }
    370 
    371 // Old ChromeOS versions may not have used the UIData property
    372 TEST_F(ManagedNetworkConfigurationHandlerTest,
    373        SetPolicyManageUnmanagedWithoutUIData) {
    374   InitializeStandardProfiles();
    375   SetUpEntry("policy/shill_unmanaged_user_wifi1.json",
    376              kUser1ProfilePath,
    377              "old_entry_path");
    378 
    379   scoped_ptr<base::DictionaryValue> expected_shill_properties =
    380       test_utils::ReadTestDictionary(
    381           "policy/shill_policy_on_unmanaged_user_wifi1.json");
    382 
    383   EXPECT_CALL(mock_profile_client_,
    384               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    385 
    386   EXPECT_CALL(
    387       mock_profile_client_,
    388       GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
    389 
    390   EXPECT_CALL(
    391       mock_profile_client_,
    392       DeleteEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
    393 
    394   EXPECT_CALL(mock_manager_client_,
    395               ConfigureServiceForProfile(
    396                   dbus::ObjectPath(kUser1ProfilePath),
    397                   IsEqualTo(expected_shill_properties.get()),
    398                   _, _));
    399 
    400   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
    401   message_loop_.RunUntilIdle();
    402 }
    403 
    404 TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyUpdateManagedNewGUID) {
    405   InitializeStandardProfiles();
    406   SetUpEntry("policy/shill_managed_wifi1.json",
    407              kUser1ProfilePath,
    408              "old_entry_path");
    409 
    410   scoped_ptr<base::DictionaryValue> expected_shill_properties =
    411       test_utils::ReadTestDictionary(
    412           "policy/shill_policy_on_unmanaged_user_wifi1.json");
    413 
    414   // The passphrase isn't sent again, because it's configured by the user and
    415   // Shill doesn't sent it on GetProperties calls.
    416   expected_shill_properties->RemoveWithoutPathExpansion(
    417       flimflam::kPassphraseProperty, NULL);
    418 
    419   EXPECT_CALL(mock_profile_client_,
    420               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    421 
    422   EXPECT_CALL(
    423       mock_profile_client_,
    424       GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
    425 
    426   EXPECT_CALL(
    427       mock_profile_client_,
    428       DeleteEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
    429 
    430   EXPECT_CALL(mock_manager_client_,
    431               ConfigureServiceForProfile(
    432                   dbus::ObjectPath(kUser1ProfilePath),
    433                   IsEqualTo(expected_shill_properties.get()),
    434                   _, _));
    435 
    436   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
    437   message_loop_.RunUntilIdle();
    438 }
    439 
    440 TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyReapplyToManaged) {
    441   InitializeStandardProfiles();
    442   SetUpEntry("policy/shill_policy_on_unmanaged_user_wifi1.json",
    443              kUser1ProfilePath,
    444              "old_entry_path");
    445 
    446   scoped_ptr<base::DictionaryValue> expected_shill_properties =
    447       test_utils::ReadTestDictionary(
    448           "policy/shill_policy_on_unmanaged_user_wifi1.json");
    449 
    450   // The passphrase isn't sent again, because it's configured by the user and
    451   // Shill doesn't sent it on GetProperties calls.
    452   expected_shill_properties->RemoveWithoutPathExpansion(
    453       flimflam::kPassphraseProperty, NULL);
    454 
    455   EXPECT_CALL(mock_profile_client_,
    456               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    457 
    458   EXPECT_CALL(
    459       mock_profile_client_,
    460       GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
    461 
    462   EXPECT_CALL(mock_manager_client_,
    463               ConfigureServiceForProfile(
    464                   dbus::ObjectPath(kUser1ProfilePath),
    465                   IsEqualTo(expected_shill_properties.get()),
    466                   _, _));
    467 
    468   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
    469   message_loop_.RunUntilIdle();
    470   VerifyAndClearExpectations();
    471 
    472   // If we apply the policy again, without change, then the Shill profile will
    473   // not be modified.
    474   EXPECT_CALL(mock_profile_client_,
    475               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    476 
    477   EXPECT_CALL(
    478       mock_profile_client_,
    479       GetEntry(dbus::ObjectPath(kUser1ProfilePath), "old_entry_path", _, _));
    480 
    481   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
    482   message_loop_.RunUntilIdle();
    483 }
    484 
    485 TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyUnmanageManaged) {
    486   InitializeStandardProfiles();
    487   SetUpEntry("policy/shill_policy_on_unmanaged_user_wifi1.json",
    488              kUser1ProfilePath,
    489              "old_entry_path");
    490 
    491   EXPECT_CALL(mock_profile_client_,
    492               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    493 
    494   EXPECT_CALL(mock_profile_client_,
    495               GetEntry(dbus::ObjectPath(kUser1ProfilePath),
    496                        "old_entry_path",
    497                        _, _));
    498 
    499   EXPECT_CALL(mock_profile_client_,
    500               DeleteEntry(dbus::ObjectPath(kUser1ProfilePath),
    501                           "old_entry_path",
    502                           _, _));
    503 
    504   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "");
    505   message_loop_.RunUntilIdle();
    506 }
    507 
    508 TEST_F(ManagedNetworkConfigurationHandlerTest, SetEmptyPolicyIgnoreUnmanaged) {
    509   InitializeStandardProfiles();
    510   SetUpEntry("policy/shill_unmanaged_user_wifi1.json",
    511              kUser1ProfilePath,
    512              "old_entry_path");
    513 
    514   EXPECT_CALL(mock_profile_client_,
    515               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    516 
    517   EXPECT_CALL(mock_profile_client_,
    518               GetEntry(dbus::ObjectPath(kUser1ProfilePath),
    519                        "old_entry_path",
    520                        _, _));
    521 
    522   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "");
    523   message_loop_.RunUntilIdle();
    524 }
    525 
    526 TEST_F(ManagedNetworkConfigurationHandlerTest, SetPolicyIgnoreUnmanaged) {
    527   InitializeStandardProfiles();
    528   SetUpEntry("policy/shill_unmanaged_user_wifi2.json",
    529              kUser1ProfilePath,
    530              "wifi2_entry_path");
    531 
    532   EXPECT_CALL(mock_profile_client_,
    533               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    534 
    535   EXPECT_CALL(
    536       mock_profile_client_,
    537       GetEntry(dbus::ObjectPath(kUser1ProfilePath), "wifi2_entry_path", _, _));
    538 
    539   scoped_ptr<base::DictionaryValue> expected_shill_properties =
    540       test_utils::ReadTestDictionary(
    541           "policy/shill_policy_on_unconfigured_wifi1.json");
    542 
    543   EXPECT_CALL(mock_manager_client_,
    544               ConfigureServiceForProfile(
    545                   dbus::ObjectPath(kUser1ProfilePath),
    546                   IsEqualTo(expected_shill_properties.get()),
    547                   _, _));
    548 
    549   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
    550   message_loop_.RunUntilIdle();
    551 }
    552 
    553 TEST_F(ManagedNetworkConfigurationHandlerTest, LateProfileLoading) {
    554   SetPolicy(onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc");
    555 
    556   message_loop_.RunUntilIdle();
    557   VerifyAndClearExpectations();
    558 
    559   scoped_ptr<base::DictionaryValue> expected_shill_properties =
    560       test_utils::ReadTestDictionary(
    561           "policy/shill_policy_on_unconfigured_wifi1.json");
    562 
    563   EXPECT_CALL(mock_profile_client_,
    564               GetProperties(dbus::ObjectPath(kUser1ProfilePath), _, _));
    565 
    566   EXPECT_CALL(mock_manager_client_,
    567               ConfigureServiceForProfile(
    568                   dbus::ObjectPath(kUser1ProfilePath),
    569                   IsEqualTo(expected_shill_properties.get()),
    570                   _, _));
    571 
    572   InitializeStandardProfiles();
    573   message_loop_.RunUntilIdle();
    574 }
    575 
    576 }  // namespace chromeos
    577