1 // Copyright 2018 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 "chrome/chrome_cleaner/chrome_utils/extensions_util.h"
6 
7 #include <memory>
8 #include <string>
9 #include <unordered_set>
10 #include <utility>
11 #include <vector>
12 
13 #include "base/base_paths_win.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/json/json_string_value_serializer.h"
17 #include "base/path_service.h"
18 #include "base/stl_util.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/synchronization/waitable_event.h"
21 #include "base/test/scoped_path_override.h"
22 #include "base/test/test_reg_util_win.h"
23 #include "base/test/test_timeouts.h"
24 #include "base/win/registry.h"
25 #include "chrome/chrome_cleaner/parsers/json_parser/test_json_parser.h"
26 #include "chrome/chrome_cleaner/test/test_extensions.h"
27 #include "chrome/chrome_cleaner/test/test_file_util.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 
31 using base::WaitableEvent;
32 
33 namespace chrome_cleaner {
34 namespace {
35 
36 const int kExtensionIdLength = 32;
37 
38 struct ExtensionIDHash {
operator ()chrome_cleaner::__anon2692d3d50111::ExtensionIDHash39   size_t operator()(const ForceInstalledExtension& extension) const {
40     return std::hash<std::string>{}(extension.id.AsString());
41   }
42 };
43 
44 struct ExtensionIDEqual {
operator ()chrome_cleaner::__anon2692d3d50111::ExtensionIDEqual45   bool operator()(const ForceInstalledExtension& lhs,
46                   const ForceInstalledExtension& rhs) const {
47     return lhs.id == rhs.id;
48   }
49 };
50 
ExtensionPolicyRegistryEntryFound(TestRegistryEntry test_entry,const std::vector<ExtensionPolicyRegistryEntry> & found_policies)51 bool ExtensionPolicyRegistryEntryFound(
52     TestRegistryEntry test_entry,
53     const std::vector<ExtensionPolicyRegistryEntry>& found_policies) {
54   for (const ExtensionPolicyRegistryEntry& policy : found_policies) {
55     std::wstring test_entry_value(test_entry.value);
56     if (policy.extension_id == test_entry_value.substr(0, kExtensionIdLength) &&
57         policy.hkey == test_entry.hkey && policy.path == test_entry.path &&
58         policy.name == test_entry.name) {
59       return true;
60     }
61   }
62   return false;
63 }
64 
65 }  // namespace
66 
TEST(ExtensionsUtilTest,GetExtensionForcelistRegistryPolicies)67 TEST(ExtensionsUtilTest, GetExtensionForcelistRegistryPolicies) {
68   registry_util::RegistryOverrideManager registry_override;
69   registry_override.OverrideRegistry(HKEY_CURRENT_USER);
70   registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);
71   for (const TestRegistryEntry& policy : kExtensionForcelistEntries) {
72     base::win::RegKey policy_key;
73     ASSERT_EQ(ERROR_SUCCESS, policy_key.Create(policy.hkey, policy.path.c_str(),
74                                                KEY_ALL_ACCESS));
75     ASSERT_TRUE(policy_key.Valid());
76     ASSERT_EQ(ERROR_SUCCESS,
77               policy_key.WriteValue(policy.name.c_str(), policy.value.c_str()));
78   }
79 
80   std::vector<ExtensionPolicyRegistryEntry> policies;
81   GetExtensionForcelistRegistryPolicies(&policies);
82 
83   for (const TestRegistryEntry& expected_result : kExtensionForcelistEntries) {
84     EXPECT_TRUE(ExtensionPolicyRegistryEntryFound(expected_result, policies));
85   }
86 }
87 
TEST(ExtensionsUtilTest,RemoveForcelistPolicyExtensions)88 TEST(ExtensionsUtilTest, RemoveForcelistPolicyExtensions) {
89   registry_util::RegistryOverrideManager registry_override;
90   registry_override.OverrideRegistry(HKEY_CURRENT_USER);
91   registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);
92   for (const TestRegistryEntry& policy : kExtensionForcelistEntries) {
93     base::win::RegKey policy_key;
94     ASSERT_EQ(ERROR_SUCCESS, policy_key.Create(policy.hkey, policy.path.c_str(),
95                                                KEY_ALL_ACCESS));
96     DCHECK(policy_key.Valid());
97     ASSERT_EQ(ERROR_SUCCESS,
98               policy_key.WriteValue(policy.name.c_str(), policy.value.c_str()));
99     std::wstring value;
100     policy_key.ReadValue(policy.name.c_str(), &value);
101     ASSERT_EQ(value, policy.value);
102   }
103 
104   std::vector<ForceInstalledExtension> extensions;
105   std::vector<ExtensionPolicyRegistryEntry> policies;
106   GetExtensionForcelistRegistryPolicies(&policies);
107   for (ExtensionPolicyRegistryEntry& policy : policies) {
108     ForceInstalledExtension extension(
109         ExtensionID::Create(base::WideToUTF8(policy.extension_id)).value(),
110         POLICY_EXTENSION_FORCELIST, "", "");
111     extension.policy_registry_entry =
112         std::make_shared<ExtensionPolicyRegistryEntry>(std::move(policy));
113     extensions.push_back(extension);
114   }
115 
116   for (ForceInstalledExtension& extension : extensions) {
117     base::win::RegKey policy_key;
118     ASSERT_TRUE(RemoveForcelistPolicyExtension(extension));
119     ASSERT_EQ(ERROR_SUCCESS,
120               policy_key.Open(extension.policy_registry_entry->hkey,
121                               extension.policy_registry_entry->path.c_str(),
122                               KEY_READ));
123     std::wstring value;
124     policy_key.ReadValue(extension.policy_registry_entry->name.c_str(), &value);
125     ASSERT_EQ(value, L"");
126   }
127 }
128 
TEST(ExtensionsUtilTest,GetNonWhitelistedDefaultExtensions)129 TEST(ExtensionsUtilTest, GetNonWhitelistedDefaultExtensions) {
130   // Set up a fake default extensions JSON file.
131   base::ScopedPathOverride program_files_override(base::DIR_PROGRAM_FILES);
132   base::FilePath program_files_dir;
133   ASSERT_TRUE(
134       base::PathService::Get(base::DIR_PROGRAM_FILES, &program_files_dir));
135 
136   base::FilePath fake_apps_dir(
137       program_files_dir.Append(kFakeChromeFolder).Append(L"default_apps"));
138   ASSERT_TRUE(base::CreateDirectoryAndGetError(fake_apps_dir, nullptr));
139 
140   base::FilePath default_extensions_file =
141       fake_apps_dir.Append(L"external_extensions.json");
142   CreateFileWithContent(default_extensions_file, kDefaultExtensionsJson,
143                         sizeof(kDefaultExtensionsJson) - 1);
144   ASSERT_TRUE(base::PathExists(default_extensions_file));
145 
146   // Set up an invalid default extensions JSON file
147   base::ScopedPathOverride program_files_x86_override(
148       base::DIR_PROGRAM_FILESX86);
149   ASSERT_TRUE(
150       base::PathService::Get(base::DIR_PROGRAM_FILESX86, &program_files_dir));
151 
152   fake_apps_dir =
153       program_files_dir.Append(kFakeChromeFolder).Append(L"default_apps");
154   ASSERT_TRUE(base::CreateDirectoryAndGetError(fake_apps_dir, nullptr));
155 
156   default_extensions_file = fake_apps_dir.Append(L"external_extensions.json");
157   CreateFileWithContent(default_extensions_file, kInvalidDefaultExtensionsJson,
158                         sizeof(kInvalidDefaultExtensionsJson) - 1);
159   ASSERT_TRUE(base::PathExists(default_extensions_file));
160 
161   TestJsonParser json_parser;
162   std::vector<ExtensionPolicyFile> policies;
163   base::WaitableEvent done(WaitableEvent::ResetPolicy::MANUAL,
164                            WaitableEvent::InitialState::NOT_SIGNALED);
165   GetNonWhitelistedDefaultExtensions(&json_parser, &policies, &done);
166   ASSERT_TRUE(done.TimedWait(TestTimeouts::action_timeout()));
167 
168   const std::wstring expected_extension_ids[] = {kTestExtensionId1,
169                                                  kTestExtensionId2};
170   ASSERT_EQ(base::size(expected_extension_ids), policies.size());
171   const std::wstring found_extension_ids[] = {policies[0].extension_id,
172                                               policies[1].extension_id};
173   EXPECT_THAT(expected_extension_ids,
174               ::testing::UnorderedElementsAreArray(found_extension_ids));
175 }
176 
TEST(ExtensionsUtilTest,RemoveNonWhitelistedDefaultExtensions)177 TEST(ExtensionsUtilTest, RemoveNonWhitelistedDefaultExtensions) {
178   // Set up a fake default extensions JSON file.
179   base::ScopedPathOverride program_files_override(base::DIR_PROGRAM_FILES);
180   base::FilePath program_files_dir;
181   ASSERT_TRUE(
182       base::PathService::Get(base::DIR_PROGRAM_FILES, &program_files_dir));
183 
184   base::FilePath fake_apps_dir(
185       program_files_dir.Append(kFakeChromeFolder).Append(L"default_apps"));
186   ASSERT_TRUE(base::CreateDirectoryAndGetError(fake_apps_dir, nullptr));
187 
188   base::FilePath default_extensions_file =
189       fake_apps_dir.Append(L"external_extensions.json");
190   CreateFileWithContent(default_extensions_file, kDefaultExtensionsJson,
191                         sizeof(kDefaultExtensionsJson) - 1);
192   ASSERT_TRUE(base::PathExists(default_extensions_file));
193 
194   // Set up an invalid default extensions JSON file
195   base::ScopedPathOverride program_files_x86_override(
196       base::DIR_PROGRAM_FILESX86);
197   ASSERT_TRUE(
198       base::PathService::Get(base::DIR_PROGRAM_FILESX86, &program_files_dir));
199 
200   fake_apps_dir =
201       program_files_dir.Append(kFakeChromeFolder).Append(L"default_apps");
202   ASSERT_TRUE(base::CreateDirectoryAndGetError(fake_apps_dir, nullptr));
203 
204   default_extensions_file = fake_apps_dir.Append(L"external_extensions.json");
205   CreateFileWithContent(default_extensions_file, kInvalidDefaultExtensionsJson,
206                         sizeof(kInvalidDefaultExtensionsJson) - 1);
207   ASSERT_TRUE(base::PathExists(default_extensions_file));
208 
209   TestJsonParser json_parser;
210   std::vector<ExtensionPolicyFile> policies;
211   base::WaitableEvent done(WaitableEvent::ResetPolicy::MANUAL,
212                            WaitableEvent::InitialState::NOT_SIGNALED);
213   GetNonWhitelistedDefaultExtensions(&json_parser, &policies, &done);
214   ASSERT_TRUE(done.TimedWait(TestTimeouts::action_timeout()));
215 
216   std::vector<ForceInstalledExtension> extensions;
217   for (ExtensionPolicyFile& policy : policies) {
218     ForceInstalledExtension extension(
219         ExtensionID::Create(base::WideToUTF8(policy.extension_id)).value(),
220         DEFAULT_APPS_EXTENSION, "", "");
221     extension.policy_file =
222         std::make_shared<ExtensionPolicyFile>(std::move(policy));
223     extensions.push_back(extension);
224   }
225   base::Value json_result = extensions[0].policy_file->json->data.Clone();
226   for (ForceInstalledExtension& extension : extensions) {
227     ASSERT_TRUE(RemoveDefaultExtension(extension, &json_result));
228   }
229   std::string result;
230   JSONStringValueSerializer serializer(&result);
231   ASSERT_TRUE(serializer.Serialize(json_result));
232   ASSERT_EQ(result, kValidDefaultExtensionsJson);
233   base::Value original = json_result.Clone();
234   for (ForceInstalledExtension& extension : extensions) {
235     ASSERT_FALSE(RemoveDefaultExtension(extension, &json_result));
236     ASSERT_EQ(original, json_result);
237   }
238 }
239 
TEST(ExtensionsUtilTest,GetNonWhitelistedDefaultExtensionsNoFilesFound)240 TEST(ExtensionsUtilTest, GetNonWhitelistedDefaultExtensionsNoFilesFound) {
241   base::ScopedPathOverride program_files_override(base::DIR_PROGRAM_FILES);
242   base::ScopedPathOverride program_files_x86_override(
243       base::DIR_PROGRAM_FILESX86);
244 
245   TestJsonParser json_parser;
246   std::vector<ExtensionPolicyFile> policies;
247   base::WaitableEvent done(WaitableEvent::ResetPolicy::MANUAL,
248                            WaitableEvent::InitialState::NOT_SIGNALED);
249   GetNonWhitelistedDefaultExtensions(&json_parser, &policies, &done);
250   ASSERT_TRUE(done.TimedWait(TestTimeouts::action_timeout()));
251 
252   size_t expected_policies_found = 0;
253   ASSERT_EQ(expected_policies_found, policies.size());
254 }
255 
TEST(ExtensionsUtilTest,GetExtensionSettingsForceInstalledExtensions)256 TEST(ExtensionsUtilTest, GetExtensionSettingsForceInstalledExtensions) {
257   registry_util::RegistryOverrideManager registry_override;
258   registry_override.OverrideRegistry(HKEY_CURRENT_USER);
259   registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);
260 
261   base::win::RegKey settings_key;
262   ASSERT_EQ(ERROR_SUCCESS,
263             settings_key.Create(HKEY_LOCAL_MACHINE,
264                                 kExtensionSettingsPolicyPath, KEY_ALL_ACCESS));
265   ASSERT_TRUE(settings_key.Valid());
266   ASSERT_EQ(ERROR_SUCCESS,
267             settings_key.WriteValue(kExtensionSettingsName,
268                                     kExtensionSettingsJsonOnlyForced));
269 
270   TestJsonParser json_parser;
271   std::vector<ExtensionPolicyRegistryEntry> policies;
272   base::WaitableEvent done(WaitableEvent::ResetPolicy::MANUAL,
273                            WaitableEvent::InitialState::NOT_SIGNALED);
274   GetExtensionSettingsForceInstalledExtensions(&json_parser, &policies, &done);
275   ASSERT_TRUE(done.TimedWait(TestTimeouts::action_timeout()));
276 
277   // Check that only the two force installed extensions were found
278   const std::wstring expected_extension_ids[] = {kTestExtensionId4,
279                                                  kTestExtensionId5};
280   const std::wstring found_extension_ids[] = {policies[0].extension_id,
281                                               policies[1].extension_id};
282   EXPECT_THAT(expected_extension_ids,
283               ::testing::UnorderedElementsAreArray(found_extension_ids));
284 
285   // Also check that the collected registry entries match the values in the
286   // registry.
287   for (const ExtensionPolicyRegistryEntry& policy : policies) {
288     EXPECT_EQ(policy.hkey, HKEY_LOCAL_MACHINE);
289     EXPECT_EQ(policy.path, kExtensionSettingsPolicyPath);
290     EXPECT_EQ(policy.name, kExtensionSettingsName);
291   }
292 }
293 
TEST(ExtensionsUtilTest,RemoveExtensionSettingsForceInstalledExtensions)294 TEST(ExtensionsUtilTest, RemoveExtensionSettingsForceInstalledExtensions) {
295   registry_util::RegistryOverrideManager registry_override;
296   registry_override.OverrideRegistry(HKEY_CURRENT_USER);
297   registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);
298 
299   base::win::RegKey settings_key;
300   ASSERT_EQ(ERROR_SUCCESS,
301             settings_key.Create(HKEY_LOCAL_MACHINE,
302                                 kExtensionSettingsPolicyPath, KEY_ALL_ACCESS));
303   DCHECK(settings_key.Valid());
304   ASSERT_EQ(ERROR_SUCCESS,
305             settings_key.WriteValue(kExtensionSettingsName,
306                                     kExtensionSettingsJsonOnlyForced));
307 
308   TestJsonParser json_parser;
309   std::vector<ExtensionPolicyRegistryEntry> policies;
310   base::WaitableEvent done(WaitableEvent::ResetPolicy::MANUAL,
311                            WaitableEvent::InitialState::NOT_SIGNALED);
312   GetExtensionSettingsForceInstalledExtensions(&json_parser, &policies, &done);
313   ASSERT_TRUE(done.TimedWait(TestTimeouts::action_timeout()));
314 
315   std::unordered_set<ForceInstalledExtension, ExtensionIDHash, ExtensionIDEqual>
316       extensions;
317   base::Value json_result = policies[0].json->data.Clone();
318   for (ExtensionPolicyRegistryEntry& policy : policies) {
319     ForceInstalledExtension extension(
320         ExtensionID::Create(base::WideToUTF8(policy.extension_id)).value(),
321         POLICY_EXTENSION_SETTINGS, "", "");
322     extension.policy_registry_entry =
323         std::make_shared<ExtensionPolicyRegistryEntry>(std::move(policy));
324     extensions.insert(extension);
325   }
326 
327   for (const ForceInstalledExtension& extension : extensions) {
328     ASSERT_TRUE(
329         RemoveExtensionSettingsPoliciesExtension(extension, &json_result));
330   }
331   std::string result;
332   JSONStringValueSerializer serializer(&result);
333   ASSERT_TRUE(serializer.Serialize(json_result));
334   ASSERT_EQ(result, "{}");
335   base::Value original = json_result.Clone();
336   for (const ForceInstalledExtension& extension : extensions) {
337     ASSERT_FALSE(
338         RemoveExtensionSettingsPoliciesExtension(extension, &json_result));
339     ASSERT_EQ(original, json_result);
340   }
341 }
342 
TEST(ExtensionsUtilTest,RemoveSomeExtensionSettingsForceInstalledExtensions)343 TEST(ExtensionsUtilTest, RemoveSomeExtensionSettingsForceInstalledExtensions) {
344   registry_util::RegistryOverrideManager registry_override;
345   registry_override.OverrideRegistry(HKEY_CURRENT_USER);
346   registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);
347 
348   base::win::RegKey settings_key;
349   ASSERT_EQ(ERROR_SUCCESS,
350             settings_key.Create(HKEY_LOCAL_MACHINE,
351                                 kExtensionSettingsPolicyPath, KEY_ALL_ACCESS));
352   DCHECK(settings_key.Valid());
353   ASSERT_EQ(ERROR_SUCCESS, settings_key.WriteValue(kExtensionSettingsName,
354                                                    kExtensionSettingsJson));
355 
356   TestJsonParser json_parser;
357   std::vector<ExtensionPolicyRegistryEntry> policies;
358   base::WaitableEvent done(WaitableEvent::ResetPolicy::MANUAL,
359                            WaitableEvent::InitialState::NOT_SIGNALED);
360   GetExtensionSettingsForceInstalledExtensions(&json_parser, &policies, &done);
361   ASSERT_TRUE(done.TimedWait(TestTimeouts::action_timeout()));
362 
363   std::unordered_set<ForceInstalledExtension, ExtensionIDHash, ExtensionIDEqual>
364       extensions;
365   base::Value json_result = policies[0].json->data.Clone();
366   for (ExtensionPolicyRegistryEntry& policy : policies) {
367     ForceInstalledExtension extension(
368         ExtensionID::Create(base::WideToUTF8(policy.extension_id)).value(),
369         POLICY_EXTENSION_SETTINGS, "", "");
370     extension.policy_registry_entry =
371         std::make_shared<ExtensionPolicyRegistryEntry>(std::move(policy));
372     extensions.insert(extension);
373   }
374 
375   for (const ForceInstalledExtension& extension : extensions) {
376     ASSERT_TRUE(
377         RemoveExtensionSettingsPoliciesExtension(extension, &json_result));
378   }
379   std::string result;
380   JSONStringValueSerializer serializer(&result);
381   ASSERT_TRUE(serializer.Serialize(json_result));
382   ASSERT_EQ(result, kValidExtensionSettingsJson);
383   base::Value original = json_result.Clone();
384   for (const ForceInstalledExtension& extension : extensions) {
385     ASSERT_FALSE(
386         RemoveExtensionSettingsPoliciesExtension(extension, &json_result));
387     ASSERT_EQ(original, json_result);
388   }
389 }
390 
TEST(ExtensionsUtilTest,GetExtensionSettingsForceInstalledExtensionsNoneFound)391 TEST(ExtensionsUtilTest,
392      GetExtensionSettingsForceInstalledExtensionsNoneFound) {
393   registry_util::RegistryOverrideManager registry_override;
394   registry_override.OverrideRegistry(HKEY_CURRENT_USER);
395   registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);
396 
397   TestJsonParser json_parser;
398   std::vector<ExtensionPolicyRegistryEntry> policies;
399   base::WaitableEvent done(WaitableEvent::ResetPolicy::MANUAL,
400                            WaitableEvent::InitialState::NOT_SIGNALED);
401   GetExtensionSettingsForceInstalledExtensions(&json_parser, &policies, &done);
402   ASSERT_TRUE(done.TimedWait(TestTimeouts::action_timeout()));
403 
404   size_t expected_policies_found = 0;
405   ASSERT_EQ(expected_policies_found, policies.size());
406 }
407 
TEST(ExtensionsUtilTest,GetMasterPreferencesExtensions)408 TEST(ExtensionsUtilTest, GetMasterPreferencesExtensions) {
409   // Set up a fake master preferences JSON file.
410   base::ScopedPathOverride program_files_override(base::DIR_PROGRAM_FILES);
411   base::FilePath program_files_dir;
412   ASSERT_TRUE(
413       base::PathService::Get(base::DIR_PROGRAM_FILES, &program_files_dir));
414 
415   base::FilePath chrome_dir(program_files_dir.Append(kChromeExePath));
416   ASSERT_TRUE(base::CreateDirectoryAndGetError(chrome_dir, nullptr));
417 
418   base::FilePath master_preferences =
419       chrome_dir.Append(kMasterPreferencesFileName);
420   CreateFileWithContent(master_preferences, kMasterPreferencesJson,
421                         sizeof(kMasterPreferencesJson) - 1);
422   ASSERT_TRUE(base::PathExists(master_preferences));
423 
424   TestJsonParser json_parser;
425   std::vector<ExtensionPolicyFile> policies;
426   base::WaitableEvent done(WaitableEvent::ResetPolicy::MANUAL,
427                            WaitableEvent::InitialState::NOT_SIGNALED);
428   GetMasterPreferencesExtensions(&json_parser, &policies, &done);
429   ASSERT_TRUE(done.TimedWait(TestTimeouts::action_timeout()));
430 
431   const std::wstring expected_extension_ids[] = {kTestExtensionId6,
432                                                  kTestExtensionId7};
433   ASSERT_EQ(base::size(expected_extension_ids), policies.size());
434   const std::wstring found_extension_ids[] = {policies[0].extension_id,
435                                               policies[1].extension_id};
436   EXPECT_THAT(expected_extension_ids,
437               ::testing::UnorderedElementsAreArray(found_extension_ids));
438 }
439 
TEST(ExtensionsUtilTest,RemoveMasterPreferencesExtensionsNoneFound)440 TEST(ExtensionsUtilTest, RemoveMasterPreferencesExtensionsNoneFound) {
441   // Set up a fake master preferences JSON file.
442   base::ScopedPathOverride program_files_override(base::DIR_PROGRAM_FILES);
443   base::FilePath program_files_dir;
444   ASSERT_TRUE(
445       base::PathService::Get(base::DIR_PROGRAM_FILES, &program_files_dir));
446 
447   base::FilePath chrome_dir(program_files_dir.Append(kChromeExePath));
448   ASSERT_TRUE(base::CreateDirectoryAndGetError(chrome_dir, nullptr));
449 
450   base::FilePath master_preferences =
451       chrome_dir.Append(kMasterPreferencesFileName);
452   CreateFileWithContent(master_preferences, kMasterPreferencesJson,
453                         sizeof(kMasterPreferencesJson) - 1);
454   ASSERT_TRUE(base::PathExists(master_preferences));
455 
456   TestJsonParser json_parser;
457   std::vector<ExtensionPolicyFile> policies;
458   base::WaitableEvent done(WaitableEvent::ResetPolicy::MANUAL,
459                            WaitableEvent::InitialState::NOT_SIGNALED);
460   GetMasterPreferencesExtensions(&json_parser, &policies, &done);
461   ASSERT_TRUE(done.TimedWait(TestTimeouts::action_timeout()));
462 
463   std::vector<ForceInstalledExtension> extensions;
464   for (ExtensionPolicyFile& policy : policies) {
465     ForceInstalledExtension extension(
466         ExtensionID::Create(base::WideToUTF8(policy.extension_id)).value(),
467         POLICY_MASTER_PREFERENCES, "", "");
468     extension.policy_file =
469         std::make_shared<ExtensionPolicyFile>(std::move(policy));
470     extensions.push_back(extension);
471   }
472   base::Value json_result = extensions[0].policy_file->json->data.Clone();
473   for (ForceInstalledExtension& extension : extensions) {
474     ASSERT_TRUE(RemoveMasterPreferencesExtension(extension, &json_result));
475   }
476   std::string result;
477   JSONStringValueSerializer serializer(&result);
478   ASSERT_TRUE(serializer.Serialize(json_result));
479   ASSERT_EQ(result, kValidMasterPreferencesJson);
480 }
481 
TEST(ExtensionsUtilTest,GetMasterPreferencesExtensionsNoneFound)482 TEST(ExtensionsUtilTest, GetMasterPreferencesExtensionsNoneFound) {
483   // Set up a fake master preferences JSON file.
484   base::ScopedPathOverride program_files_override(base::DIR_PROGRAM_FILES);
485   base::FilePath program_files_dir;
486   ASSERT_TRUE(
487       base::PathService::Get(base::DIR_PROGRAM_FILES, &program_files_dir));
488 
489   base::FilePath chrome_dir(program_files_dir.Append(kChromeExePath));
490   ASSERT_TRUE(base::CreateDirectoryAndGetError(chrome_dir, nullptr));
491 
492   base::FilePath master_preferences =
493       chrome_dir.Append(kMasterPreferencesFileName);
494   CreateFileWithContent(master_preferences, kMasterPreferencesJsonNoExtensions,
495                         sizeof(kMasterPreferencesJsonNoExtensions) - 1);
496   ASSERT_TRUE(base::PathExists(master_preferences));
497 
498   TestJsonParser json_parser;
499   std::vector<ExtensionPolicyFile> policies;
500   base::WaitableEvent done(WaitableEvent::ResetPolicy::MANUAL,
501                            WaitableEvent::InitialState::NOT_SIGNALED);
502   GetMasterPreferencesExtensions(&json_parser, &policies, &done);
503   ASSERT_TRUE(done.TimedWait(TestTimeouts::action_timeout()));
504 
505   size_t expected_policies_found = 0;
506   ASSERT_EQ(expected_policies_found, policies.size());
507 }
508 
509 }  // namespace chrome_cleaner
510