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 <cstdlib>
      7 #include <map>
      8 #include <sstream>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/file_util.h"
     14 #include "base/files/file_path.h"
     15 #include "base/json/json_reader.h"
     16 #include "base/logging.h"
     17 #include "base/memory/scoped_ptr.h"
     18 #include "base/memory/scoped_vector.h"
     19 #include "base/memory/weak_ptr.h"
     20 #include "base/prefs/pref_service.h"
     21 #include "base/run_loop.h"
     22 #include "base/stl_util.h"
     23 #include "base/strings/string_util.h"
     24 #include "base/strings/utf_string_conversions.h"
     25 #include "base/values.h"
     26 #include "chrome/browser/browser_process.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 "components/policy/core/browser/browser_policy_connector.h"
     34 #include "components/policy/core/common/external_data_fetcher.h"
     35 #include "components/policy/core/common/external_data_manager.h"
     36 #include "components/policy/core/common/mock_configuration_policy_provider.h"
     37 #include "components/policy/core/common/policy_details.h"
     38 #include "components/policy/core/common/policy_map.h"
     39 #include "components/policy/core/common/schema.h"
     40 #include "content/public/browser/web_contents.h"
     41 #include "content/public/test/browser_test_utils.h"
     42 #include "policy/policy_constants.h"
     43 #include "testing/gmock/include/gmock/gmock.h"
     44 #include "testing/gtest/include/gtest/gtest.h"
     45 #include "url/gurl.h"
     46 
     47 using testing::Return;
     48 using testing::_;
     49 
     50 namespace policy {
     51 
     52 namespace {
     53 
     54 const char kMainSettingsPage[] = "chrome://settings-frame";
     55 
     56 const char kCrosSettingsPrefix[] = "cros.";
     57 
     58 std::string GetPolicyName(const std::string& policy_name_decorated) {
     59   const size_t offset = policy_name_decorated.find('.');
     60   if (offset != std::string::npos)
     61     return policy_name_decorated.substr(0, offset);
     62   return policy_name_decorated;
     63 }
     64 
     65 // Contains the details of a single test case verifying that the controlled
     66 // setting indicators for a pref affected by a policy work correctly. This is
     67 // part of the data loaded from chrome/test/data/policy/policy_test_cases.json.
     68 class IndicatorTestCase {
     69  public:
     70   IndicatorTestCase(const base::DictionaryValue& policy,
     71                     const std::string& value,
     72                     bool readonly)
     73       : policy_(policy.DeepCopy()), value_(value), readonly_(readonly) {}
     74   ~IndicatorTestCase() {}
     75 
     76   const base::DictionaryValue& policy() const { return *policy_; }
     77 
     78   const std::string& value() const { return value_; }
     79 
     80   bool readonly() const { return readonly_; }
     81 
     82  private:
     83   scoped_ptr<base::DictionaryValue> policy_;
     84   std::string value_;
     85   bool readonly_;
     86 
     87   DISALLOW_COPY_AND_ASSIGN(IndicatorTestCase);
     88 };
     89 
     90 // Contains the testing details for a single pref affected by a policy. This is
     91 // part of the data loaded from chrome/test/data/policy/policy_test_cases.json.
     92 class PrefMapping {
     93  public:
     94   PrefMapping(const std::string& pref,
     95               bool is_local_state,
     96               bool check_for_mandatory,
     97               bool check_for_recommended,
     98               const std::string& indicator_test_setup_js,
     99               const std::string& indicator_selector)
    100       : pref_(pref),
    101         is_local_state_(is_local_state),
    102         check_for_mandatory_(check_for_mandatory),
    103         check_for_recommended_(check_for_recommended),
    104         indicator_test_setup_js_(indicator_test_setup_js),
    105         indicator_selector_(indicator_selector) {}
    106   ~PrefMapping() {}
    107 
    108   const std::string& pref() const { return pref_; }
    109 
    110   bool is_local_state() const { return is_local_state_; }
    111 
    112   bool check_for_mandatory() const { return check_for_mandatory_; }
    113 
    114   bool check_for_recommended() const { return check_for_recommended_; }
    115 
    116   const std::string& indicator_test_setup_js() const {
    117     return indicator_test_setup_js_;
    118   }
    119 
    120   const std::string& indicator_selector() const {
    121     return indicator_selector_;
    122   }
    123 
    124   const ScopedVector<IndicatorTestCase>& indicator_test_cases() const {
    125     return indicator_test_cases_;
    126   }
    127   void AddIndicatorTestCase(IndicatorTestCase* test_case) {
    128     indicator_test_cases_.push_back(test_case);
    129   }
    130 
    131  private:
    132   const std::string pref_;
    133   const bool is_local_state_;
    134   const bool check_for_mandatory_;
    135   const bool check_for_recommended_;
    136   const std::string indicator_test_setup_js_;
    137   const std::string indicator_selector_;
    138   ScopedVector<IndicatorTestCase> indicator_test_cases_;
    139 
    140   DISALLOW_COPY_AND_ASSIGN(PrefMapping);
    141 };
    142 
    143 // Contains the testing details for a single policy. This is part of the data
    144 // loaded from chrome/test/data/policy/policy_test_cases.json.
    145 class PolicyTestCase {
    146  public:
    147   PolicyTestCase(const std::string& name,
    148                  bool is_official_only,
    149                  bool can_be_recommended,
    150                  const std::string& indicator_selector)
    151       : name_(name),
    152         is_official_only_(is_official_only),
    153         can_be_recommended_(can_be_recommended),
    154         indicator_selector_(indicator_selector) {}
    155   ~PolicyTestCase() {}
    156 
    157   const std::string& name() const { return name_; }
    158 
    159   bool is_official_only() const { return is_official_only_; }
    160 
    161   bool can_be_recommended() const { return can_be_recommended_; }
    162 
    163   bool IsOsSupported() const {
    164 #if defined(OS_WIN)
    165     const std::string os("win");
    166 #elif defined(OS_MACOSX)
    167     const std::string os("mac");
    168 #elif defined(OS_CHROMEOS)
    169     const std::string os("chromeos");
    170 #elif defined(OS_LINUX)
    171     const std::string os("linux");
    172 #else
    173 #error "Unknown platform"
    174 #endif
    175     return std::find(supported_os_.begin(), supported_os_.end(), os) !=
    176         supported_os_.end();
    177   }
    178   void AddSupportedOs(const std::string& os) { supported_os_.push_back(os); }
    179 
    180   bool IsSupported() const {
    181 #if !defined(OFFICIAL_BUILD)
    182     if (is_official_only())
    183       return false;
    184 #endif
    185     return IsOsSupported();
    186   }
    187 
    188   const base::DictionaryValue& test_policy() const { return test_policy_; }
    189   void SetTestPolicy(const base::DictionaryValue& policy) {
    190     test_policy_.Clear();
    191     test_policy_.MergeDictionary(&policy);
    192   }
    193 
    194   const ScopedVector<PrefMapping>& pref_mappings() const {
    195     return pref_mappings_;
    196   }
    197   void AddPrefMapping(PrefMapping* pref_mapping) {
    198     pref_mappings_.push_back(pref_mapping);
    199   }
    200 
    201   const std::string& indicator_selector() const { return indicator_selector_; }
    202 
    203  private:
    204   std::string name_;
    205   bool is_official_only_;
    206   bool can_be_recommended_;
    207   std::vector<std::string> supported_os_;
    208   base::DictionaryValue test_policy_;
    209   ScopedVector<PrefMapping> pref_mappings_;
    210   std::string indicator_selector_;
    211 
    212   DISALLOW_COPY_AND_ASSIGN(PolicyTestCase);
    213 };
    214 
    215 // Parses all policy test cases and makes then available in a map.
    216 class PolicyTestCases {
    217  public:
    218   typedef std::vector<PolicyTestCase*> PolicyTestCaseVector;
    219   typedef std::map<std::string, PolicyTestCaseVector> PolicyTestCaseMap;
    220   typedef PolicyTestCaseMap::const_iterator iterator;
    221 
    222   PolicyTestCases() {
    223     base::FilePath path = ui_test_utils::GetTestFilePath(
    224         base::FilePath(FILE_PATH_LITERAL("policy")),
    225         base::FilePath(FILE_PATH_LITERAL("policy_test_cases.json")));
    226     std::string json;
    227     if (!base::ReadFileToString(path, &json)) {
    228       ADD_FAILURE();
    229       return;
    230     }
    231     int error_code = -1;
    232     std::string error_string;
    233     base::DictionaryValue* dict = NULL;
    234     scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
    235         json, base::JSON_PARSE_RFC, &error_code, &error_string));
    236     if (!value.get() || !value->GetAsDictionary(&dict)) {
    237       ADD_FAILURE() << "Error parsing policy_test_cases.json: " << error_string;
    238       return;
    239     }
    240     Schema chrome_schema = Schema::Wrap(GetChromeSchemaData());
    241     if (!chrome_schema.valid()) {
    242       ADD_FAILURE();
    243       return;
    244     }
    245     for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
    246          it.Advance()) {
    247       const std::string policy_name = GetPolicyName(it.key());
    248       if (!chrome_schema.GetKnownProperty(policy_name).valid())
    249         continue;
    250       PolicyTestCase* policy_test_case = GetPolicyTestCase(dict, it.key());
    251       if (policy_test_case)
    252         policy_test_cases_[policy_name].push_back(policy_test_case);
    253     }
    254   }
    255 
    256   ~PolicyTestCases() {
    257     for (iterator policy = policy_test_cases_.begin();
    258          policy != policy_test_cases_.end();
    259          ++policy) {
    260       for (PolicyTestCaseVector::const_iterator test_case =
    261                policy->second.begin();
    262            test_case != policy->second.end();
    263            ++test_case) {
    264         delete *test_case;
    265       }
    266     }
    267   }
    268 
    269   const PolicyTestCaseVector* Get(const std::string& name) const {
    270     const iterator it = policy_test_cases_.find(name);
    271     return it == end() ? NULL : &it->second;
    272   }
    273 
    274   const PolicyTestCaseMap& map() const { return policy_test_cases_; }
    275   iterator begin() const { return policy_test_cases_.begin(); }
    276   iterator end() const { return policy_test_cases_.end(); }
    277 
    278  private:
    279   PolicyTestCase* GetPolicyTestCase(const base::DictionaryValue* tests,
    280                                     const std::string& name) {
    281     const base::DictionaryValue* policy_test_dict = NULL;
    282     if (!tests->GetDictionaryWithoutPathExpansion(name, &policy_test_dict))
    283       return NULL;
    284     bool is_official_only = false;
    285     policy_test_dict->GetBoolean("official_only", &is_official_only);
    286     bool can_be_recommended = false;
    287     policy_test_dict->GetBoolean("can_be_recommended", &can_be_recommended);
    288     std::string indicator_selector;
    289     policy_test_dict->GetString("indicator_selector", &indicator_selector);
    290     PolicyTestCase* policy_test_case = new PolicyTestCase(name,
    291                                                           is_official_only,
    292                                                           can_be_recommended,
    293                                                           indicator_selector);
    294     const base::ListValue* os_list = NULL;
    295     if (policy_test_dict->GetList("os", &os_list)) {
    296       for (size_t i = 0; i < os_list->GetSize(); ++i) {
    297         std::string os;
    298         if (os_list->GetString(i, &os))
    299           policy_test_case->AddSupportedOs(os);
    300       }
    301     }
    302     const base::DictionaryValue* policy = NULL;
    303     if (policy_test_dict->GetDictionary("test_policy", &policy))
    304       policy_test_case->SetTestPolicy(*policy);
    305     const base::ListValue* pref_mappings = NULL;
    306     if (policy_test_dict->GetList("pref_mappings", &pref_mappings)) {
    307       for (size_t i = 0; i < pref_mappings->GetSize(); ++i) {
    308         const base::DictionaryValue* pref_mapping_dict = NULL;
    309         std::string pref;
    310         if (!pref_mappings->GetDictionary(i, &pref_mapping_dict) ||
    311             !pref_mapping_dict->GetString("pref", &pref)) {
    312           ADD_FAILURE() << "Malformed pref_mappings entry in "
    313                         << "policy_test_cases.json.";
    314           continue;
    315         }
    316         bool is_local_state = false;
    317         pref_mapping_dict->GetBoolean("local_state", &is_local_state);
    318         bool check_for_mandatory = true;
    319         pref_mapping_dict->GetBoolean("check_for_mandatory",
    320                                       &check_for_mandatory);
    321         bool check_for_recommended = true;
    322         pref_mapping_dict->GetBoolean("check_for_recommended",
    323                                       &check_for_recommended);
    324         std::string indicator_test_setup_js;
    325         pref_mapping_dict->GetString("indicator_test_setup_js",
    326                                      &indicator_test_setup_js);
    327         std::string indicator_selector;
    328         pref_mapping_dict->GetString("indicator_selector", &indicator_selector);
    329         PrefMapping* pref_mapping = new PrefMapping(pref,
    330                                                     is_local_state,
    331                                                     check_for_mandatory,
    332                                                     check_for_recommended,
    333                                                     indicator_test_setup_js,
    334                                                     indicator_selector);
    335         const base::ListValue* indicator_tests = NULL;
    336         if (pref_mapping_dict->GetList("indicator_tests", &indicator_tests)) {
    337           for (size_t i = 0; i < indicator_tests->GetSize(); ++i) {
    338             const base::DictionaryValue* indicator_test_dict = NULL;
    339             const base::DictionaryValue* policy = NULL;
    340             if (!indicator_tests->GetDictionary(i, &indicator_test_dict) ||
    341                 !indicator_test_dict->GetDictionary("policy", &policy)) {
    342               ADD_FAILURE() << "Malformed indicator_tests entry in "
    343                             << "policy_test_cases.json.";
    344               continue;
    345             }
    346             std::string value;
    347             indicator_test_dict->GetString("value", &value);
    348             bool readonly = false;
    349             indicator_test_dict->GetBoolean("readonly", &readonly);
    350             pref_mapping->AddIndicatorTestCase(
    351                 new IndicatorTestCase(*policy, value, readonly));
    352           }
    353         }
    354         policy_test_case->AddPrefMapping(pref_mapping);
    355       }
    356     }
    357     return policy_test_case;
    358   }
    359 
    360   PolicyTestCaseMap policy_test_cases_;
    361 
    362   DISALLOW_COPY_AND_ASSIGN(PolicyTestCases);
    363 };
    364 
    365 // Returns a pseudo-random integer distributed in [0, range).
    366 int GetRandomNumber(int range) {
    367   return rand() % range;
    368 }
    369 
    370 // Splits all known policies into subsets of the given |chunk_size|. The
    371 // policies are shuffled so that there is no correlation between their initial
    372 // alphabetic ordering and the assignment to chunks. This ensures that the
    373 // expected number of policies with long-running test cases is equal for each
    374 // subset. The shuffle algorithm uses a fixed seed, ensuring that no randomness
    375 // is introduced into the testing process.
    376 std::vector<std::vector<std::string> > SplitPoliciesIntoChunks(int chunk_size) {
    377   Schema chrome_schema = Schema::Wrap(GetChromeSchemaData());
    378   if (!chrome_schema.valid())
    379     ADD_FAILURE();
    380 
    381   std::vector<std::string> policies;
    382   for (Schema::Iterator it = chrome_schema.GetPropertiesIterator();
    383        !it.IsAtEnd(); it.Advance()) {
    384     policies.push_back(it.key());
    385   }
    386 
    387   // Use a fixed random seed to obtain a reproducible shuffle.
    388   srand(1);
    389   std::random_shuffle(policies.begin(), policies.end(), GetRandomNumber);
    390 
    391   std::vector<std::vector<std::string> > chunks;
    392   std::vector<std::string>::const_iterator it = policies.begin();
    393   const std::vector<std::string>::const_iterator end = policies.end();
    394   for ( ; end - it >= chunk_size; it += chunk_size)
    395     chunks.push_back(std::vector<std::string>(it, it + chunk_size));
    396   if (it != end)
    397     chunks.push_back(std::vector<std::string>(it, end));
    398   return chunks;
    399 }
    400 
    401 void VerifyControlledSettingIndicators(Browser* browser,
    402                                        const std::string& selector,
    403                                        const std::string& value,
    404                                        const std::string& controlled_by,
    405                                        bool readonly) {
    406   std::stringstream javascript;
    407   javascript << "var nodes = document.querySelectorAll("
    408              << "    'span.controlled-setting-indicator"
    409              <<          selector.c_str() << "');"
    410              << "var indicators = [];"
    411              << "for (var i = 0; i < nodes.length; i++) {"
    412              << "  var node = nodes[i];"
    413              << "  var indicator = {};"
    414              << "  indicator.value = node.value || '';"
    415              << "  indicator.controlledBy = node.controlledBy || '';"
    416              << "  indicator.readOnly = node.readOnly || false;"
    417              << "  indicator.visible ="
    418              << "      window.getComputedStyle(node).display != 'none';"
    419              << "  indicators.push(indicator)"
    420              << "}"
    421              << "domAutomationController.send(JSON.stringify(indicators));";
    422   content::WebContents* contents =
    423       browser->tab_strip_model()->GetActiveWebContents();
    424   std::string json;
    425   // Retrieve the state of all controlled setting indicators matching the
    426   // |selector| as JSON.
    427   ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents, javascript.str(),
    428                                                      &json));
    429   scoped_ptr<base::Value> value_ptr(base::JSONReader::Read(json));
    430   const base::ListValue* indicators = NULL;
    431   ASSERT_TRUE(value_ptr.get());
    432   ASSERT_TRUE(value_ptr->GetAsList(&indicators));
    433   // Verify that controlled setting indicators representing |value| are visible
    434   // and have the correct state while those not representing |value| are
    435   // invisible.
    436   if (!controlled_by.empty()) {
    437     EXPECT_GT(indicators->GetSize(), 0u)
    438         << "Expected to find at least one controlled setting indicator.";
    439   }
    440   bool have_visible_indicators = false;
    441   for (base::ListValue::const_iterator indicator = indicators->begin();
    442        indicator != indicators->end(); ++indicator) {
    443     const base::DictionaryValue* properties = NULL;
    444     ASSERT_TRUE((*indicator)->GetAsDictionary(&properties));
    445     std::string indicator_value;
    446     std::string indicator_controlled_by;
    447     bool indicator_readonly;
    448     bool indicator_visible;
    449     EXPECT_TRUE(properties->GetString("value", &indicator_value));
    450     EXPECT_TRUE(properties->GetString("controlledBy",
    451                                       &indicator_controlled_by));
    452     EXPECT_TRUE(properties->GetBoolean("readOnly", &indicator_readonly));
    453     EXPECT_TRUE(properties->GetBoolean("visible", &indicator_visible));
    454     if (!controlled_by.empty() && (indicator_value == value)) {
    455       EXPECT_EQ(controlled_by, indicator_controlled_by);
    456       EXPECT_EQ(readonly, indicator_readonly);
    457       EXPECT_TRUE(indicator_visible);
    458       have_visible_indicators = true;
    459     } else {
    460       EXPECT_FALSE(indicator_visible);
    461     }
    462   }
    463   if (!controlled_by.empty()) {
    464     EXPECT_TRUE(have_visible_indicators)
    465         << "Expected to find at least one visible controlled setting "
    466         << "indicator.";
    467   }
    468 }
    469 
    470 }  // namespace
    471 
    472 typedef InProcessBrowserTest PolicyPrefsTestCoverageTest;
    473 
    474 IN_PROC_BROWSER_TEST_F(PolicyPrefsTestCoverageTest, AllPoliciesHaveATestCase) {
    475   // Verifies that all known policies have a test case in the JSON file.
    476   // This test fails when a policy is added to
    477   // components/policy/resources/policy_templates.json but a test case is not
    478   // added to chrome/test/data/policy/policy_test_cases.json.
    479   Schema chrome_schema = Schema::Wrap(GetChromeSchemaData());
    480   ASSERT_TRUE(chrome_schema.valid());
    481 
    482   PolicyTestCases policy_test_cases;
    483   for (Schema::Iterator it = chrome_schema.GetPropertiesIterator();
    484        !it.IsAtEnd(); it.Advance()) {
    485     EXPECT_TRUE(ContainsKey(policy_test_cases.map(), it.key()))
    486         << "Missing policy test case for: " << it.key();
    487   }
    488 }
    489 
    490 // Base class for tests that change policy.
    491 class PolicyPrefsTest : public InProcessBrowserTest {
    492  protected:
    493   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    494     EXPECT_CALL(provider_, IsInitializationComplete(_))
    495         .WillRepeatedly(Return(true));
    496     BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
    497   }
    498 
    499   virtual void SetUpOnMainThread() OVERRIDE {
    500     ui_test_utils::WaitForTemplateURLServiceToLoad(
    501         TemplateURLServiceFactory::GetForProfile(browser()->profile()));
    502   }
    503 
    504   virtual void TearDownOnMainThread() OVERRIDE {
    505     ClearProviderPolicy();
    506   }
    507 
    508   void ClearProviderPolicy() {
    509     provider_.UpdateChromePolicy(PolicyMap());
    510     base::RunLoop().RunUntilIdle();
    511   }
    512 
    513   void SetProviderPolicy(const base::DictionaryValue& policies,
    514                          PolicyLevel level) {
    515     PolicyMap policy_map;
    516     for (base::DictionaryValue::Iterator it(policies);
    517          !it.IsAtEnd(); it.Advance()) {
    518       const PolicyDetails* policy_details = GetChromePolicyDetails(it.key());
    519       ASSERT_TRUE(policy_details);
    520       policy_map.Set(
    521           it.key(),
    522           level,
    523           POLICY_SCOPE_USER,
    524           it.value().DeepCopy(),
    525           policy_details->max_external_data_size ?
    526               new ExternalDataFetcher(base::WeakPtr<ExternalDataManager>(),
    527                                       it.key()) :
    528               NULL);
    529     }
    530     provider_.UpdateChromePolicy(policy_map);
    531     base::RunLoop().RunUntilIdle();
    532   }
    533 
    534   MockConfigurationPolicyProvider provider_;
    535 };
    536 
    537 // Verifies that policies make their corresponding preferences become managed,
    538 // and that the user can't override that setting.
    539 IN_PROC_BROWSER_TEST_F(PolicyPrefsTest, PolicyToPrefsMapping) {
    540   PrefService* local_state = g_browser_process->local_state();
    541   PrefService* user_prefs = browser()->profile()->GetPrefs();
    542 
    543   const PolicyTestCases test_cases;
    544   for (PolicyTestCases::iterator policy = test_cases.begin();
    545        policy != test_cases.end();
    546        ++policy) {
    547     for (PolicyTestCases::PolicyTestCaseVector::const_iterator test_case =
    548              policy->second.begin();
    549          test_case != policy->second.end();
    550          ++test_case) {
    551       const ScopedVector<PrefMapping>& pref_mappings =
    552           (*test_case)->pref_mappings();
    553       if (!(*test_case)->IsSupported() || pref_mappings.empty())
    554         continue;
    555 
    556       LOG(INFO) << "Testing policy: " << policy->first;
    557 
    558       for (ScopedVector<PrefMapping>::const_iterator pref_mapping =
    559                pref_mappings.begin();
    560            pref_mapping != pref_mappings.end();
    561            ++pref_mapping) {
    562         // Skip Chrome OS preferences that use a different backend and cannot be
    563         // retrieved through the prefs mechanism.
    564         if (StartsWithASCII((*pref_mapping)->pref(), kCrosSettingsPrefix, true))
    565           continue;
    566 
    567         // Skip preferences that should not be checked when the policy is set to
    568         // a mandatory value.
    569         if (!(*pref_mapping)->check_for_mandatory())
    570           continue;
    571 
    572         PrefService* prefs =
    573             (*pref_mapping)->is_local_state() ? local_state : user_prefs;
    574         // The preference must have been registered.
    575         const PrefService::Preference* pref =
    576             prefs->FindPreference((*pref_mapping)->pref().c_str());
    577         ASSERT_TRUE(pref);
    578 
    579         // Verify that setting the policy overrides the pref.
    580         ClearProviderPolicy();
    581         prefs->ClearPref((*pref_mapping)->pref().c_str());
    582         EXPECT_TRUE(pref->IsDefaultValue());
    583         EXPECT_TRUE(pref->IsUserModifiable());
    584         EXPECT_FALSE(pref->IsUserControlled());
    585         EXPECT_FALSE(pref->IsManaged());
    586 
    587         SetProviderPolicy((*test_case)->test_policy(), POLICY_LEVEL_MANDATORY);
    588         EXPECT_FALSE(pref->IsDefaultValue());
    589         EXPECT_FALSE(pref->IsUserModifiable());
    590         EXPECT_FALSE(pref->IsUserControlled());
    591         EXPECT_TRUE(pref->IsManaged());
    592       }
    593     }
    594   }
    595 }
    596 
    597 class PolicyPrefIndicatorTest
    598     : public PolicyPrefsTest,
    599       public testing::WithParamInterface<std::vector<std::string> > {
    600 };
    601 
    602 // Verifies that controlled setting indicators correctly show whether a pref's
    603 // value is recommended or enforced by a corresponding policy.
    604 IN_PROC_BROWSER_TEST_P(PolicyPrefIndicatorTest, CheckPolicyIndicators) {
    605   const PolicyTestCases test_cases;
    606   PrefService* local_state = g_browser_process->local_state();
    607   PrefService* user_prefs = browser()->profile()->GetPrefs();
    608 
    609   ui_test_utils::NavigateToURL(browser(), GURL(kMainSettingsPage));
    610 
    611   for (std::vector<std::string>::const_iterator policy = GetParam().begin();
    612        policy != GetParam().end();
    613        ++policy) {
    614     const std::vector<PolicyTestCase*>* policy_test_cases =
    615         test_cases.Get(*policy);
    616     ASSERT_TRUE(policy_test_cases) << "PolicyTestCase not found for "
    617                                    << *policy;
    618     for (std::vector<PolicyTestCase*>::const_iterator test_case =
    619              policy_test_cases->begin();
    620          test_case != policy_test_cases->end();
    621          ++test_case) {
    622       PolicyTestCase* policy_test_case = *test_case;
    623       if (!policy_test_case->IsSupported())
    624         continue;
    625       const ScopedVector<PrefMapping>& pref_mappings =
    626           policy_test_case->pref_mappings();
    627       if (policy_test_case->indicator_selector().empty()) {
    628         bool has_pref_indicator_tests = false;
    629         for (ScopedVector<PrefMapping>::const_iterator pref_mapping =
    630                  pref_mappings.begin();
    631              pref_mapping != pref_mappings.end();
    632              ++pref_mapping) {
    633           if (!(*pref_mapping)->indicator_test_cases().empty()) {
    634             has_pref_indicator_tests = true;
    635             break;
    636           }
    637         }
    638         if (!has_pref_indicator_tests)
    639           continue;
    640       }
    641 
    642       LOG(INFO) << "Testing policy: " << *policy;
    643 
    644       if (!policy_test_case->indicator_selector().empty()) {
    645         // Check that no controlled setting indicator is visible when no value
    646         // is set by policy.
    647         ClearProviderPolicy();
    648         VerifyControlledSettingIndicators(
    649             browser(),
    650             policy_test_case->indicator_selector(),
    651             std::string(),
    652             std::string(),
    653             false);
    654         // Check that the appropriate controlled setting indicator is shown when
    655         // a value is enforced by policy.
    656         SetProviderPolicy(policy_test_case->test_policy(),
    657                           POLICY_LEVEL_MANDATORY);
    658         VerifyControlledSettingIndicators(
    659             browser(),
    660             policy_test_case->indicator_selector(),
    661             std::string(),
    662             "policy",
    663             false);
    664       }
    665 
    666       for (ScopedVector<PrefMapping>::const_iterator
    667                pref_mapping = pref_mappings.begin();
    668            pref_mapping != pref_mappings.end();
    669            ++pref_mapping) {
    670         const ScopedVector<IndicatorTestCase>& indicator_test_cases =
    671             (*pref_mapping)->indicator_test_cases();
    672         if (indicator_test_cases.empty())
    673           continue;
    674 
    675         if (!(*pref_mapping)->indicator_test_setup_js().empty()) {
    676           ASSERT_TRUE(content::ExecuteScript(
    677               browser()->tab_strip_model()->GetActiveWebContents(),
    678               (*pref_mapping)->indicator_test_setup_js()));
    679         }
    680 
    681         std::string indicator_selector = (*pref_mapping)->indicator_selector();
    682         if (indicator_selector.empty())
    683           indicator_selector = "[pref=\"" + (*pref_mapping)->pref() + "\"]";
    684         for (ScopedVector<IndicatorTestCase>::const_iterator
    685                  indicator_test_case = indicator_test_cases.begin();
    686              indicator_test_case != indicator_test_cases.end();
    687              ++indicator_test_case) {
    688           // Check that no controlled setting indicator is visible when no value
    689           // is set by policy.
    690           ClearProviderPolicy();
    691           VerifyControlledSettingIndicators(browser(),
    692                                             indicator_selector,
    693                                             std::string(),
    694                                             std::string(),
    695                                             false);
    696 
    697           if ((*pref_mapping)->check_for_mandatory()) {
    698             // Check that the appropriate controlled setting indicator is shown
    699             // when a value is enforced by policy.
    700             SetProviderPolicy((*indicator_test_case)->policy(),
    701                               POLICY_LEVEL_MANDATORY);
    702 
    703             VerifyControlledSettingIndicators(
    704                 browser(),
    705                 indicator_selector,
    706                 (*indicator_test_case)->value(),
    707                 "policy",
    708                 (*indicator_test_case)->readonly());
    709           }
    710 
    711           if (!policy_test_case->can_be_recommended() ||
    712               !(*pref_mapping)->check_for_recommended()) {
    713             continue;
    714           }
    715 
    716           PrefService* prefs =
    717               (*pref_mapping)->is_local_state() ? local_state : user_prefs;
    718           // The preference must have been registered.
    719           const PrefService::Preference* pref =
    720               prefs->FindPreference((*pref_mapping)->pref().c_str());
    721           ASSERT_TRUE(pref);
    722 
    723           // Check that the appropriate controlled setting indicator is shown
    724           // when a value is recommended by policy and the user has not
    725           // overridden the recommendation.
    726           SetProviderPolicy((*indicator_test_case)->policy(),
    727                             POLICY_LEVEL_RECOMMENDED);
    728           VerifyControlledSettingIndicators(browser(),
    729                                             indicator_selector,
    730                                             (*indicator_test_case)->value(),
    731                                             "recommended",
    732                                             (*indicator_test_case)->readonly());
    733           // Check that the appropriate controlled setting indicator is shown
    734           // when a value is recommended by policy and the user has overridden
    735           // the recommendation.
    736           prefs->Set((*pref_mapping)->pref().c_str(), *pref->GetValue());
    737           VerifyControlledSettingIndicators(browser(),
    738                                             indicator_selector,
    739                                             (*indicator_test_case)->value(),
    740                                             "hasRecommendation",
    741                                             (*indicator_test_case)->readonly());
    742           prefs->ClearPref((*pref_mapping)->pref().c_str());
    743         }
    744       }
    745     }
    746   }
    747 }
    748 
    749 INSTANTIATE_TEST_CASE_P(PolicyPrefIndicatorTestInstance,
    750                         PolicyPrefIndicatorTest,
    751                         testing::ValuesIn(SplitPoliciesIntoChunks(10)));
    752 
    753 }  // namespace policy
    754