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 std::string
& source
,
45 const policy::PolicyMap::Entry
* metadata
,
47 std::vector
<std::string
> expected_policy
;
49 // Populate expected scope.
51 expected_policy
.push_back(l10n_util::GetStringUTF8(
52 metadata
->scope
== policy::POLICY_SCOPE_MACHINE
?
53 IDS_POLICY_SCOPE_DEVICE
: IDS_POLICY_SCOPE_USER
));
55 expected_policy
.push_back(std::string());
58 // Populate expected level.
60 expected_policy
.push_back(l10n_util::GetStringUTF8(
61 metadata
->level
== policy::POLICY_LEVEL_RECOMMENDED
?
62 IDS_POLICY_LEVEL_RECOMMENDED
: IDS_POLICY_LEVEL_MANDATORY
));
64 expected_policy
.push_back(std::string());
66 // Populate expected source name.
67 expected_policy
.push_back(source
);
69 // Populate expected policy name.
70 expected_policy
.push_back(name
);
72 // Populate expected policy value.
73 expected_policy
.push_back(value
);
75 // Populate expected status.
77 expected_policy
.push_back(l10n_util::GetStringUTF8(IDS_POLICY_UNKNOWN
));
79 expected_policy
.push_back(l10n_util::GetStringUTF8(IDS_POLICY_OK
));
81 expected_policy
.push_back(l10n_util::GetStringUTF8(IDS_POLICY_UNSET
));
83 // Populate expected expanded policy value.
84 expected_policy
.push_back(value
);
86 return expected_policy
;
91 class PolicyUITest
: public InProcessBrowserTest
{
94 ~PolicyUITest() override
;
97 // InProcessBrowserTest implementation.
98 void SetUpInProcessBrowserTestFixture() override
;
100 void UpdateProviderPolicy(const policy::PolicyMap
& policy
);
102 void VerifyPolicies(const std::vector
<std::vector
<std::string
> >& expected
);
105 policy::MockConfigurationPolicyProvider provider_
;
108 DISALLOW_COPY_AND_ASSIGN(PolicyUITest
);
111 PolicyUITest::PolicyUITest() {
114 PolicyUITest::~PolicyUITest() {
117 void PolicyUITest::SetUpInProcessBrowserTestFixture() {
118 EXPECT_CALL(provider_
, IsInitializationComplete(_
))
119 .WillRepeatedly(Return(true));
120 policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_
);
123 void PolicyUITest::UpdateProviderPolicy(const policy::PolicyMap
& policy
) {
124 provider_
.UpdateChromePolicy(policy
);
129 void PolicyUITest::VerifyPolicies(
130 const std::vector
<std::vector
<std::string
> >& expected_policies
) {
131 ui_test_utils::NavigateToURL(browser(), GURL("chrome://policy"));
133 // Retrieve the text contents of the policy table cells for all policies.
134 const std::string javascript
=
135 "var entries = document.querySelectorAll("
136 " 'section.policy-table-section > * > tbody');"
138 "for (var i = 0; i < entries.length; ++i) {"
139 " var items = entries[i].querySelectorAll('tr > td');"
141 " for (var j = 0; j < items.length; ++j) {"
142 " var item = items[j];"
143 " var children = item.getElementsByTagName('div');"
144 " if (children.length == 1)"
145 " item = children[0];"
146 " children = item.getElementsByTagName('span');"
147 " if (children.length == 1)"
148 " item = children[0];"
149 " values.push(item.textContent);"
151 " policies.push(values);"
153 "domAutomationController.send(JSON.stringify(policies));";
154 content::WebContents
* contents
=
155 browser()->tab_strip_model()->GetActiveWebContents();
157 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents
, javascript
,
159 scoped_ptr
<base::Value
> value_ptr
= base::JSONReader::Read(json
);
160 const base::ListValue
* actual_policies
= NULL
;
161 ASSERT_TRUE(value_ptr
.get());
162 ASSERT_TRUE(value_ptr
->GetAsList(&actual_policies
));
164 // Verify that the cells contain the expected strings for all policies.
165 ASSERT_EQ(expected_policies
.size(), actual_policies
->GetSize());
166 for (size_t i
= 0; i
< expected_policies
.size(); ++i
) {
167 const std::vector
<std::string
> expected_policy
= expected_policies
[i
];
168 const base::ListValue
* actual_policy
;
169 ASSERT_TRUE(actual_policies
->GetList(i
, &actual_policy
));
170 ASSERT_EQ(expected_policy
.size(), actual_policy
->GetSize());
171 for (size_t j
= 0; j
< expected_policy
.size(); ++j
) {
173 ASSERT_TRUE(actual_policy
->GetString(j
, &value
));
174 EXPECT_EQ(expected_policy
[j
], value
);
179 IN_PROC_BROWSER_TEST_F(PolicyUITest
, SendPolicyNames
) {
180 // Verifies that the names of known policies are sent to the UI and processed
181 // there correctly by checking that the policy table contains all policies in
182 // the correct order.
184 // Expect that the policy table contains all known policies in alphabetical
185 // order and none of the policies have a set value.
186 std::vector
<std::vector
<std::string
> > expected_policies
;
187 policy::Schema chrome_schema
=
188 policy::Schema::Wrap(policy::GetChromeSchemaData());
189 ASSERT_TRUE(chrome_schema
.valid());
190 for (policy::Schema::Iterator it
= chrome_schema
.GetPropertiesIterator();
191 !it
.IsAtEnd(); it
.Advance()) {
192 expected_policies
.push_back(
193 PopulateExpectedPolicy(
194 it
.key(), std::string(), std::string(), nullptr, false));
197 // Retrieve the contents of the policy table from the UI and verify that it
198 // matches the expectation.
199 VerifyPolicies(expected_policies
);
202 IN_PROC_BROWSER_TEST_F(PolicyUITest
, SendPolicyValues
) {
203 // Verifies that policy values are sent to the UI and processed there
204 // correctly by setting the values of four known and one unknown policy and
205 // checking that the policy table contains the policy names, values and
206 // metadata in the correct order.
207 policy::PolicyMap values
;
208 std::map
<std::string
, std::string
> expected_values
;
210 // Set the values of four existing policies.
211 base::ListValue
* restore_on_startup_urls
= new base::ListValue
;
212 restore_on_startup_urls
->Append(new base::StringValue("aaa"));
213 restore_on_startup_urls
->Append(new base::StringValue("bbb"));
214 restore_on_startup_urls
->Append(new base::StringValue("ccc"));
215 values
.Set(policy::key::kRestoreOnStartupURLs
,
216 policy::POLICY_LEVEL_MANDATORY
,
217 policy::POLICY_SCOPE_USER
,
218 policy::POLICY_SOURCE_CLOUD
,
219 restore_on_startup_urls
,
221 expected_values
[policy::key::kRestoreOnStartupURLs
] = "aaa,bbb,ccc";
222 values
.Set(policy::key::kHomepageLocation
,
223 policy::POLICY_LEVEL_MANDATORY
,
224 policy::POLICY_SCOPE_MACHINE
,
225 policy::POLICY_SOURCE_CLOUD
,
226 new base::StringValue("http://google.com"),
228 expected_values
[policy::key::kHomepageLocation
] = "http://google.com";
229 values
.Set(policy::key::kRestoreOnStartup
,
230 policy::POLICY_LEVEL_RECOMMENDED
,
231 policy::POLICY_SCOPE_USER
,
232 policy::POLICY_SOURCE_CLOUD
,
233 new base::FundamentalValue(4),
235 expected_values
[policy::key::kRestoreOnStartup
] = "4";
236 values
.Set(policy::key::kShowHomeButton
,
237 policy::POLICY_LEVEL_RECOMMENDED
,
238 policy::POLICY_SCOPE_MACHINE
,
239 policy::POLICY_SOURCE_CLOUD
,
240 new base::FundamentalValue(true),
242 expected_values
[policy::key::kShowHomeButton
] = "true";
243 // Set the value of a policy that does not exist.
244 const std::string kUnknownPolicy
= "NoSuchThing";
245 values
.Set(kUnknownPolicy
,
246 policy::POLICY_LEVEL_MANDATORY
,
247 policy::POLICY_SCOPE_USER
,
248 policy::POLICY_SOURCE_PLATFORM
,
249 new base::FundamentalValue(true),
251 expected_values
[kUnknownPolicy
] = "true";
252 UpdateProviderPolicy(values
);
254 // Expect that the policy table contains, in order:
255 // * All known policies whose value has been set, in alphabetical order.
256 // * The unknown policy.
257 // * All known policies whose value has not been set, in alphabetical order.
258 std::vector
<std::vector
<std::string
> > expected_policies
;
259 size_t first_unset_position
= 0;
260 policy::Schema chrome_schema
=
261 policy::Schema::Wrap(policy::GetChromeSchemaData());
262 ASSERT_TRUE(chrome_schema
.valid());
263 for (policy::Schema::Iterator props
= chrome_schema
.GetPropertiesIterator();
264 !props
.IsAtEnd(); props
.Advance()) {
265 std::map
<std::string
, std::string
>::const_iterator it
=
266 expected_values
.find(props
.key());
267 const std::string value
=
268 it
== expected_values
.end() ? std::string() : it
->second
;
269 const std::string source
=
270 it
== expected_values
.end() ? std::string() : "Cloud";
271 const policy::PolicyMap::Entry
* metadata
= values
.Get(props
.key());
272 expected_policies
.insert(
273 metadata
? expected_policies
.begin() + first_unset_position
++ :
274 expected_policies
.end(),
275 PopulateExpectedPolicy(props
.key(), value
, source
, metadata
, false));
277 expected_policies
.insert(
278 expected_policies
.begin() + first_unset_position
++,
279 PopulateExpectedPolicy(kUnknownPolicy
,
280 expected_values
[kUnknownPolicy
],
282 values
.Get(kUnknownPolicy
),
285 // Retrieve the contents of the policy table from the UI and verify that it
286 // matches the expectation.
287 VerifyPolicies(expected_policies
);
290 IN_PROC_BROWSER_TEST_F(PolicyUITest
, ExtensionLoadAndSendPolicy
) {
291 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIPolicyURL
));
292 base::ScopedTempDir temp_dir_
;
293 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
295 const std::string newly_added_policy_name
= "new_policy";
296 std::string json_data
= "{\"type\": \"object\",\"properties\": {\"" +
297 newly_added_policy_name
+
298 "\": { \"type\": \"string\"}}}";
300 const std::string schema_file
= "schema.json";
301 base::FilePath schema_path
= temp_dir_
.path().AppendASCII(schema_file
);
302 base::WriteFile(schema_path
, json_data
.data(), json_data
.size());
304 // Build extension that contains the policy schema.
305 extensions::DictionaryBuilder storage
;
306 storage
.Set("managed_schema", schema_file
);
308 extensions::DictionaryBuilder manifest
;
309 manifest
.Set("name", "test")
311 .Set("manifest_version", 2)
312 .Set("storage", storage
);
314 extensions::ExtensionBuilder builder
;
315 builder
.SetPath(temp_dir_
.path());
316 builder
.SetManifest(manifest
);
318 // Install extension.
319 ExtensionService
* service
= extensions::ExtensionSystem::Get(
320 browser()->profile())->extension_service();
321 EXPECT_CALL(provider_
, RefreshPolicies());
322 service
->OnExtensionInstalled(builder
.Build().get(), syncer::StringOrdinal(),
325 std::vector
<std::vector
<std::string
>> expected_policies
;
326 policy::Schema chrome_schema
=
327 policy::Schema::Wrap(policy::GetChromeSchemaData());
328 ASSERT_TRUE(chrome_schema
.valid());
330 for (policy::Schema::Iterator it
= chrome_schema
.GetPropertiesIterator();
331 !it
.IsAtEnd(); it
.Advance()) {
332 expected_policies
.push_back(
333 PopulateExpectedPolicy(
334 it
.key(), std::string(), std::string(), nullptr, false));
336 // Add newly added policy to expected policy list.
337 expected_policies
.push_back(PopulateExpectedPolicy(
338 newly_added_policy_name
, std::string(), std::string(), nullptr, false));
340 // Verify if policy UI includes policy that extension have.
341 VerifyPolicies(expected_policies
);