Home | History | Annotate | Download | only in policy
      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 <algorithm>
      6 #include <map>
      7 #include <sstream>
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/file_util.h"
     13 #include "base/files/file_path.h"
     14 #include "base/json/json_reader.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/memory/scoped_vector.h"
     17 #include "base/prefs/pref_service.h"
     18 #include "base/run_loop.h"
     19 #include "base/stl_util.h"
     20 #include "base/strings/string_util.h"
     21 #include "base/strings/utf_string_conversions.h"
     22 #include "base/values.h"
     23 #include "chrome/browser/browser_process.h"
     24 #include "chrome/browser/policy/browser_policy_connector.h"
     25 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
     26 #include "chrome/browser/policy/policy_map.h"
     27 #include "chrome/browser/profiles/profile.h"
     28 #include "chrome/browser/search_engines/template_url_service_factory.h"
     29 #include "chrome/browser/ui/browser.h"
     30 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     31 #include "chrome/test/base/in_process_browser_test.h"
     32 #include "chrome/test/base/ui_test_utils.h"
     33 #include "content/public/browser/web_contents.h"
     34 #include "content/public/test/browser_test_utils.h"
     35 #include "policy/policy_constants.h"
     36 #include "testing/gmock/include/gmock/gmock.h"
     37 #include "testing/gtest/include/gtest/gtest.h"
     38 #include "url/gurl.h"
     39 
     40 using testing::AnyNumber;
     41 using testing::Return;
     42 using testing::_;
     43 
     44 namespace policy {
     45 
     46 namespace {
     47 
     48 const char kMainSettingsPage[] = "chrome://settings-frame";
     49 
     50 const char kCrosSettingsPrefix[] = "cros.";
     51 
     52 // Contains the details of a single test case verifying that the controlled
     53 // setting indicators for a pref affected by a policy work correctly. This is
     54 // part of the data loaded from chrome/test/data/policy/policy_test_cases.json.
     55 class IndicatorTestCase {
     56  public:
     57   IndicatorTestCase(const base::DictionaryValue& policy,
     58                     const std::string& value,
     59                     bool readonly)
     60       : policy_(policy.DeepCopy()), value_(value), readonly_(readonly) {}
     61   ~IndicatorTestCase() {}
     62 
     63   const base::DictionaryValue& policy() const { return *policy_; }
     64 
     65   const std::string& value() const { return value_; }
     66 
     67   bool readonly() const { return readonly_; }
     68 
     69  private:
     70   scoped_ptr<base::DictionaryValue> policy_;
     71   std::string value_;
     72   bool readonly_;
     73 
     74   DISALLOW_COPY_AND_ASSIGN(IndicatorTestCase);
     75 };
     76 
     77 // Contains the testing details for a single pref affected by a policy. This is
     78 // part of the data loaded from chrome/test/data/policy/policy_test_cases.json.
     79 class PrefMapping {
     80  public:
     81   PrefMapping(const std::string& pref,
     82               bool is_local_state,
     83               const std::string& indicator_test_setup_js,
     84               const std::string& indicator_selector)
     85       : pref_(pref),
     86         is_local_state_(is_local_state),
     87         indicator_test_setup_js_(indicator_test_setup_js),
     88         indicator_selector_(indicator_selector) {
     89   }
     90   ~PrefMapping() {}
     91 
     92   const std::string& pref() const { return pref_; }
     93 
     94   bool is_local_state() const { return is_local_state_; }
     95 
     96   const std::string& indicator_test_setup_js() const {
     97     return indicator_test_setup_js_;
     98   }
     99 
    100   const std::string& indicator_selector() const {
    101     return indicator_selector_;
    102   }
    103 
    104   const ScopedVector<IndicatorTestCase>& indicator_test_cases() const {
    105     return indicator_test_cases_;
    106   }
    107   void AddIndicatorTestCase(IndicatorTestCase* test_case) {
    108     indicator_test_cases_.push_back(test_case);
    109   }
    110 
    111  private:
    112   std::string pref_;
    113   bool is_local_state_;
    114   std::string indicator_test_setup_js_;
    115   std::string indicator_selector_;
    116   ScopedVector<IndicatorTestCase> indicator_test_cases_;
    117 
    118   DISALLOW_COPY_AND_ASSIGN(PrefMapping);
    119 };
    120 
    121 // Contains the testing details for a single policy. This is part of the data
    122 // loaded from chrome/test/data/policy/policy_test_cases.json.
    123 class PolicyTestCase {
    124  public:
    125   PolicyTestCase(const std::string& name,
    126                  bool is_official_only,
    127                  bool can_be_recommended)
    128       : name_(name),
    129         is_official_only_(is_official_only),
    130         can_be_recommended_(can_be_recommended) {}
    131   ~PolicyTestCase() {}
    132 
    133   const std::string& name() const { return name_; }
    134 
    135   bool is_official_only() const { return is_official_only_; }
    136 
    137   bool can_be_recommended() const { return can_be_recommended_; }
    138 
    139   bool IsOsSupported() const {
    140 #if defined(OS_WIN)
    141     const std::string os("win");
    142 #elif defined(OS_MACOSX)
    143     const std::string os("mac");
    144 #elif defined(OS_CHROMEOS)
    145     const std::string os("chromeos");
    146 #elif defined(OS_LINUX)
    147     const std::string os("linux");
    148 #else
    149 #error "Unknown platform"
    150 #endif
    151     return std::find(supported_os_.begin(), supported_os_.end(), os) !=
    152         supported_os_.end();
    153   }
    154   void AddSupportedOs(const std::string& os) { supported_os_.push_back(os); }
    155 
    156   bool IsSupported() const {
    157 #if !defined(OFFICIAL_BUILD)
    158     if (is_official_only())
    159       return false;
    160 #endif
    161     return IsOsSupported();
    162   }
    163 
    164   const PolicyMap& test_policy() const { return test_policy_; }
    165   void SetTestPolicy(const PolicyMap& policy) {
    166     test_policy_.CopyFrom(policy);
    167   }
    168 
    169   const ScopedVector<PrefMapping>& pref_mappings() const {
    170     return pref_mappings_;
    171   }
    172   void AddPrefMapping(PrefMapping* pref_mapping) {
    173     pref_mappings_.push_back(pref_mapping);
    174   }
    175 
    176  private:
    177   std::string name_;
    178   bool is_official_only_;
    179   bool can_be_recommended_;
    180   std::vector<std::string> supported_os_;
    181   PolicyMap test_policy_;
    182   ScopedVector<PrefMapping> pref_mappings_;
    183 
    184   DISALLOW_COPY_AND_ASSIGN(PolicyTestCase);
    185 };
    186 
    187 // Parses all policy test cases and makes then available in a map.
    188 class PolicyTestCases {
    189  public:
    190   typedef std::map<std::string, PolicyTestCase*> PolicyTestCaseMap;
    191   typedef PolicyTestCaseMap::const_iterator iterator;
    192 
    193   PolicyTestCases() {
    194     policy_test_cases_ = new std::map<std::string, PolicyTestCase*>();
    195 
    196     base::FilePath path = ui_test_utils::GetTestFilePath(
    197         base::FilePath(FILE_PATH_LITERAL("policy")),
    198         base::FilePath(FILE_PATH_LITERAL("policy_test_cases.json")));
    199     std::string json;
    200     if (!file_util::ReadFileToString(path, &json)) {
    201       ADD_FAILURE();
    202       return;
    203     }
    204     int error_code = -1;
    205     std::string error_string;
    206     base::DictionaryValue* dict = NULL;
    207     scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
    208         json, base::JSON_PARSE_RFC, &error_code, &error_string));
    209     if (!value.get() || !value->GetAsDictionary(&dict)) {
    210       ADD_FAILURE() << "Error parsing policy_test_cases.json: " << error_string;
    211       return;
    212     }
    213     const PolicyDefinitionList* list = GetChromePolicyDefinitionList();
    214     for (const PolicyDefinitionList::Entry* policy = list->begin;
    215          policy != list->end; ++policy) {
    216       PolicyTestCase* policy_test_case = GetPolicyTestCase(dict, policy->name);
    217       if (policy_test_case)
    218         (*policy_test_cases_)[policy->name] = policy_test_case;
    219     }
    220   }
    221 
    222   ~PolicyTestCases() {
    223     STLDeleteValues(policy_test_cases_);
    224     delete policy_test_cases_;
    225   }
    226 
    227   const PolicyTestCase* Get(const std::string& name) {
    228     iterator it = policy_test_cases_->find(name);
    229     return it == end() ? NULL : it->second;
    230   }
    231 
    232   const PolicyTestCaseMap& map() const { return *policy_test_cases_; }
    233   iterator begin() const { return policy_test_cases_->begin(); }
    234   iterator end() const { return policy_test_cases_->end(); }
    235 
    236  private:
    237   PolicyTestCase* GetPolicyTestCase(const base::DictionaryValue* tests,
    238                                     const std::string& name) {
    239     const base::DictionaryValue* policy_test_dict = NULL;
    240     if (!tests->GetDictionary(name, &policy_test_dict))
    241       return NULL;
    242     bool is_official_only = false;
    243     policy_test_dict->GetBoolean("official_only", &is_official_only);
    244     bool can_be_recommended = false;
    245     policy_test_dict->GetBoolean("can_be_recommended", &can_be_recommended);
    246     PolicyTestCase* policy_test_case =
    247         new PolicyTestCase(name, is_official_only, can_be_recommended);
    248     const base::ListValue* os_list = NULL;
    249     if (policy_test_dict->GetList("os", &os_list)) {
    250       for (size_t i = 0; i < os_list->GetSize(); ++i) {
    251         std::string os;
    252         if (os_list->GetString(i, &os))
    253           policy_test_case->AddSupportedOs(os);
    254       }
    255     }
    256     const base::DictionaryValue* policy_dict = NULL;
    257     if (policy_test_dict->GetDictionary("test_policy", &policy_dict)) {
    258       PolicyMap policy;
    259       policy.LoadFrom(policy_dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
    260       policy_test_case->SetTestPolicy(policy);
    261     }
    262     const base::ListValue* pref_mappings = NULL;
    263     if (policy_test_dict->GetList("pref_mappings", &pref_mappings)) {
    264       for (size_t i = 0; i < pref_mappings->GetSize(); ++i) {
    265         const base::DictionaryValue* pref_mapping_dict = NULL;
    266         std::string pref;
    267         if (!pref_mappings->GetDictionary(i, &pref_mapping_dict) ||
    268             !pref_mapping_dict->GetString("pref", &pref)) {
    269           ADD_FAILURE() << "Malformed pref_mappings entry in "
    270                         << "policy_test_cases.json.";
    271           continue;
    272         }
    273         bool is_local_state = false;
    274         pref_mapping_dict->GetBoolean("local_state", &is_local_state);
    275         std::string indicator_test_setup_js;
    276         pref_mapping_dict->GetString("indicator_test_setup_js",
    277                                      &indicator_test_setup_js);
    278         std::string indicator_selector;
    279         pref_mapping_dict->GetString("indicator_selector", &indicator_selector);
    280         PrefMapping* pref_mapping = new PrefMapping(
    281             pref, is_local_state, indicator_test_setup_js, indicator_selector);
    282         const base::ListValue* indicator_tests = NULL;
    283         if (pref_mapping_dict->GetList("indicator_tests", &indicator_tests)) {
    284           for (size_t i = 0; i < indicator_tests->GetSize(); ++i) {
    285             const base::DictionaryValue* indicator_test_dict = NULL;
    286             const base::DictionaryValue* policy = NULL;
    287             if (!indicator_tests->GetDictionary(i, &indicator_test_dict) ||
    288                 !indicator_test_dict->GetDictionary("policy", &policy)) {
    289               ADD_FAILURE() << "Malformed indicator_tests entry in "
    290                             << "policy_test_cases.json.";
    291               continue;
    292             }
    293             std::string value;
    294             indicator_test_dict->GetString("value", &value);
    295             bool readonly = false;
    296             indicator_test_dict->GetBoolean("readonly", &readonly);
    297             pref_mapping->AddIndicatorTestCase(
    298                 new IndicatorTestCase(*policy, value, readonly));
    299           }
    300         }
    301         policy_test_case->AddPrefMapping(pref_mapping);
    302       }
    303     }
    304     return policy_test_case;
    305   }
    306 
    307   PolicyTestCaseMap* policy_test_cases_;
    308 
    309   DISALLOW_COPY_AND_ASSIGN(PolicyTestCases);
    310 };
    311 
    312 void VerifyControlledSettingIndicators(Browser* browser,
    313                                        const std::string& selector,
    314                                        const std::string& value,
    315                                        const std::string& controlled_by,
    316                                        bool readonly) {
    317   std::stringstream javascript;
    318   javascript << "var nodes = document.querySelectorAll("
    319              << "    'span.controlled-setting-indicator"
    320              <<          selector.c_str() << "');"
    321              << "var indicators = [];"
    322              << "for (var i = 0; i < nodes.length; i++) {"
    323              << "  var node = nodes[i];"
    324              << "  var indicator = {};"
    325              << "  indicator.value = node.value || '';"
    326              << "  indicator.controlledBy = node.controlledBy || '';"
    327              << "  indicator.readOnly = node.readOnly || false;"
    328              << "  indicator.visible ="
    329              << "      window.getComputedStyle(node).display != 'none';"
    330              << "  indicators.push(indicator)"
    331              << "}"
    332              << "domAutomationController.send(JSON.stringify(indicators));";
    333   content::WebContents* contents =
    334       browser->tab_strip_model()->GetActiveWebContents();
    335   std::string json;
    336   // Retrieve the state of all controlled setting indicators matching the
    337   // |selector| as JSON.
    338   ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents, javascript.str(),
    339                                                      &json));
    340   scoped_ptr<base::Value> value_ptr(base::JSONReader::Read(json));
    341   const base::ListValue* indicators = NULL;
    342   ASSERT_TRUE(value_ptr.get());
    343   ASSERT_TRUE(value_ptr->GetAsList(&indicators));
    344   // Verify that controlled setting indicators representing |value| are visible
    345   // and have the correct state while those not representing |value| are
    346   // invisible.
    347   if (!controlled_by.empty()) {
    348     EXPECT_GT(indicators->GetSize(), 0u)
    349         << "Expected to find at least one controlled setting indicator.";
    350   }
    351   bool have_visible_indicators = false;
    352   for (base::ListValue::const_iterator indicator = indicators->begin();
    353        indicator != indicators->end(); ++indicator) {
    354     const base::DictionaryValue* properties = NULL;
    355     ASSERT_TRUE((*indicator)->GetAsDictionary(&properties));
    356     std::string indicator_value;
    357     std::string indicator_controlled_by;
    358     bool indicator_readonly;
    359     bool indicator_visible;
    360     EXPECT_TRUE(properties->GetString("value", &indicator_value));
    361     EXPECT_TRUE(properties->GetString("controlledBy",
    362                                       &indicator_controlled_by));
    363     EXPECT_TRUE(properties->GetBoolean("readOnly", &indicator_readonly));
    364     EXPECT_TRUE(properties->GetBoolean("visible", &indicator_visible));
    365     if (!controlled_by.empty() && (indicator_value == value)) {
    366       EXPECT_EQ(controlled_by, indicator_controlled_by);
    367       EXPECT_EQ(readonly, indicator_readonly);
    368       EXPECT_TRUE(indicator_visible);
    369       have_visible_indicators = true;
    370     } else {
    371       EXPECT_FALSE(indicator_visible);
    372     }
    373   }
    374   if (!controlled_by.empty()) {
    375     EXPECT_TRUE(have_visible_indicators)
    376         << "Expected to find at least one visible controlled setting "
    377         << "indicator.";
    378   }
    379 }
    380 
    381 }  // namespace
    382 
    383 // Base class for tests that change policy and are parameterized with a policy
    384 // definition.
    385 class PolicyPrefsTest
    386     : public InProcessBrowserTest,
    387       public testing::WithParamInterface<PolicyDefinitionList::Entry> {
    388  protected:
    389   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    390     EXPECT_CALL(provider_, IsInitializationComplete(_))
    391         .WillRepeatedly(Return(true));
    392     EXPECT_CALL(provider_, RegisterPolicyDomain(_)).Times(AnyNumber());
    393     BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
    394   }
    395 
    396   virtual void SetUpOnMainThread() OVERRIDE {
    397     ui_test_utils::WaitForTemplateURLServiceToLoad(
    398         TemplateURLServiceFactory::GetForProfile(browser()->profile()));
    399   }
    400 
    401   void UpdateProviderPolicy(const PolicyMap& policy) {
    402     provider_.UpdateChromePolicy(policy);
    403     base::RunLoop loop;
    404     loop.RunUntilIdle();
    405   }
    406 
    407   PolicyTestCases policy_test_cases_;
    408   MockConfigurationPolicyProvider provider_;
    409 };
    410 
    411 TEST(PolicyPrefsTestCoverageTest, AllPoliciesHaveATestCase) {
    412   // Verifies that all known policies have a test case in the JSON file.
    413   // This test fails when a policy is added to
    414   // chrome/app/policy/policy_templates.json but a test case is not added to
    415   // chrome/test/data/policy/policy_test_cases.json.
    416   PolicyTestCases policy_test_cases;
    417   const PolicyDefinitionList* list = GetChromePolicyDefinitionList();
    418   for (const PolicyDefinitionList::Entry* policy = list->begin;
    419        policy != list->end; ++policy) {
    420     EXPECT_TRUE(ContainsKey(policy_test_cases.map(), policy->name))
    421         << "Missing policy test case for: " << policy->name;
    422   }
    423 }
    424 
    425 IN_PROC_BROWSER_TEST_P(PolicyPrefsTest, PolicyToPrefsMapping) {
    426   // Verifies that policies make their corresponding preferences become managed,
    427   // and that the user can't override that setting.
    428   const PolicyTestCase* test_case = policy_test_cases_.Get(GetParam().name);
    429   ASSERT_TRUE(test_case) << "PolicyTestCase not found for " << GetParam().name;
    430   const ScopedVector<PrefMapping>& pref_mappings = test_case->pref_mappings();
    431   if (!test_case->IsSupported() || pref_mappings.empty())
    432     return;
    433   LOG(INFO) << "Testing policy: " << test_case->name();
    434 
    435   for (ScopedVector<PrefMapping>::const_iterator
    436            pref_mapping = pref_mappings.begin();
    437        pref_mapping != pref_mappings.end();
    438        ++pref_mapping) {
    439     // Skip Chrome OS preferences that use a different backend and cannot be
    440     // retrieved through the prefs mechanism.
    441     if (StartsWithASCII((*pref_mapping)->pref(), kCrosSettingsPrefix, true))
    442       continue;
    443 
    444     PrefService* local_state = g_browser_process->local_state();
    445     PrefService* user_prefs = browser()->profile()->GetPrefs();
    446     PrefService* prefs = (*pref_mapping)->is_local_state() ?
    447         local_state : user_prefs;
    448     // The preference must have been registered.
    449     const PrefService::Preference* pref =
    450         prefs->FindPreference((*pref_mapping)->pref().c_str());
    451     ASSERT_TRUE(pref);
    452     prefs->ClearPref((*pref_mapping)->pref().c_str());
    453 
    454     // Verify that setting the policy overrides the pref.
    455     const PolicyMap kNoPolicies;
    456     UpdateProviderPolicy(kNoPolicies);
    457     EXPECT_TRUE(pref->IsDefaultValue());
    458     EXPECT_TRUE(pref->IsUserModifiable());
    459     EXPECT_FALSE(pref->IsUserControlled());
    460     EXPECT_FALSE(pref->IsManaged());
    461 
    462     UpdateProviderPolicy(test_case->test_policy());
    463     EXPECT_FALSE(pref->IsDefaultValue());
    464     EXPECT_FALSE(pref->IsUserModifiable());
    465     EXPECT_FALSE(pref->IsUserControlled());
    466     EXPECT_TRUE(pref->IsManaged());
    467   }
    468 }
    469 
    470 IN_PROC_BROWSER_TEST_P(PolicyPrefsTest, CheckPolicyIndicators) {
    471   // Verifies that controlled setting indicators correctly show whether a pref's
    472   // value is recommended or enforced by a corresponding policy.
    473   const PolicyTestCase* policy_test_case =
    474       policy_test_cases_.Get(GetParam().name);
    475   ASSERT_TRUE(policy_test_case) << "PolicyTestCase not found for "
    476       << GetParam().name;
    477   const ScopedVector<PrefMapping>& pref_mappings =
    478       policy_test_case->pref_mappings();
    479   if (!policy_test_case->IsSupported() || pref_mappings.empty())
    480     return;
    481   bool has_indicator_tests = false;
    482   for (ScopedVector<PrefMapping>::const_iterator
    483            pref_mapping = pref_mappings.begin();
    484        pref_mapping != pref_mappings.end();
    485        ++pref_mapping) {
    486     if (!(*pref_mapping)->indicator_test_cases().empty()) {
    487       has_indicator_tests = true;
    488       break;
    489     }
    490   }
    491   if (!has_indicator_tests)
    492     return;
    493   LOG(INFO) << "Testing policy: " << policy_test_case->name();
    494 
    495   for (ScopedVector<PrefMapping>::const_iterator
    496            pref_mapping = pref_mappings.begin();
    497        pref_mapping != pref_mappings.end();
    498        ++pref_mapping) {
    499     const ScopedVector<IndicatorTestCase>&
    500         indicator_test_cases = (*pref_mapping)->indicator_test_cases();
    501     if (indicator_test_cases.empty())
    502       continue;
    503 
    504     ui_test_utils::NavigateToURL(browser(), GURL(kMainSettingsPage));
    505     if (!(*pref_mapping)->indicator_test_setup_js().empty()) {
    506       ASSERT_TRUE(content::ExecuteScript(
    507           browser()->tab_strip_model()->GetActiveWebContents(),
    508           (*pref_mapping)->indicator_test_setup_js()));
    509     }
    510 
    511     std::string indicator_selector = (*pref_mapping)->indicator_selector();
    512     if (indicator_selector.empty())
    513       indicator_selector = "[pref=\"" + (*pref_mapping)->pref() + "\"]";
    514     for (ScopedVector<IndicatorTestCase>::const_iterator
    515              indicator_test_case = indicator_test_cases.begin();
    516          indicator_test_case != indicator_test_cases.end();
    517          ++indicator_test_case) {
    518       // Check that no controlled setting indicator is visible when no value is
    519       // set by policy.
    520       PolicyMap policies;
    521       UpdateProviderPolicy(policies);
    522       VerifyControlledSettingIndicators(
    523           browser(), indicator_selector, std::string(), std::string(), false);
    524       // Check that the appropriate controlled setting indicator is shown when a
    525       // value is enforced by policy.
    526       policies.LoadFrom(&(*indicator_test_case)->policy(),
    527                         POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
    528       UpdateProviderPolicy(policies);
    529       VerifyControlledSettingIndicators(browser(), indicator_selector,
    530                                         (*indicator_test_case)->value(),
    531                                         "policy",
    532                                         (*indicator_test_case)->readonly());
    533 
    534       if (!policy_test_case->can_be_recommended())
    535         continue;
    536 
    537       PrefService* local_state = g_browser_process->local_state();
    538       PrefService* user_prefs = browser()->profile()->GetPrefs();
    539       PrefService* prefs = (*pref_mapping)->is_local_state() ?
    540           local_state : user_prefs;
    541       // The preference must have been registered.
    542       const PrefService::Preference* pref =
    543           prefs->FindPreference((*pref_mapping)->pref().c_str());
    544       ASSERT_TRUE(pref);
    545 
    546       // Check that the appropriate controlled setting indicator is shown when a
    547       // value is recommended by policy and the user has not overridden the
    548       // recommendation.
    549       policies.LoadFrom(&(*indicator_test_case)->policy(),
    550                         POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER);
    551       UpdateProviderPolicy(policies);
    552       VerifyControlledSettingIndicators(browser(), indicator_selector,
    553                                         (*indicator_test_case)->value(),
    554                                         "recommended",
    555                                         (*indicator_test_case)->readonly());
    556       // Check that the appropriate controlled setting indicator is shown when a
    557       // value is recommended by policy and the user has overriddent the
    558       // recommendation.
    559       prefs->Set((*pref_mapping)->pref().c_str(), *pref->GetValue());
    560       VerifyControlledSettingIndicators(browser(), indicator_selector,
    561                                         (*indicator_test_case)->value(),
    562                                         "hasRecommendation",
    563                                         (*indicator_test_case)->readonly());
    564       prefs->ClearPref((*pref_mapping)->pref().c_str());
    565     }
    566   }
    567 }
    568 
    569 INSTANTIATE_TEST_CASE_P(
    570     PolicyPrefsTestInstance,
    571     PolicyPrefsTest,
    572     testing::ValuesIn(GetChromePolicyDefinitionList()->begin,
    573                       GetChromePolicyDefinitionList()->end));
    574 
    575 }  // namespace policy
    576