Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc

Issue 2801583003: developerPrivate.repair: Skip not-corrupted and policy extensions (Closed)
Patch Set: change Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/developer_private/developer_private_api. h" 5 #include "chrome/browser/extensions/api/developer_private/developer_private_api. h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/extensions/error_console/error_console.h" 15 #include "chrome/browser/extensions/error_console/error_console.h"
15 #include "chrome/browser/extensions/extension_function_test_utils.h" 16 #include "chrome/browser/extensions/extension_function_test_utils.h"
16 #include "chrome/browser/extensions/extension_service.h" 17 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/extensions/extension_service_test_base.h" 18 #include "chrome/browser/extensions/extension_service_test_with_install.h"
18 #include "chrome/browser/extensions/extension_util.h" 19 #include "chrome/browser/extensions/extension_util.h"
19 #include "chrome/browser/extensions/scripting_permissions_modifier.h" 20 #include "chrome/browser/extensions/scripting_permissions_modifier.h"
20 #include "chrome/browser/extensions/test_extension_dir.h" 21 #include "chrome/browser/extensions/test_extension_dir.h"
21 #include "chrome/browser/extensions/test_extension_system.h" 22 #include "chrome/browser/extensions/test_extension_system.h"
22 #include "chrome/browser/extensions/unpacked_installer.h" 23 #include "chrome/browser/extensions/unpacked_installer.h"
23 #include "chrome/browser/ui/browser.h" 24 #include "chrome/browser/ui/browser.h"
24 #include "chrome/common/extensions/api/developer_private.h" 25 #include "chrome/common/extensions/api/developer_private.h"
25 #include "chrome/common/pref_names.h" 26 #include "chrome/common/pref_names.h"
26 #include "chrome/test/base/test_browser_window.h" 27 #include "chrome/test/base/test_browser_window.h"
27 #include "components/crx_file/id_util.h" 28 #include "components/crx_file/id_util.h"
28 #include "components/policy/core/browser/browser_policy_connector.h" 29 #include "components/policy/core/browser/browser_policy_connector.h"
29 #include "components/policy/core/common/mock_configuration_policy_provider.h" 30 #include "components/policy/core/common/mock_configuration_policy_provider.h"
30 #include "components/policy/core/common/policy_map.h" 31 #include "components/policy/core/common/policy_map.h"
31 #include "components/policy/core/common/policy_service_impl.h" 32 #include "components/policy/core/common/policy_service_impl.h"
32 #include "components/policy/core/common/policy_types.h" 33 #include "components/policy/core/common/policy_types.h"
33 #include "components/policy/policy_constants.h" 34 #include "components/policy/policy_constants.h"
34 #include "components/sync_preferences/testing_pref_service_syncable.h" 35 #include "components/sync_preferences/testing_pref_service_syncable.h"
36 #include "content/public/browser/notification_service.h"
35 #include "content/public/test/web_contents_tester.h" 37 #include "content/public/test/web_contents_tester.h"
36 #include "extensions/browser/api_test_utils.h" 38 #include "extensions/browser/api_test_utils.h"
37 #include "extensions/browser/event_router_factory.h" 39 #include "extensions/browser/event_router_factory.h"
38 #include "extensions/browser/extension_error_test_util.h" 40 #include "extensions/browser/extension_error_test_util.h"
39 #include "extensions/browser/extension_prefs.h" 41 #include "extensions/browser/extension_prefs.h"
40 #include "extensions/browser/extension_registry.h" 42 #include "extensions/browser/extension_registry.h"
41 #include "extensions/browser/extension_system.h" 43 #include "extensions/browser/extension_system.h"
42 #include "extensions/browser/extension_util.h" 44 #include "extensions/browser/extension_util.h"
45 #include "extensions/browser/external_install_info.h"
43 #include "extensions/browser/test_extension_registry_observer.h" 46 #include "extensions/browser/test_extension_registry_observer.h"
44 #include "extensions/common/extension.h" 47 #include "extensions/common/extension.h"
45 #include "extensions/common/extension_builder.h" 48 #include "extensions/common/extension_builder.h"
46 #include "extensions/common/extension_set.h" 49 #include "extensions/common/extension_set.h"
47 #include "extensions/common/feature_switch.h" 50 #include "extensions/common/feature_switch.h"
48 #include "extensions/common/manifest_constants.h" 51 #include "extensions/common/manifest_constants.h"
49 #include "extensions/common/test_util.h" 52 #include "extensions/common/test_util.h"
50 #include "extensions/common/value_builder.h" 53 #include "extensions/common/value_builder.h"
51 54
52 using testing::Return; 55 using testing::Return;
53 using testing::_; 56 using testing::_;
54 57
55 namespace extensions { 58 namespace extensions {
56 59
57 namespace { 60 namespace {
58 61
62 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
63
59 std::unique_ptr<KeyedService> BuildAPI(content::BrowserContext* context) { 64 std::unique_ptr<KeyedService> BuildAPI(content::BrowserContext* context) {
60 return base::MakeUnique<DeveloperPrivateAPI>(context); 65 return base::MakeUnique<DeveloperPrivateAPI>(context);
61 } 66 }
62 67
63 std::unique_ptr<KeyedService> BuildEventRouter( 68 std::unique_ptr<KeyedService> BuildEventRouter(
64 content::BrowserContext* profile) { 69 content::BrowserContext* profile) {
65 return base::MakeUnique<EventRouter>(profile, ExtensionPrefs::Get(profile)); 70 return base::MakeUnique<EventRouter>(profile, ExtensionPrefs::Get(profile));
66 } 71 }
67 72
68 bool HasAllUrlsPermission(const Extension* extension, 73 bool HasAllUrlsPermission(const Extension* extension,
69 content::BrowserContext* context) { 74 content::BrowserContext* context) {
70 return ScriptingPermissionsModifier(context, extension).IsAllowedOnAllUrls(); 75 return ScriptingPermissionsModifier(context, extension).IsAllowedOnAllUrls();
71 } 76 }
72 77
73 bool HasPrefsPermission(bool (*has_pref)(const std::string&, 78 bool HasPrefsPermission(bool (*has_pref)(const std::string&,
74 content::BrowserContext*), 79 content::BrowserContext*),
75 content::BrowserContext* context, 80 content::BrowserContext* context,
76 const std::string& id) { 81 const std::string& id) {
77 return has_pref(id, context); 82 return has_pref(id, context);
78 } 83 }
79 84
85 // This class is almost entirely copied from extension_service_unittest.cc.
86 // TODO(lazyboy): ) Extract to a separate file.
87 class MockExtensionProvider : public extensions::ExternalProviderInterface {
88 public:
89 MockExtensionProvider(VisitorInterface* visitor, Manifest::Location location)
90 : location_(location), visitor_(visitor) {}
91
92 ~MockExtensionProvider() override {}
93
94 void AddExtension(const std::string& id,
95 const std::string& version,
96 const base::FilePath& path) {
97 extension_map_[id] = std::make_pair(version, path);
98 }
99
100 void RemoveExtension(const std::string& id) { extension_map_.erase(id); }
101
102 // ExternalProvider implementation:
103 void VisitRegisteredExtension() override {
104 for (DataMap::const_iterator i = extension_map_.begin();
105 i != extension_map_.end(); ++i) {
106 std::unique_ptr<base::Version> version(
107 new base::Version(i->second.first));
108
109 std::unique_ptr<ExternalInstallInfoFile> info(new ExternalInstallInfoFile(
110 i->first, std::move(version), i->second.second, location_,
111 Extension::NO_FLAGS, false, false));
112 visitor_->OnExternalExtensionFileFound(*info);
113 }
114 visitor_->OnExternalProviderReady(this);
115 }
116
117 bool HasExtension(const std::string& id) const override {
118 return extension_map_.find(id) != extension_map_.end();
119 }
120
121 bool GetExtensionDetails(
122 const std::string& id,
123 Manifest::Location* location,
124 std::unique_ptr<base::Version>* version) const override {
125 DataMap::const_iterator it = extension_map_.find(id);
126 if (it == extension_map_.end())
127 return false;
128
129 if (version)
130 version->reset(new base::Version(it->second.first));
131
132 if (location)
133 *location = location_;
134
135 return true;
136 }
137
138 bool IsReady() const override { return true; }
139
140 void ServiceShutdown() override {}
141
142 private:
143 using DataMap = std::map<std::string, std::pair<std::string, base::FilePath>>;
144 DataMap extension_map_;
145 Manifest::Location location_;
146 VisitorInterface* visitor_;
147
148 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
149 };
150
80 } // namespace 151 } // namespace
81 152
82 class DeveloperPrivateApiUnitTest : public ExtensionServiceTestBase { 153 class DeveloperPrivateApiUnitTest : public ExtensionServiceTestWithInstall {
83 protected: 154 protected:
84 DeveloperPrivateApiUnitTest() {} 155 DeveloperPrivateApiUnitTest() {}
85 ~DeveloperPrivateApiUnitTest() override {} 156 ~DeveloperPrivateApiUnitTest() override {}
86 157
158 void AddMockExternalProvider(
159 std::unique_ptr<ExternalProviderInterface> provider) {
160 service()->AddProviderForTesting(std::move(provider));
161 }
162
87 // A wrapper around extension_function_test_utils::RunFunction that runs with 163 // A wrapper around extension_function_test_utils::RunFunction that runs with
88 // the associated browser, no flags, and can take stack-allocated arguments. 164 // the associated browser, no flags, and can take stack-allocated arguments.
89 bool RunFunction(const scoped_refptr<UIThreadExtensionFunction>& function, 165 bool RunFunction(const scoped_refptr<UIThreadExtensionFunction>& function,
90 const base::ListValue& args); 166 const base::ListValue& args);
91 167
92 // Loads an unpacked extension that is backed by a real directory, allowing 168 // Loads an unpacked extension that is backed by a real directory, allowing
93 // it to be reloaded. 169 // it to be reloaded.
94 const Extension* LoadUnpackedExtension(); 170 const Extension* LoadUnpackedExtension();
95 171
96 // Loads an extension with no real directory; this is faster, but means the 172 // Loads an extension with no real directory; this is faster, but means the
(...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 ListBuilder() 923 ListBuilder()
848 .Append( 924 .Append(
849 DictionaryBuilder().Set("extensionId", extension->id()).Build()) 925 DictionaryBuilder().Set("extensionId", extension->id()).Build())
850 .Build(); 926 .Build();
851 function = new api::DeveloperPrivateDeleteExtensionErrorsFunction(); 927 function = new api::DeveloperPrivateDeleteExtensionErrorsFunction();
852 EXPECT_TRUE(RunFunction(function, *args)) << function->GetError(); 928 EXPECT_TRUE(RunFunction(function, *args)) << function->GetError();
853 // No more errors! 929 // No more errors!
854 EXPECT_TRUE(error_console->GetErrorsForExtension(extension->id()).empty()); 930 EXPECT_TRUE(error_console->GetErrorsForExtension(extension->id()).empty());
855 } 931 }
856 932
933 // Tests that developerPrivate.repair does not succeed for a non-corrupted
934 // extension and any policy extension.
935 // Regression test for https://crbug.com/577959.
936 TEST_F(DeveloperPrivateApiUnitTest, RepairNotBrokenExtension) {
937 std::string extension_id(good_crx);
938
939 // Set up a mock provider with a policy extension.
940 std::unique_ptr<MockExtensionProvider> mock_provider =
941 base::MakeUnique<MockExtensionProvider>(
942 service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
943 MockExtensionProvider* mock_provider_ptr = mock_provider.get();
944 AddMockExternalProvider(std::move(mock_provider));
945 mock_provider_ptr->AddExtension(extension_id, "1.0.0.0",
946 data_dir().AppendASCII("good.crx"));
947 // Reloading extensions should find our externally registered extension
948 // and install it.
949 content::WindowedNotificationObserver observer(
950 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
951 content::NotificationService::AllSources());
952 service()->CheckForExternalUpdates();
953 observer.Wait();
954
955 // Attempt to repair the good extension, expect failure.
956 std::unique_ptr<base::ListValue> args =
957 ListBuilder().Append(extension_id).Build();
958 scoped_refptr<UIThreadExtensionFunction> function =
959 new api::DeveloperPrivateRepairExtensionFunction();
960 EXPECT_FALSE(RunFunction(function, *args));
961 EXPECT_EQ("Cannot repair a not corrupted extension.", function->GetError());
962
963 // Corrupt the extension , still expect repair failure because this is a
964 // policy extension.
965 service()->DisableExtension(extension_id, Extension::DISABLE_CORRUPTED);
966 args = ListBuilder().Append(extension_id).Build();
967 function = new api::DeveloperPrivateRepairExtensionFunction();
968 EXPECT_FALSE(RunFunction(function, *args));
969 EXPECT_EQ("Cannot repair a policy extension.", function->GetError());
Devlin 2017/04/06 21:01:32 I'd slightly prefer two separate tests - one for u
lazyboy 2017/04/06 22:32:56 Done.
970 }
971
857 // Test developerPrivate.updateProfileConfiguration: Try to turn on devMode 972 // Test developerPrivate.updateProfileConfiguration: Try to turn on devMode
858 // when DeveloperToolsDisabled policy is active. 973 // when DeveloperToolsDisabled policy is active.
859 TEST_F(DeveloperPrivateApiUnitTest, DeveloperPrivateDevModeDisabledPolicy) { 974 TEST_F(DeveloperPrivateApiUnitTest, DeveloperPrivateDevModeDisabledPolicy) {
860 testing_pref_service()->SetManagedPref(prefs::kExtensionsUIDeveloperMode, 975 testing_pref_service()->SetManagedPref(prefs::kExtensionsUIDeveloperMode,
861 base::MakeUnique<base::Value>(false)); 976 base::MakeUnique<base::Value>(false));
862 977
863 UpdateProfileConfigurationDevMode(true); 978 UpdateProfileConfigurationDevMode(true);
864 979
865 EXPECT_FALSE( 980 EXPECT_FALSE(
866 profile()->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode)); 981 profile()->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode));
(...skipping 15 matching lines...) Expand all
882 EXPECT_TRUE( 997 EXPECT_TRUE(
883 profile()->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode)); 998 profile()->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode));
884 999
885 std::unique_ptr<api::developer_private::ProfileInfo> profile_info; 1000 std::unique_ptr<api::developer_private::ProfileInfo> profile_info;
886 ASSERT_NO_FATAL_FAILURE(GetProfileConfiguration(&profile_info)); 1001 ASSERT_NO_FATAL_FAILURE(GetProfileConfiguration(&profile_info));
887 EXPECT_TRUE(profile_info->in_developer_mode); 1002 EXPECT_TRUE(profile_info->in_developer_mode);
888 EXPECT_FALSE(profile_info->is_developer_mode_controlled_by_policy); 1003 EXPECT_FALSE(profile_info->is_developer_mode_controlled_by_policy);
889 } 1004 }
890 1005
891 } // namespace extensions 1006 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698