• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/files/file_path.h"
14 #include "base/files/file_util.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 
GetPolicyName(const std::string & policy_name_decorated)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:
IndicatorTestCase(const base::DictionaryValue & policy,const std::string & value,bool readonly)70   IndicatorTestCase(const base::DictionaryValue& policy,
71                     const std::string& value,
72                     bool readonly)
73       : policy_(policy.DeepCopy()), value_(value), readonly_(readonly) {}
~IndicatorTestCase()74   ~IndicatorTestCase() {}
75 
policy() const76   const base::DictionaryValue& policy() const { return *policy_; }
77 
value() const78   const std::string& value() const { return value_; }
79 
readonly() const80   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:
PrefMapping(const std::string & pref,bool is_local_state,bool check_for_mandatory,bool check_for_recommended,const std::string & indicator_test_setup_js,const std::string & indicator_selector)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) {}
~PrefMapping()106   ~PrefMapping() {}
107 
pref() const108   const std::string& pref() const { return pref_; }
109 
is_local_state() const110   bool is_local_state() const { return is_local_state_; }
111 
check_for_mandatory() const112   bool check_for_mandatory() const { return check_for_mandatory_; }
113 
check_for_recommended() const114   bool check_for_recommended() const { return check_for_recommended_; }
115 
indicator_test_setup_js() const116   const std::string& indicator_test_setup_js() const {
117     return indicator_test_setup_js_;
118   }
119 
indicator_selector() const120   const std::string& indicator_selector() const {
121     return indicator_selector_;
122   }
123 
indicator_test_cases() const124   const ScopedVector<IndicatorTestCase>& indicator_test_cases() const {
125     return indicator_test_cases_;
126   }
AddIndicatorTestCase(IndicatorTestCase * test_case)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:
PolicyTestCase(const std::string & name,bool is_official_only,bool can_be_recommended,const std::string & indicator_selector)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) {}
~PolicyTestCase()155   ~PolicyTestCase() {}
156 
name() const157   const std::string& name() const { return name_; }
158 
is_official_only() const159   bool is_official_only() const { return is_official_only_; }
160 
can_be_recommended() const161   bool can_be_recommended() const { return can_be_recommended_; }
162 
IsOsSupported() const163   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   }
AddSupportedOs(const std::string & os)178   void AddSupportedOs(const std::string& os) { supported_os_.push_back(os); }
179 
IsSupported() const180   bool IsSupported() const {
181 #if !defined(GOOGLE_CHROME_BUILD)
182     if (is_official_only())
183       return false;
184 #endif
185     return IsOsSupported();
186   }
187 
test_policy() const188   const base::DictionaryValue& test_policy() const { return test_policy_; }
SetTestPolicy(const base::DictionaryValue & policy)189   void SetTestPolicy(const base::DictionaryValue& policy) {
190     test_policy_.Clear();
191     test_policy_.MergeDictionary(&policy);
192   }
193 
pref_mappings() const194   const ScopedVector<PrefMapping>& pref_mappings() const {
195     return pref_mappings_;
196   }
AddPrefMapping(PrefMapping * pref_mapping)197   void AddPrefMapping(PrefMapping* pref_mapping) {
198     pref_mappings_.push_back(pref_mapping);
199   }
200 
indicator_selector() const201   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 
PolicyTestCases()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 
~PolicyTestCases()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 
Get(const std::string & name) const269   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 
map() const274   const PolicyTestCaseMap& map() const { return policy_test_cases_; }
begin() const275   iterator begin() const { return policy_test_cases_.begin(); }
end() const276   iterator end() const { return policy_test_cases_.end(); }
277 
278  private:
GetPolicyTestCase(const base::DictionaryValue * tests,const std::string & name)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).
GetRandomNumber(int 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.
SplitPoliciesIntoChunks(int chunk_size)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 
VerifyControlledSettingIndicators(Browser * browser,const std::string & selector,const std::string & value,const std::string & controlled_by,bool readonly)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 
IN_PROC_BROWSER_TEST_F(PolicyPrefsTestCoverageTest,AllPoliciesHaveATestCase)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:
SetUpInProcessBrowserTestFixture()493   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
494     EXPECT_CALL(provider_, IsInitializationComplete(_))
495         .WillRepeatedly(Return(true));
496     BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
497   }
498 
SetUpOnMainThread()499   virtual void SetUpOnMainThread() OVERRIDE {
500     ui_test_utils::WaitForTemplateURLServiceToLoad(
501         TemplateURLServiceFactory::GetForProfile(browser()->profile()));
502   }
503 
TearDownOnMainThread()504   virtual void TearDownOnMainThread() OVERRIDE {
505     ClearProviderPolicy();
506   }
507 
ClearProviderPolicy()508   void ClearProviderPolicy() {
509     provider_.UpdateChromePolicy(PolicyMap());
510     base::RunLoop().RunUntilIdle();
511   }
512 
SetProviderPolicy(const base::DictionaryValue & policies,PolicyLevel level)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.
IN_PROC_BROWSER_TEST_F(PolicyPrefsTest,PolicyToPrefsMapping)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.
IN_PROC_BROWSER_TEST_P(PolicyPrefIndicatorTest,CheckPolicyIndicators)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