1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "base/callback.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/json/json_reader.h"
10 #include "base/run_loop.h"
11 #include "base/values.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/extensions/test_extension_system.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/url_constants.h"
18 #include "chrome/test/base/in_process_browser_test.h"
19 #include "chrome/test/base/ui_test_utils.h"
20 #include "components/policy/core/browser/browser_policy_connector.h"
21 #include "components/policy/core/common/external_data_fetcher.h"
22 #include "components/policy/core/common/mock_configuration_policy_provider.h"
23 #include "components/policy/core/common/policy_map.h"
24 #include "components/policy/core/common/policy_types.h"
25 #include "components/policy/core/common/schema.h"
26 #include "content/public/browser/web_contents.h"
27 #include "content/public/test/browser_test_utils.h"
28 #include "extensions/common/extension_builder.h"
29 #include "grit/components_strings.h"
30 #include "policy/policy_constants.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "ui/base/l10n/l10n_util.h"
36 using testing::Return
;
41 std::vector
<std::string
> PopulateExpectedPolicy(
42 const std::string
& name
,
43 const std::string
& value
,
44 const policy::PolicyMap::Entry
* metadata
,
46 std::vector
<std::string
> expected_policy
;
48 // Populate expected scope.
50 expected_policy
.push_back(l10n_util::GetStringUTF8(
51 metadata
->scope
== policy::POLICY_SCOPE_MACHINE
?
52 IDS_POLICY_SCOPE_DEVICE
: IDS_POLICY_SCOPE_USER
));
54 expected_policy
.push_back(std::string());
57 // Populate expected level.
59 expected_policy
.push_back(l10n_util::GetStringUTF8(
60 metadata
->level
== policy::POLICY_LEVEL_RECOMMENDED
?
61 IDS_POLICY_LEVEL_RECOMMENDED
: IDS_POLICY_LEVEL_MANDATORY
));
63 expected_policy
.push_back(std::string());
66 // Populate expected policy name.
67 expected_policy
.push_back(name
);
69 // Populate expected policy value.
70 expected_policy
.push_back(value
);
72 // Populate expected status.
74 expected_policy
.push_back(l10n_util::GetStringUTF8(IDS_POLICY_UNKNOWN
));
76 expected_policy
.push_back(l10n_util::GetStringUTF8(IDS_POLICY_OK
));
78 expected_policy
.push_back(l10n_util::GetStringUTF8(IDS_POLICY_UNSET
));
80 // Populate expected expanded policy value.
81 expected_policy
.push_back(value
);
83 return expected_policy
;
88 class PolicyUITest
: public InProcessBrowserTest
{
91 ~PolicyUITest() override
;
94 // InProcessBrowserTest implementation.
95 void SetUpInProcessBrowserTestFixture() override
;
97 void UpdateProviderPolicy(const policy::PolicyMap
& policy
);
99 void VerifyPolicies(const std::vector
<std::vector
<std::string
> >& expected
);
102 policy::MockConfigurationPolicyProvider provider_
;
105 DISALLOW_COPY_AND_ASSIGN(PolicyUITest
);
108 PolicyUITest::PolicyUITest() {
111 PolicyUITest::~PolicyUITest() {
114 void PolicyUITest::SetUpInProcessBrowserTestFixture() {
115 EXPECT_CALL(provider_
, IsInitializationComplete(_
))
116 .WillRepeatedly(Return(true));
117 policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_
);
120 void PolicyUITest::UpdateProviderPolicy(const policy::PolicyMap
& policy
) {
121 provider_
.UpdateChromePolicy(policy
);
126 void PolicyUITest::VerifyPolicies(
127 const std::vector
<std::vector
<std::string
> >& expected_policies
) {
128 ui_test_utils::NavigateToURL(browser(), GURL("chrome://policy"));
130 // Retrieve the text contents of the policy table cells for all policies.
131 const std::string javascript
=
132 "var entries = document.querySelectorAll("
133 " 'section.policy-table-section > * > tbody');"
135 "for (var i = 0; i < entries.length; ++i) {"
136 " var items = entries[i].querySelectorAll('tr > td');"
138 " for (var j = 0; j < items.length; ++j) {"
139 " var item = items[j];"
140 " var children = item.getElementsByTagName('div');"
141 " if (children.length == 1)"
142 " item = children[0];"
143 " children = item.getElementsByTagName('span');"
144 " if (children.length == 1)"
145 " item = children[0];"
146 " values.push(item.textContent);"
148 " policies.push(values);"
150 "domAutomationController.send(JSON.stringify(policies));";
151 content::WebContents
* contents
=
152 browser()->tab_strip_model()->GetActiveWebContents();
154 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents
, javascript
,
156 scoped_ptr
<base::Value
> value_ptr
= base::JSONReader::Read(json
);
157 const base::ListValue
* actual_policies
= NULL
;
158 ASSERT_TRUE(value_ptr
.get());
159 ASSERT_TRUE(value_ptr
->GetAsList(&actual_policies
));
161 // Verify that the cells contain the expected strings for all policies.
162 ASSERT_EQ(expected_policies
.size(), actual_policies
->GetSize());
163 for (size_t i
= 0; i
< expected_policies
.size(); ++i
) {
164 const std::vector
<std::string
> expected_policy
= expected_policies
[i
];
165 const base::ListValue
* actual_policy
;
166 ASSERT_TRUE(actual_policies
->GetList(i
, &actual_policy
));
167 ASSERT_EQ(expected_policy
.size(), actual_policy
->GetSize());
168 for (size_t j
= 0; j
< expected_policy
.size(); ++j
) {
170 ASSERT_TRUE(actual_policy
->GetString(j
, &value
));
171 EXPECT_EQ(expected_policy
[j
], value
);
176 IN_PROC_BROWSER_TEST_F(PolicyUITest
, SendPolicyNames
) {
177 // Verifies that the names of known policies are sent to the UI and processed
178 // there correctly by checking that the policy table contains all policies in
179 // the correct order.
181 // Expect that the policy table contains all known policies in alphabetical
182 // order and none of the policies have a set value.
183 std::vector
<std::vector
<std::string
> > expected_policies
;
184 policy::Schema chrome_schema
=
185 policy::Schema::Wrap(policy::GetChromeSchemaData());
186 ASSERT_TRUE(chrome_schema
.valid());
187 for (policy::Schema::Iterator it
= chrome_schema
.GetPropertiesIterator();
188 !it
.IsAtEnd(); it
.Advance()) {
189 expected_policies
.push_back(
190 PopulateExpectedPolicy(it
.key(), std::string(), NULL
, false));
193 // Retrieve the contents of the policy table from the UI and verify that it
194 // matches the expectation.
195 VerifyPolicies(expected_policies
);
198 IN_PROC_BROWSER_TEST_F(PolicyUITest
, SendPolicyValues
) {
199 // Verifies that policy values are sent to the UI and processed there
200 // correctly by setting the values of four known and one unknown policy and
201 // checking that the policy table contains the policy names, values and
202 // metadata in the correct order.
203 policy::PolicyMap values
;
204 std::map
<std::string
, std::string
> expected_values
;
206 // Set the values of four existing policies.
207 base::ListValue
* restore_on_startup_urls
= new base::ListValue
;
208 restore_on_startup_urls
->Append(new base::StringValue("aaa"));
209 restore_on_startup_urls
->Append(new base::StringValue("bbb"));
210 restore_on_startup_urls
->Append(new base::StringValue("ccc"));
211 values
.Set(policy::key::kRestoreOnStartupURLs
,
212 policy::POLICY_LEVEL_MANDATORY
,
213 policy::POLICY_SCOPE_USER
,
214 restore_on_startup_urls
,
216 expected_values
[policy::key::kRestoreOnStartupURLs
] = "aaa,bbb,ccc";
217 values
.Set(policy::key::kHomepageLocation
,
218 policy::POLICY_LEVEL_MANDATORY
,
219 policy::POLICY_SCOPE_MACHINE
,
220 new base::StringValue("http://google.com"),
222 expected_values
[policy::key::kHomepageLocation
] = "http://google.com";
223 values
.Set(policy::key::kRestoreOnStartup
,
224 policy::POLICY_LEVEL_RECOMMENDED
,
225 policy::POLICY_SCOPE_USER
,
226 new base::FundamentalValue(4),
228 expected_values
[policy::key::kRestoreOnStartup
] = "4";
229 values
.Set(policy::key::kShowHomeButton
,
230 policy::POLICY_LEVEL_RECOMMENDED
,
231 policy::POLICY_SCOPE_MACHINE
,
232 new base::FundamentalValue(true),
234 expected_values
[policy::key::kShowHomeButton
] = "true";
235 // Set the value of a policy that does not exist.
236 const std::string kUnknownPolicy
= "NoSuchThing";
237 values
.Set(kUnknownPolicy
,
238 policy::POLICY_LEVEL_MANDATORY
,
239 policy::POLICY_SCOPE_USER
,
240 new base::FundamentalValue(true),
242 expected_values
[kUnknownPolicy
] = "true";
243 UpdateProviderPolicy(values
);
245 // Expect that the policy table contains, in order:
246 // * All known policies whose value has been set, in alphabetical order.
247 // * The unknown policy.
248 // * All known policies whose value has not been set, in alphabetical order.
249 std::vector
<std::vector
<std::string
> > expected_policies
;
250 size_t first_unset_position
= 0;
251 policy::Schema chrome_schema
=
252 policy::Schema::Wrap(policy::GetChromeSchemaData());
253 ASSERT_TRUE(chrome_schema
.valid());
254 for (policy::Schema::Iterator props
= chrome_schema
.GetPropertiesIterator();
255 !props
.IsAtEnd(); props
.Advance()) {
256 std::map
<std::string
, std::string
>::const_iterator it
=
257 expected_values
.find(props
.key());
258 const std::string value
=
259 it
== expected_values
.end() ? std::string() : it
->second
;
260 const policy::PolicyMap::Entry
* metadata
= values
.Get(props
.key());
261 expected_policies
.insert(
262 metadata
? expected_policies
.begin() + first_unset_position
++ :
263 expected_policies
.end(),
264 PopulateExpectedPolicy(props
.key(), value
, metadata
, false));
266 expected_policies
.insert(
267 expected_policies
.begin() + first_unset_position
++,
268 PopulateExpectedPolicy(kUnknownPolicy
,
269 expected_values
[kUnknownPolicy
],
270 values
.Get(kUnknownPolicy
),
273 // Retrieve the contents of the policy table from the UI and verify that it
274 // matches the expectation.
275 VerifyPolicies(expected_policies
);
278 IN_PROC_BROWSER_TEST_F(PolicyUITest
, ExtensionLoadAndSendPolicy
) {
279 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIPolicyURL
));
280 base::ScopedTempDir temp_dir_
;
281 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
283 const std::string newly_added_policy_name
= "new_policy";
284 std::string json_data
= "{\"type\": \"object\",\"properties\": {\"" +
285 newly_added_policy_name
+
286 "\": { \"type\": \"string\"}}}";
288 const std::string schema_file
= "schema.json";
289 base::FilePath schema_path
= temp_dir_
.path().AppendASCII(schema_file
);
290 base::WriteFile(schema_path
, json_data
.data(), json_data
.size());
292 // Build extension that contains the policy schema.
293 extensions::DictionaryBuilder storage
;
294 storage
.Set("managed_schema", schema_file
);
296 extensions::DictionaryBuilder manifest
;
297 manifest
.Set("name", "test")
299 .Set("manifest_version", 2)
300 .Set("storage", storage
);
302 extensions::ExtensionBuilder builder
;
303 builder
.SetPath(temp_dir_
.path());
304 builder
.SetManifest(manifest
);
306 // Install extension.
307 ExtensionService
* service
= extensions::ExtensionSystem::Get(
308 browser()->profile())->extension_service();
309 EXPECT_CALL(provider_
, RefreshPolicies());
310 service
->OnExtensionInstalled(builder
.Build().get(), syncer::StringOrdinal(),
313 std::vector
<std::vector
<std::string
>> expected_policies
;
314 policy::Schema chrome_schema
=
315 policy::Schema::Wrap(policy::GetChromeSchemaData());
316 ASSERT_TRUE(chrome_schema
.valid());
318 for (policy::Schema::Iterator it
= chrome_schema
.GetPropertiesIterator();
319 !it
.IsAtEnd(); it
.Advance()) {
320 expected_policies
.push_back(
321 PopulateExpectedPolicy(it
.key(), std::string(), NULL
, false));
323 // Add newly added policy to expected policy list.
324 expected_policies
.push_back(PopulateExpectedPolicy(
325 newly_added_policy_name
, std::string(), NULL
, false));
327 // Verify if policy UI includes policy that extension have.
328 VerifyPolicies(expected_policies
);