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

Side by Side Diff: chrome/browser/extensions/extension_service_unittest.cc

Issue 1411773002: Move Sync-specific tests from ExtensionServiceTest into new file (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@su_ext_reenable
Patch Set: . Created 5 years, 2 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 (c) 2013 The Chromium Authors. All rights reserved. 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 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 <algorithm> 5 #include <algorithm>
6 #include <map>
6 #include <set> 7 #include <set>
8 #include <string>
7 #include <vector> 9 #include <vector>
8 10
9 #include "base/at_exit.h" 11 #include "base/at_exit.h"
10 #include "base/basictypes.h" 12 #include "base/basictypes.h"
11 #include "base/bind.h" 13 #include "base/bind.h"
12 #include "base/command_line.h" 14 #include "base/command_line.h"
13 #include "base/files/file_enumerator.h" 15 #include "base/files/file_enumerator.h"
14 #include "base/files/file_util.h" 16 #include "base/files/file_util.h"
15 #include "base/files/scoped_temp_dir.h" 17 #include "base/files/scoped_temp_dir.h"
16 #include "base/json/json_file_value_serializer.h" 18 #include "base/json/json_file_value_serializer.h"
17 #include "base/json/json_reader.h" 19 #include "base/json/json_reader.h"
18 #include "base/json/json_string_value_serializer.h" 20 #include "base/json/json_string_value_serializer.h"
19 #include "base/location.h" 21 #include "base/location.h"
20 #include "base/memory/scoped_ptr.h" 22 #include "base/memory/scoped_ptr.h"
21 #include "base/memory/weak_ptr.h" 23 #include "base/memory/weak_ptr.h"
22 #include "base/metrics/field_trial.h"
23 #include "base/prefs/scoped_user_pref_update.h" 24 #include "base/prefs/scoped_user_pref_update.h"
24 #include "base/single_thread_task_runner.h" 25 #include "base/single_thread_task_runner.h"
25 #include "base/stl_util.h" 26 #include "base/stl_util.h"
26 #include "base/strings/pattern.h" 27 #include "base/strings/pattern.h"
27 #include "base/strings/string16.h" 28 #include "base/strings/string16.h"
28 #include "base/strings/string_number_conversions.h" 29 #include "base/strings/string_number_conversions.h"
29 #include "base/strings/string_util.h" 30 #include "base/strings/string_util.h"
30 #include "base/strings/utf_string_conversions.h" 31 #include "base/strings/utf_string_conversions.h"
31 #include "base/test/mock_entropy_provider.h"
32 #include "base/thread_task_runner_handle.h" 32 #include "base/thread_task_runner_handle.h"
33 #include "base/version.h" 33 #include "base/version.h"
34 #include "chrome/browser/browser_process.h" 34 #include "chrome/browser/browser_process.h"
35 #include "chrome/browser/chrome_notification_types.h" 35 #include "chrome/browser/chrome_notification_types.h"
36 #include "chrome/browser/extensions/blacklist.h" 36 #include "chrome/browser/extensions/blacklist.h"
37 #include "chrome/browser/extensions/chrome_app_sorting.h" 37 #include "chrome/browser/extensions/chrome_app_sorting.h"
38 #include "chrome/browser/extensions/component_loader.h" 38 #include "chrome/browser/extensions/component_loader.h"
39 #include "chrome/browser/extensions/crx_installer.h" 39 #include "chrome/browser/extensions/crx_installer.h"
40 #include "chrome/browser/extensions/default_apps.h" 40 #include "chrome/browser/extensions/default_apps.h"
41 #include "chrome/browser/extensions/extension_creator.h" 41 #include "chrome/browser/extensions/extension_creator.h"
42 #include "chrome/browser/extensions/extension_error_reporter.h" 42 #include "chrome/browser/extensions/extension_error_reporter.h"
43 #include "chrome/browser/extensions/extension_error_ui.h" 43 #include "chrome/browser/extensions/extension_error_ui.h"
44 #include "chrome/browser/extensions/extension_management_test_util.h" 44 #include "chrome/browser/extensions/extension_management_test_util.h"
45 #include "chrome/browser/extensions/extension_notification_observer.h" 45 #include "chrome/browser/extensions/extension_notification_observer.h"
46 #include "chrome/browser/extensions/extension_service.h" 46 #include "chrome/browser/extensions/extension_service.h"
47 #include "chrome/browser/extensions/extension_service_test_base.h" 47 #include "chrome/browser/extensions/extension_service_test_base.h"
48 #include "chrome/browser/extensions/extension_service_test_with_install.h"
48 #include "chrome/browser/extensions/extension_special_storage_policy.h" 49 #include "chrome/browser/extensions/extension_special_storage_policy.h"
49 #include "chrome/browser/extensions/extension_sync_data.h"
50 #include "chrome/browser/extensions/extension_sync_service.h"
51 #include "chrome/browser/extensions/extension_util.h" 50 #include "chrome/browser/extensions/extension_util.h"
52 #include "chrome/browser/extensions/external_install_error.h" 51 #include "chrome/browser/extensions/external_install_error.h"
53 #include "chrome/browser/extensions/external_install_manager.h" 52 #include "chrome/browser/extensions/external_install_manager.h"
54 #include "chrome/browser/extensions/external_policy_loader.h" 53 #include "chrome/browser/extensions/external_policy_loader.h"
55 #include "chrome/browser/extensions/external_pref_loader.h" 54 #include "chrome/browser/extensions/external_pref_loader.h"
56 #include "chrome/browser/extensions/external_provider_impl.h" 55 #include "chrome/browser/extensions/external_provider_impl.h"
57 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h" 56 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
58 #include "chrome/browser/extensions/installed_loader.h" 57 #include "chrome/browser/extensions/installed_loader.h"
59 #include "chrome/browser/extensions/pack_extension_job.h" 58 #include "chrome/browser/extensions/pack_extension_job.h"
60 #include "chrome/browser/extensions/pending_extension_info.h" 59 #include "chrome/browser/extensions/pending_extension_info.h"
61 #include "chrome/browser/extensions/pending_extension_manager.h" 60 #include "chrome/browser/extensions/pending_extension_manager.h"
62 #include "chrome/browser/extensions/permissions_updater.h" 61 #include "chrome/browser/extensions/permissions_updater.h"
63 #include "chrome/browser/extensions/test_blacklist.h" 62 #include "chrome/browser/extensions/test_blacklist.h"
64 #include "chrome/browser/extensions/test_extension_system.h" 63 #include "chrome/browser/extensions/test_extension_system.h"
65 #include "chrome/browser/extensions/unpacked_installer.h" 64 #include "chrome/browser/extensions/unpacked_installer.h"
66 #include "chrome/browser/extensions/updater/extension_updater.h" 65 #include "chrome/browser/extensions/updater/extension_updater.h"
67 #include "chrome/browser/policy/profile_policy_connector.h" 66 #include "chrome/browser/policy/profile_policy_connector.h"
68 #include "chrome/browser/policy/profile_policy_connector_factory.h" 67 #include "chrome/browser/policy/profile_policy_connector_factory.h"
69 #include "chrome/browser/sync/profile_sync_service.h"
70 #include "chrome/browser/sync/profile_sync_service_factory.h"
71 #include "chrome/common/chrome_constants.h" 68 #include "chrome/common/chrome_constants.h"
72 #include "chrome/common/chrome_switches.h" 69 #include "chrome/common/chrome_switches.h"
73 #include "chrome/common/extensions/api/plugins/plugins_handler.h" 70 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
74 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 71 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
75 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" 72 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
76 #include "chrome/common/extensions/sync_helper.h"
77 #include "chrome/common/pref_names.h" 73 #include "chrome/common/pref_names.h"
78 #include "chrome/common/url_constants.h" 74 #include "chrome/common/url_constants.h"
79 #include "chrome/test/base/scoped_browser_locale.h" 75 #include "chrome/test/base/scoped_browser_locale.h"
80 #include "chrome/test/base/testing_profile.h" 76 #include "chrome/test/base/testing_profile.h"
81 #include "components/crx_file/id_util.h" 77 #include "components/crx_file/id_util.h"
82 #include "components/pref_registry/pref_registry_syncable.h" 78 #include "components/pref_registry/pref_registry_syncable.h"
83 #include "components/syncable_prefs/pref_service_syncable.h" 79 #include "components/syncable_prefs/pref_service_syncable.h"
84 #include "components/syncable_prefs/testing_pref_service_syncable.h" 80 #include "components/syncable_prefs/testing_pref_service_syncable.h"
85 #include "content/public/browser/dom_storage_context.h" 81 #include "content/public/browser/dom_storage_context.h"
86 #include "content/public/browser/gpu_data_manager.h" 82 #include "content/public/browser/gpu_data_manager.h"
87 #include "content/public/browser/indexed_db_context.h" 83 #include "content/public/browser/indexed_db_context.h"
88 #include "content/public/browser/notification_registrar.h"
89 #include "content/public/browser/notification_service.h" 84 #include "content/public/browser/notification_service.h"
90 #include "content/public/browser/plugin_service.h" 85 #include "content/public/browser/plugin_service.h"
91 #include "content/public/browser/render_process_host.h" 86 #include "content/public/browser/render_process_host.h"
92 #include "content/public/browser/storage_partition.h" 87 #include "content/public/browser/storage_partition.h"
93 #include "content/public/common/content_constants.h" 88 #include "content/public/common/content_constants.h"
94 #include "content/public/test/test_browser_thread_bundle.h" 89 #include "content/public/test/test_browser_thread_bundle.h"
95 #include "content/public/test/test_utils.h" 90 #include "content/public/test/test_utils.h"
96 #include "extensions/browser/extension_dialog_auto_confirm.h" 91 #include "extensions/browser/extension_dialog_auto_confirm.h"
97 #include "extensions/browser/extension_prefs.h" 92 #include "extensions/browser/extension_prefs.h"
98 #include "extensions/browser/extension_registry.h" 93 #include "extensions/browser/extension_registry.h"
(...skipping 22 matching lines...) Expand all
121 #include "grit/browser_resources.h" 116 #include "grit/browser_resources.h"
122 #include "grit/generated_resources.h" 117 #include "grit/generated_resources.h"
123 #include "net/cookies/canonical_cookie.h" 118 #include "net/cookies/canonical_cookie.h"
124 #include "net/cookies/cookie_monster.h" 119 #include "net/cookies/cookie_monster.h"
125 #include "net/cookies/cookie_options.h" 120 #include "net/cookies/cookie_options.h"
126 #include "net/url_request/url_request_context.h" 121 #include "net/url_request/url_request_context.h"
127 #include "net/url_request/url_request_context_getter.h" 122 #include "net/url_request/url_request_context_getter.h"
128 #include "storage/browser/database/database_tracker.h" 123 #include "storage/browser/database/database_tracker.h"
129 #include "storage/browser/quota/quota_manager.h" 124 #include "storage/browser/quota/quota_manager.h"
130 #include "storage/common/database/database_identifier.h" 125 #include "storage/common/database/database_identifier.h"
131 #include "sync/api/fake_sync_change_processor.h"
132 #include "sync/api/string_ordinal.h" 126 #include "sync/api/string_ordinal.h"
133 #include "sync/api/sync_data.h" 127 #include "testing/gmock/include/gmock/gmock.h"
134 #include "sync/api/sync_error_factory.h"
135 #include "sync/api/sync_error_factory_mock.h"
136 #include "sync/api/syncable_service.h"
137 #include "sync/protocol/app_specifics.pb.h"
138 #include "sync/protocol/extension_specifics.pb.h"
139 #include "sync/protocol/sync.pb.h"
140 #include "testing/gtest/include/gtest/gtest.h" 128 #include "testing/gtest/include/gtest/gtest.h"
141 #include "testing/platform_test.h" 129 #include "testing/platform_test.h"
142 #include "ui/base/l10n/l10n_util.h" 130 #include "ui/base/l10n/l10n_util.h"
143 #include "ui/base/resource/material_design/material_design_controller.h" 131 #include "ui/base/resource/material_design/material_design_controller.h"
144 #include "url/gurl.h" 132 #include "url/gurl.h"
145 133
146 #if defined(ENABLE_SUPERVISED_USERS)
147 #include "chrome/browser/supervised_user/permission_request_creator.h"
148 #include "chrome/browser/supervised_user/supervised_user_constants.h"
149 #include "chrome/browser/supervised_user/supervised_user_service.h"
150 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
151 #endif
152
153 #if defined(OS_CHROMEOS) 134 #if defined(OS_CHROMEOS)
154 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h" 135 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
155 #include "chrome/browser/chromeos/settings/cros_settings.h" 136 #include "chrome/browser/chromeos/settings/cros_settings.h"
156 #include "chrome/browser/chromeos/settings/device_settings_service.h" 137 #include "chrome/browser/chromeos/settings/device_settings_service.h"
157 #endif 138 #endif
158 139
159 // The blacklist tests rely on the safe-browsing database. 140 // The blacklist tests rely on the safe-browsing database.
160 #if defined(SAFE_BROWSING_DB_LOCAL) 141 #if defined(SAFE_BROWSING_DB_LOCAL)
161 #define ENABLE_BLACKLIST_TESTS 142 #define ENABLE_BLACKLIST_TESTS
162 #endif 143 #endif
163 144
164 using base::DictionaryValue;
165 using base::ListValue;
166 using base::Value;
167 using content::BrowserContext; 145 using content::BrowserContext;
168 using content::BrowserThread; 146 using content::BrowserThread;
169 using content::DOMStorageContext; 147 using content::DOMStorageContext;
170 using content::IndexedDBContext; 148 using content::IndexedDBContext;
171 using content::PluginService; 149 using content::PluginService;
172 using extensions::APIPermission; 150 using extensions::APIPermission;
173 using extensions::APIPermissionSet; 151 using extensions::APIPermissionSet;
174 using extensions::AppSorting; 152 using extensions::AppSorting;
175 using extensions::Blacklist; 153 using extensions::Blacklist;
176 using extensions::CrxInstaller; 154 using extensions::CrxInstaller;
177 using extensions::Extension; 155 using extensions::Extension;
178 using extensions::ExtensionCreator; 156 using extensions::ExtensionCreator;
179 using extensions::ExtensionPrefs; 157 using extensions::ExtensionPrefs;
180 using extensions::ExtensionRegistry; 158 using extensions::ExtensionRegistry;
181 using extensions::ExtensionResource; 159 using extensions::ExtensionResource;
182 using extensions::ExtensionSyncData;
183 using extensions::ExtensionSystem; 160 using extensions::ExtensionSystem;
184 using extensions::FakeSafeBrowsingDatabaseManager; 161 using extensions::FakeSafeBrowsingDatabaseManager;
185 using extensions::FeatureSwitch; 162 using extensions::FeatureSwitch;
186 using extensions::Manifest; 163 using extensions::Manifest;
187 using extensions::PermissionSet; 164 using extensions::PermissionSet;
188 using extensions::TestExtensionSystem; 165 using extensions::TestExtensionSystem;
189 using extensions::UnloadedExtensionInfo; 166 using extensions::UnloadedExtensionInfo;
190 using extensions::URLPatternSet; 167 using extensions::URLPatternSet;
191 168
192 namespace keys = extensions::manifest_keys; 169 namespace keys = extensions::manifest_keys;
193 170
194 namespace { 171 namespace {
195 172
196 // Extension ids used during testing. 173 // Extension ids used during testing.
197 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj"; 174 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
198 const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk"; 175 const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
199 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa"; 176 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
200 const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 177 const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
201 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh"; 178 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
202 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; 179 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
203 const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi"; 180 const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
204 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln"; 181 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
205 const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad"; 182 const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad";
206 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf"; 183 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
207 const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin"; 184 const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
208 const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj"; 185 const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
209 const char permissions_blocklist[] = "noffkehfcaggllbcojjbopcmlhcnhcdn"; 186 const char permissions_blocklist[] = "noffkehfcaggllbcojjbopcmlhcnhcdn";
210 187
211 struct ExtensionsOrder {
212 bool operator()(const scoped_refptr<const Extension>& a,
213 const scoped_refptr<const Extension>& b) {
214 return a->name() < b->name();
215 }
216 };
217
218 static std::vector<base::string16> GetErrors() {
219 const std::vector<base::string16>* errors =
220 ExtensionErrorReporter::GetInstance()->GetErrors();
221 std::vector<base::string16> ret_val;
222
223 for (std::vector<base::string16>::const_iterator iter = errors->begin();
224 iter != errors->end(); ++iter) {
225 std::string utf8_error = base::UTF16ToUTF8(*iter);
226 if (utf8_error.find(".svn") == std::string::npos) {
227 ret_val.push_back(*iter);
228 }
229 }
230
231 // The tests rely on the errors being in a certain order, which can vary
232 // depending on how filesystem iteration works.
233 std::stable_sort(ret_val.begin(), ret_val.end());
234
235 return ret_val;
236 }
237
238 static void AddPattern(URLPatternSet* extent, const std::string& pattern) { 188 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
239 int schemes = URLPattern::SCHEME_ALL; 189 int schemes = URLPattern::SCHEME_ALL;
240 extent->AddPattern(URLPattern(schemes, pattern)); 190 extent->AddPattern(URLPattern(schemes, pattern));
241 } 191 }
242 192
243 base::FilePath GetTemporaryFile() { 193 base::FilePath GetTemporaryFile() {
244 base::FilePath temp_file; 194 base::FilePath temp_file;
245 CHECK(base::CreateTemporaryFile(&temp_file)); 195 CHECK(base::CreateTemporaryFile(&temp_file));
246 return temp_file; 196 return temp_file;
247 } 197 }
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 int ids_found_; 423 int ids_found_;
474 base::FilePath fake_base_path_; 424 base::FilePath fake_base_path_;
475 int expected_creation_flags_; 425 int expected_creation_flags_;
476 scoped_ptr<extensions::ExternalProviderImpl> provider_; 426 scoped_ptr<extensions::ExternalProviderImpl> provider_;
477 scoped_ptr<base::DictionaryValue> prefs_; 427 scoped_ptr<base::DictionaryValue> prefs_;
478 scoped_ptr<TestingProfile> profile_; 428 scoped_ptr<TestingProfile> profile_;
479 429
480 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor); 430 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
481 }; 431 };
482 432
483 class ExtensionServiceTest : public extensions::ExtensionServiceTestBase, 433 class ExtensionServiceTest
484 public content::NotificationObserver { 434 : public extensions::ExtensionServiceTestWithInstall {
485 public: 435 public:
486 ExtensionServiceTest() 436 ExtensionServiceTest()
487 : unloaded_reason_(UnloadedExtensionInfo::REASON_UNDEFINED), 437 : override_external_install_prompt_(
488 installed_(NULL),
489 was_update_(false),
490 override_external_install_prompt_(
491 FeatureSwitch::prompt_for_external_extensions(), 438 FeatureSwitch::prompt_for_external_extensions(),
492 false), 439 false) {}
493 expected_extensions_count_(0) {
494 registrar_.Add(this,
495 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
496 content::NotificationService::AllSources());
497 registrar_.Add(this,
498 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
499 content::NotificationService::AllSources());
500 registrar_.Add(
501 this,
502 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
503 content::NotificationService::AllSources());
504 }
505
506 void Observe(int type,
507 const content::NotificationSource& source,
508 const content::NotificationDetails& details) override {
509 switch (type) {
510 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
511 const Extension* extension =
512 content::Details<const Extension>(details).ptr();
513 loaded_.push_back(make_scoped_refptr(extension));
514 // The tests rely on the errors being in a certain order, which can vary
515 // depending on how filesystem iteration works.
516 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
517 break;
518 }
519
520 case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
521 UnloadedExtensionInfo* unloaded_info =
522 content::Details<UnloadedExtensionInfo>(details).ptr();
523 const Extension* e = unloaded_info->extension;
524 unloaded_id_ = e->id();
525 unloaded_reason_ = unloaded_info->reason;
526 extensions::ExtensionList::iterator i =
527 std::find(loaded_.begin(), loaded_.end(), e);
528 // TODO(erikkay) fix so this can be an assert. Right now the tests
529 // are manually calling clear() on loaded_, so this isn't doable.
530 if (i == loaded_.end())
531 return;
532 loaded_.erase(i);
533 break;
534 }
535 case extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED: {
536 const extensions::InstalledExtensionInfo* installed_info =
537 content::Details<const extensions::InstalledExtensionInfo>(details)
538 .ptr();
539 installed_ = installed_info->extension;
540 was_update_ = installed_info->is_update;
541 old_name_ = installed_info->old_name;
542 break;
543 }
544
545 default:
546 DCHECK(false);
547 }
548 }
549 440
550 void AddMockExternalProvider( 441 void AddMockExternalProvider(
551 extensions::ExternalProviderInterface* provider) { 442 extensions::ExternalProviderInterface* provider) {
552 service()->AddProviderForTesting(provider); 443 service()->AddProviderForTesting(provider);
553 } 444 }
554 445
555 void MockSyncStartFlare(bool* was_called,
556 syncer::ModelType* model_type_passed_in,
557 syncer::ModelType model_type) {
558 *was_called = true;
559 *model_type_passed_in = model_type;
560 }
561
562 protected: 446 protected:
563 // Paths to some of the fake extensions. 447 // Paths to some of the fake extensions.
564 base::FilePath good0_path() {
565 return data_dir()
566 .AppendASCII("good")
567 .AppendASCII("Extensions")
568 .AppendASCII(good0)
569 .AppendASCII("1.0.0.0");
570 }
571
572 base::FilePath good1_path() { 448 base::FilePath good1_path() {
573 return data_dir() 449 return data_dir()
574 .AppendASCII("good") 450 .AppendASCII("good")
575 .AppendASCII("Extensions") 451 .AppendASCII("Extensions")
576 .AppendASCII(good1) 452 .AppendASCII(good1)
577 .AppendASCII("2"); 453 .AppendASCII("2");
578 } 454 }
579 455
580 base::FilePath good2_path() { 456 base::FilePath good2_path() {
581 return data_dir() 457 return data_dir()
582 .AppendASCII("good") 458 .AppendASCII("good")
583 .AppendASCII("Extensions") 459 .AppendASCII("Extensions")
584 .AppendASCII(good2) 460 .AppendASCII(good2)
585 .AppendASCII("1.0"); 461 .AppendASCII("1.0");
586 } 462 }
587 463
588 void TestExternalProvider(MockExtensionProvider* provider, 464 void TestExternalProvider(MockExtensionProvider* provider,
589 Manifest::Location location); 465 Manifest::Location location);
590 466
591 void PackCRX(const base::FilePath& dir_path,
592 const base::FilePath& pem_path,
593 const base::FilePath& crx_path) {
594 // Use the existing pem key, if provided.
595 base::FilePath pem_output_path;
596 if (pem_path.value().empty()) {
597 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
598 } else {
599 ASSERT_TRUE(base::PathExists(pem_path));
600 }
601
602 ASSERT_TRUE(base::DeleteFile(crx_path, false));
603
604 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
605 ASSERT_TRUE(creator->Run(dir_path,
606 crx_path,
607 pem_path,
608 pem_output_path,
609 ExtensionCreator::kOverwriteCRX));
610
611 ASSERT_TRUE(base::PathExists(crx_path));
612 }
613
614 enum InstallState {
615 INSTALL_FAILED,
616 INSTALL_UPDATED,
617 INSTALL_NEW,
618 INSTALL_WITHOUT_LOAD,
619 };
620
621 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
622 const base::FilePath& pem_path,
623 InstallState install_state,
624 int creation_flags) {
625 base::FilePath crx_path;
626 base::ScopedTempDir temp_dir;
627 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
628 crx_path = temp_dir.path().AppendASCII("temp.crx");
629
630 PackCRX(dir_path, pem_path, crx_path);
631 return InstallCRX(crx_path, install_state, creation_flags);
632 }
633
634 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
635 const base::FilePath& pem_path,
636 InstallState install_state) {
637 return PackAndInstallCRX(dir_path, pem_path, install_state,
638 Extension::NO_FLAGS);
639 }
640
641 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
642 InstallState install_state) {
643 return PackAndInstallCRX(dir_path, base::FilePath(), install_state,
644 Extension::NO_FLAGS);
645 }
646
647 // Attempts to install an extension. Use INSTALL_FAILED if the installation
648 // is expected to fail.
649 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
650 // non-empty, expects that the existing extension's title was
651 // |expected_old_name|.
652 const Extension* InstallCRX(const base::FilePath& path,
653 InstallState install_state,
654 int creation_flags,
655 const std::string& expected_old_name) {
656 InstallCRXInternal(path, creation_flags);
657 return VerifyCrxInstall(path, install_state, expected_old_name);
658 }
659
660 // Attempts to install an extension. Use INSTALL_FAILED if the installation
661 // is expected to fail.
662 const Extension* InstallCRX(const base::FilePath& path,
663 InstallState install_state,
664 int creation_flags) {
665 return InstallCRX(path, install_state, creation_flags, std::string());
666 }
667
668 // Attempts to install an extension. Use INSTALL_FAILED if the installation
669 // is expected to fail.
670 const Extension* InstallCRX(const base::FilePath& path,
671 InstallState install_state) {
672 return InstallCRX(path, install_state, Extension::NO_FLAGS);
673 }
674
675 const Extension* InstallCRXFromWebStore(const base::FilePath& path,
676 InstallState install_state) {
677 InstallCRXInternal(path, Extension::FROM_WEBSTORE);
678 return VerifyCrxInstall(path, install_state);
679 }
680
681 const Extension* InstallCRXWithLocation(const base::FilePath& crx_path,
682 Manifest::Location install_location,
683 InstallState install_state) {
684 EXPECT_TRUE(base::PathExists(crx_path))
685 << "Path does not exist: "<< crx_path.value().c_str();
686 // no client (silent install)
687 scoped_refptr<CrxInstaller> installer(
688 CrxInstaller::CreateSilent(service()));
689 installer->set_install_source(install_location);
690
691 content::WindowedNotificationObserver observer(
692 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
693 content::NotificationService::AllSources());
694 installer->InstallCrx(crx_path);
695 observer.Wait();
696
697 return VerifyCrxInstall(crx_path, install_state);
698 }
699
700 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
701 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
702 // Returns an Extension pointer if the install succeeded, NULL otherwise.
703 const Extension* VerifyCrxInstall(const base::FilePath& path,
704 InstallState install_state) {
705 return VerifyCrxInstall(path, install_state, std::string());
706 }
707
708 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
709 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
710 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
711 // non-empty, expects that the existing extension's title was
712 // |expected_old_name|.
713 // Returns an Extension pointer if the install succeeded, NULL otherwise.
714 const Extension* VerifyCrxInstall(const base::FilePath& path,
715 InstallState install_state,
716 const std::string& expected_old_name) {
717 std::vector<base::string16> errors = GetErrors();
718 const Extension* extension = NULL;
719 if (install_state != INSTALL_FAILED) {
720 if (install_state == INSTALL_NEW)
721 ++expected_extensions_count_;
722
723 EXPECT_TRUE(installed_) << path.value();
724 // If and only if INSTALL_UPDATED, it should have the is_update flag.
725 EXPECT_EQ(install_state == INSTALL_UPDATED, was_update_)
726 << path.value();
727 // If INSTALL_UPDATED, old_name_ should match the given string.
728 if (install_state == INSTALL_UPDATED && !expected_old_name.empty())
729 EXPECT_EQ(expected_old_name, old_name_);
730 EXPECT_EQ(0u, errors.size()) << path.value();
731
732 if (install_state == INSTALL_WITHOUT_LOAD) {
733 EXPECT_EQ(0u, loaded_.size()) << path.value();
734 } else {
735 EXPECT_EQ(1u, loaded_.size()) << path.value();
736 size_t actual_extension_count =
737 registry()->enabled_extensions().size() +
738 registry()->disabled_extensions().size();
739 EXPECT_EQ(expected_extensions_count_, actual_extension_count) <<
740 path.value();
741 extension = loaded_[0].get();
742 EXPECT_TRUE(service()->GetExtensionById(extension->id(), false))
743 << path.value();
744 }
745
746 for (std::vector<base::string16>::iterator err = errors.begin();
747 err != errors.end(); ++err) {
748 LOG(ERROR) << *err;
749 }
750 } else {
751 EXPECT_FALSE(installed_) << path.value();
752 EXPECT_EQ(0u, loaded_.size()) << path.value();
753 EXPECT_EQ(1u, errors.size()) << path.value();
754 }
755
756 installed_ = NULL;
757 was_update_ = false;
758 old_name_ = "";
759 loaded_.clear();
760 ExtensionErrorReporter::GetInstance()->ClearErrors();
761 return extension;
762 }
763
764 enum UpdateState {
765 FAILED_SILENTLY,
766 FAILED,
767 UPDATED,
768 INSTALLED,
769 DISABLED,
770 ENABLED
771 };
772
773 void BlackListWebGL() { 467 void BlackListWebGL() {
774 static const std::string json_blacklist = 468 static const std::string json_blacklist =
775 "{\n" 469 "{\n"
776 " \"name\": \"gpu blacklist\",\n" 470 " \"name\": \"gpu blacklist\",\n"
777 " \"version\": \"1.0\",\n" 471 " \"version\": \"1.0\",\n"
778 " \"entries\": [\n" 472 " \"entries\": [\n"
779 " {\n" 473 " {\n"
780 " \"id\": 1,\n" 474 " \"id\": 1,\n"
781 " \"features\": [\"webgl\"]\n" 475 " \"features\": [\"webgl\"]\n"
782 " }\n" 476 " }\n"
783 " ]\n" 477 " ]\n"
784 "}"; 478 "}";
785 gpu::GPUInfo gpu_info; 479 gpu::GPUInfo gpu_info;
786 content::GpuDataManager::GetInstance()->InitializeForTesting( 480 content::GpuDataManager::GetInstance()->InitializeForTesting(
787 json_blacklist, gpu_info); 481 json_blacklist, gpu_info);
788 } 482 }
789 483
790 // Grants all optional permissions stated in manifest to active permission 484 // Grants all optional permissions stated in manifest to active permission
791 // set for extension |id|. 485 // set for extension |id|.
792 void GrantAllOptionalPermissions(const std::string& id) { 486 void GrantAllOptionalPermissions(const std::string& id) {
793 const Extension* extension = service()->GetInstalledExtension(id); 487 const Extension* extension = service()->GetInstalledExtension(id);
794 const PermissionSet& all_optional_permissions = 488 const PermissionSet& all_optional_permissions =
795 extensions::PermissionsParser::GetOptionalPermissions(extension); 489 extensions::PermissionsParser::GetOptionalPermissions(extension);
796 extensions::PermissionsUpdater perms_updater(profile()); 490 extensions::PermissionsUpdater perms_updater(profile());
797 perms_updater.AddPermissions(extension, all_optional_permissions); 491 perms_updater.AddPermissions(extension, all_optional_permissions);
798 } 492 }
799 493
800 // Helper method to set up a WindowedNotificationObserver to wait for a
801 // specific CrxInstaller to finish if we don't know the value of the
802 // |installer| yet.
803 static bool IsCrxInstallerDone(extensions::CrxInstaller** installer,
804 const content::NotificationSource& source,
805 const content::NotificationDetails& details) {
806 return content::Source<extensions::CrxInstaller>(source).ptr() ==
807 *installer;
808 }
809
810 void PackCRXAndUpdateExtension(const std::string& id,
811 const base::FilePath& dir_path,
812 const base::FilePath& pem_path,
813 UpdateState expected_state) {
814 base::ScopedTempDir temp_dir;
815 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
816 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
817
818 PackCRX(dir_path, pem_path, crx_path);
819 UpdateExtension(id, crx_path, expected_state);
820 }
821
822 void UpdateExtension(const std::string& id,
823 const base::FilePath& in_path,
824 UpdateState expected_state) {
825 ASSERT_TRUE(base::PathExists(in_path));
826
827 // We need to copy this to a temporary location because Update() will delete
828 // it.
829 base::FilePath path = temp_dir().path();
830 path = path.Append(in_path.BaseName());
831 ASSERT_TRUE(base::CopyFile(in_path, path));
832
833 int previous_enabled_extension_count =
834 registry()->enabled_extensions().size();
835 int previous_installed_extension_count =
836 previous_enabled_extension_count +
837 registry()->disabled_extensions().size();
838
839 extensions::CrxInstaller* installer = NULL;
840 content::WindowedNotificationObserver observer(
841 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
842 base::Bind(&IsCrxInstallerDone, &installer));
843 service()->UpdateExtension(extensions::CRXFileInfo(id, path), true,
844 &installer);
845
846 if (installer)
847 observer.Wait();
848 else
849 base::RunLoop().RunUntilIdle();
850
851 std::vector<base::string16> errors = GetErrors();
852 int error_count = errors.size();
853 int enabled_extension_count = registry()->enabled_extensions().size();
854 int installed_extension_count =
855 enabled_extension_count + registry()->disabled_extensions().size();
856
857 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
858 EXPECT_EQ(expected_error_count, error_count) << path.value();
859
860 if (expected_state <= FAILED) {
861 EXPECT_EQ(previous_enabled_extension_count,
862 enabled_extension_count);
863 EXPECT_EQ(previous_installed_extension_count,
864 installed_extension_count);
865 } else {
866 int expected_installed_extension_count =
867 (expected_state >= INSTALLED) ? 1 : 0;
868 int expected_enabled_extension_count =
869 (expected_state >= ENABLED) ? 1 : 0;
870 EXPECT_EQ(expected_installed_extension_count,
871 installed_extension_count);
872 EXPECT_EQ(expected_enabled_extension_count,
873 enabled_extension_count);
874 }
875
876 // Update() should the temporary input file.
877 EXPECT_FALSE(base::PathExists(path));
878 }
879
880 void TerminateExtension(const std::string& id) {
881 const Extension* extension = service()->GetInstalledExtension(id);
882 if (!extension) {
883 ADD_FAILURE();
884 return;
885 }
886 service()->TrackTerminatedExtensionForTest(extension);
887 }
888
889 testing::AssertionResult IsBlocked(const std::string& id) { 494 testing::AssertionResult IsBlocked(const std::string& id) {
890 scoped_ptr<extensions::ExtensionSet> all_unblocked_extensions = 495 scoped_ptr<extensions::ExtensionSet> all_unblocked_extensions =
891 registry()->GenerateInstalledExtensionsSet( 496 registry()->GenerateInstalledExtensionsSet(
892 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::BLOCKED); 497 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::BLOCKED);
893 if (all_unblocked_extensions.get()->Contains(id)) 498 if (all_unblocked_extensions.get()->Contains(id))
894 return testing::AssertionFailure() << id << " is still unblocked!"; 499 return testing::AssertionFailure() << id << " is still unblocked!";
895 if (!registry()->blocked_extensions().Contains(id)) 500 if (!registry()->blocked_extensions().Contains(id))
896 return testing::AssertionFailure() << id << " is not blocked!"; 501 return testing::AssertionFailure() << id << " is not blocked!";
897 return testing::AssertionSuccess(); 502 return testing::AssertionSuccess();
898 } 503 }
(...skipping 13 matching lines...) Expand all
912 ASSERT_TRUE(IsBlocked(extension_id)); 517 ASSERT_TRUE(IsBlocked(extension_id));
913 else 518 else
914 ASSERT_FALSE(IsBlocked(extension_id)); 519 ASSERT_FALSE(IsBlocked(extension_id));
915 520
916 service()->UnblockAllExtensions(); 521 service()->UnblockAllExtensions();
917 base::RunLoop().RunUntilIdle(); 522 base::RunLoop().RunUntilIdle();
918 523
919 ASSERT_FALSE(IsBlocked(extension_id)); 524 ASSERT_FALSE(IsBlocked(extension_id));
920 } 525 }
921 526
922 size_t GetPrefKeyCount() {
923 const base::DictionaryValue* dict =
924 profile()->GetPrefs()->GetDictionary("extensions.settings");
925 if (!dict) {
926 ADD_FAILURE();
927 return 0;
928 }
929 return dict->size();
930 }
931
932 void UninstallExtension(const std::string& id, bool use_helper) {
933 UninstallExtension(id, use_helper, Extension::ENABLED);
934 }
935
936 void UninstallExtension(const std::string& id, bool use_helper,
937 Extension::State expected_state) {
938 // Verify that the extension is installed.
939 base::FilePath extension_path = extensions_install_dir().AppendASCII(id);
940 EXPECT_TRUE(base::PathExists(extension_path));
941 size_t pref_key_count = GetPrefKeyCount();
942 EXPECT_GT(pref_key_count, 0u);
943 ValidateIntegerPref(id, "state", expected_state);
944
945 // Uninstall it.
946 if (use_helper) {
947 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(
948 service(), id, extensions::UNINSTALL_REASON_FOR_TESTING));
949 } else {
950 EXPECT_TRUE(service()->UninstallExtension(
951 id,
952 extensions::UNINSTALL_REASON_FOR_TESTING,
953 base::Bind(&base::DoNothing),
954 NULL));
955 }
956 --expected_extensions_count_;
957
958 // We should get an unload notification.
959 EXPECT_FALSE(unloaded_id_.empty());
960 EXPECT_EQ(id, unloaded_id_);
961
962 // Verify uninstalled state.
963 size_t new_pref_key_count = GetPrefKeyCount();
964 if (new_pref_key_count == pref_key_count) {
965 ValidateIntegerPref(id, "state",
966 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
967 } else {
968 EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
969 }
970
971 // The extension should not be in the service anymore.
972 EXPECT_FALSE(service()->GetInstalledExtension(id));
973 base::RunLoop().RunUntilIdle();
974
975 // The directory should be gone.
976 EXPECT_FALSE(base::PathExists(extension_path));
977 }
978
979 void ValidatePrefKeyCount(size_t count) {
980 EXPECT_EQ(count, GetPrefKeyCount());
981 }
982
983 testing::AssertionResult ValidateBooleanPref(
984 const std::string& extension_id,
985 const std::string& pref_path,
986 bool expected_val) {
987 std::string msg = "while checking: ";
988 msg += extension_id;
989 msg += " ";
990 msg += pref_path;
991 msg += " == ";
992 msg += expected_val ? "true" : "false";
993
994 PrefService* prefs = profile()->GetPrefs();
995 const base::DictionaryValue* dict =
996 prefs->GetDictionary("extensions.settings");
997 if (!dict) {
998 return testing::AssertionFailure()
999 << "extension.settings does not exist " << msg;
1000 }
1001
1002 const base::DictionaryValue* pref = NULL;
1003 if (!dict->GetDictionary(extension_id, &pref)) {
1004 return testing::AssertionFailure()
1005 << "extension pref does not exist " << msg;
1006 }
1007
1008 bool val;
1009 if (!pref->GetBoolean(pref_path, &val)) {
1010 return testing::AssertionFailure()
1011 << pref_path << " pref not found " << msg;
1012 }
1013
1014 return expected_val == val
1015 ? testing::AssertionSuccess()
1016 : testing::AssertionFailure() << "base::Value is incorrect " << msg;
1017 }
1018
1019 bool IsPrefExist(const std::string& extension_id, 527 bool IsPrefExist(const std::string& extension_id,
1020 const std::string& pref_path) { 528 const std::string& pref_path) {
1021 const base::DictionaryValue* dict = 529 const base::DictionaryValue* dict =
1022 profile()->GetPrefs()->GetDictionary("extensions.settings"); 530 profile()->GetPrefs()->GetDictionary("extensions.settings");
1023 if (dict == NULL) return false; 531 if (dict == NULL) return false;
1024 const base::DictionaryValue* pref = NULL; 532 const base::DictionaryValue* pref = NULL;
1025 if (!dict->GetDictionary(extension_id, &pref)) { 533 if (!dict->GetDictionary(extension_id, &pref)) {
1026 return false; 534 return false;
1027 } 535 }
1028 if (pref == NULL) { 536 if (pref == NULL) {
1029 return false; 537 return false;
1030 } 538 }
1031 bool val; 539 bool val;
1032 if (!pref->GetBoolean(pref_path, &val)) { 540 if (!pref->GetBoolean(pref_path, &val)) {
1033 return false; 541 return false;
1034 } 542 }
1035 return true; 543 return true;
1036 } 544 }
1037 545
1038 void ValidateIntegerPref(const std::string& extension_id,
1039 const std::string& pref_path,
1040 int expected_val) {
1041 std::string msg = " while checking: ";
1042 msg += extension_id;
1043 msg += " ";
1044 msg += pref_path;
1045 msg += " == ";
1046 msg += base::IntToString(expected_val);
1047
1048 PrefService* prefs = profile()->GetPrefs();
1049 const base::DictionaryValue* dict =
1050 prefs->GetDictionary("extensions.settings");
1051 ASSERT_TRUE(dict != NULL) << msg;
1052 const base::DictionaryValue* pref = NULL;
1053 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1054 EXPECT_TRUE(pref != NULL) << msg;
1055 int val;
1056 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
1057 EXPECT_EQ(expected_val, val) << msg;
1058 }
1059
1060 void ValidateStringPref(const std::string& extension_id,
1061 const std::string& pref_path,
1062 const std::string& expected_val) {
1063 std::string msg = " while checking: ";
1064 msg += extension_id;
1065 msg += ".manifest.";
1066 msg += pref_path;
1067 msg += " == ";
1068 msg += expected_val;
1069
1070 const base::DictionaryValue* dict =
1071 profile()->GetPrefs()->GetDictionary("extensions.settings");
1072 ASSERT_TRUE(dict != NULL) << msg;
1073 const base::DictionaryValue* pref = NULL;
1074 std::string manifest_path = extension_id + ".manifest";
1075 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
1076 EXPECT_TRUE(pref != NULL) << msg;
1077 std::string val;
1078 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
1079 EXPECT_EQ(expected_val, val) << msg;
1080 }
1081
1082 void SetPref(const std::string& extension_id, 546 void SetPref(const std::string& extension_id,
1083 const std::string& pref_path, 547 const std::string& pref_path,
1084 base::Value* value, 548 base::Value* value,
1085 const std::string& msg) { 549 const std::string& msg) {
1086 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings"); 550 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1087 base::DictionaryValue* dict = update.Get(); 551 base::DictionaryValue* dict = update.Get();
1088 ASSERT_TRUE(dict != NULL) << msg; 552 ASSERT_TRUE(dict != NULL) << msg;
1089 base::DictionaryValue* pref = NULL; 553 base::DictionaryValue* pref = NULL;
1090 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; 554 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1091 EXPECT_TRUE(pref != NULL) << msg; 555 EXPECT_TRUE(pref != NULL) << msg;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 ExtensionServiceTestBase::ExtensionServiceInitParams params = 618 ExtensionServiceTestBase::ExtensionServiceInitParams params =
1155 CreateDefaultInitParams(); 619 CreateDefaultInitParams();
1156 params.pref_file = base::FilePath(); 620 params.pref_file = base::FilePath();
1157 InitializeExtensionService(params); 621 InitializeExtensionService(params);
1158 } 622 }
1159 623
1160 extensions::ManagementPolicy* GetManagementPolicy() { 624 extensions::ManagementPolicy* GetManagementPolicy() {
1161 return ExtensionSystem::Get(browser_context())->management_policy(); 625 return ExtensionSystem::Get(browser_context())->management_policy();
1162 } 626 }
1163 627
1164 ExtensionSyncService* extension_sync_service() {
1165 return ExtensionSyncService::Get(profile());
1166 }
1167
1168 protected: 628 protected:
1169 typedef extensions::ExtensionManagementPrefUpdater< 629 typedef extensions::ExtensionManagementPrefUpdater<
1170 syncable_prefs::TestingPrefServiceSyncable> ManagementPrefUpdater; 630 syncable_prefs::TestingPrefServiceSyncable> ManagementPrefUpdater;
1171 extensions::ExtensionList loaded_;
1172 std::string unloaded_id_;
1173 UnloadedExtensionInfo::Reason unloaded_reason_;
1174 const Extension* installed_;
1175 bool was_update_;
1176 std::string old_name_;
1177 FeatureSwitch::ScopedOverride override_external_install_prompt_; 631 FeatureSwitch::ScopedOverride override_external_install_prompt_;
1178
1179 private:
1180 // Create a CrxInstaller and install the CRX file.
1181 // Instead of calling this method yourself, use InstallCRX(), which does extra
1182 // error checking.
1183 void InstallCRXInternal(const base::FilePath& crx_path) {
1184 InstallCRXInternal(crx_path, Extension::NO_FLAGS);
1185 }
1186
1187 void InstallCRXInternal(const base::FilePath& crx_path, int creation_flags) {
1188 ASSERT_TRUE(base::PathExists(crx_path))
1189 << "Path does not exist: "<< crx_path.value().c_str();
1190 scoped_refptr<CrxInstaller> installer(
1191 CrxInstaller::CreateSilent(service()));
1192 installer->set_creation_flags(creation_flags);
1193 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT))
1194 installer->set_allow_silent_install(true);
1195
1196 content::WindowedNotificationObserver observer(
1197 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1198 content::Source<extensions::CrxInstaller>(installer.get()));
1199
1200 installer->InstallCrx(crx_path);
1201
1202 observer.Wait();
1203 }
1204
1205 size_t expected_extensions_count_;
1206 content::NotificationRegistrar registrar_;
1207 }; 632 };
1208 633
1209 // Receives notifications from a PackExtensionJob, indicating either that 634 // Receives notifications from a PackExtensionJob, indicating either that
1210 // packing succeeded or that there was some error. 635 // packing succeeded or that there was some error.
1211 class PackExtensionTestClient : public extensions::PackExtensionJob::Client { 636 class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
1212 public: 637 public:
1213 PackExtensionTestClient(const base::FilePath& expected_crx_path, 638 PackExtensionTestClient(const base::FilePath& expected_crx_path,
1214 const base::FilePath& expected_private_key_path); 639 const base::FilePath& expected_private_key_path);
1215 void OnPackSuccess(const base::FilePath& crx_path, 640 void OnPackSuccess(const base::FilePath& crx_path,
1216 const base::FilePath& private_key_path) override; 641 const base::FilePath& private_key_path) override;
(...skipping 4605 matching lines...) Expand 10 before | Expand all | Expand 10 after
5822 ValidatePrefKeyCount(1); 5247 ValidatePrefKeyCount(1);
5823 5248
5824 // Reload all extensions, and make sure it comes back. 5249 // Reload all extensions, and make sure it comes back.
5825 std::string extension_id = (*registry()->enabled_extensions().begin())->id(); 5250 std::string extension_id = (*registry()->enabled_extensions().begin())->id();
5826 loaded_.clear(); 5251 loaded_.clear();
5827 service()->ReloadExtensionsForTest(); 5252 service()->ReloadExtensionsForTest();
5828 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 5253 ASSERT_EQ(1u, registry()->enabled_extensions().size());
5829 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id()); 5254 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id());
5830 } 5255 }
5831 5256
5832 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
5833 InitializeEmptyExtensionService();
5834
5835 bool flare_was_called = false;
5836 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5837 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5838 extension_sync_service()->SetSyncStartFlareForTesting(
5839 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5840 factory.GetWeakPtr(),
5841 &flare_was_called, // Safe due to WeakPtrFactory scope.
5842 &triggered_type)); // Safe due to WeakPtrFactory scope.
5843
5844 // Install a component extension.
5845 std::string manifest;
5846 ASSERT_TRUE(base::ReadFileToString(
5847 good0_path().Append(extensions::kManifestFilename), &manifest));
5848 service()->component_loader()->Add(manifest, good0_path());
5849 ASSERT_FALSE(service()->is_ready());
5850 service()->Init();
5851 ASSERT_TRUE(service()->is_ready());
5852
5853 // Extensions added before service is_ready() don't trigger sync startup.
5854 EXPECT_FALSE(flare_was_called);
5855 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5856 }
5857
5858 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
5859 InitializeGoodInstalledExtensionService();
5860
5861 bool flare_was_called = false;
5862 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5863 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5864 extension_sync_service()->SetSyncStartFlareForTesting(
5865 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5866 factory.GetWeakPtr(),
5867 &flare_was_called, // Safe due to WeakPtrFactory scope.
5868 &triggered_type)); // Safe due to WeakPtrFactory scope.
5869
5870 ASSERT_FALSE(service()->is_ready());
5871 service()->Init();
5872 ASSERT_EQ(3u, loaded_.size());
5873 ASSERT_TRUE(service()->is_ready());
5874
5875 // Extensions added before service is_ready() don't trigger sync startup.
5876 EXPECT_FALSE(flare_was_called);
5877 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5878 }
5879
5880 TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
5881 InitializeEmptyExtensionService();
5882 service()->Init();
5883 ASSERT_TRUE(service()->is_ready());
5884
5885 bool flare_was_called = false;
5886 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5887 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5888 extension_sync_service()->SetSyncStartFlareForTesting(
5889 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5890 factory.GetWeakPtr(),
5891 &flare_was_called, // Safe due to WeakPtrFactory scope.
5892 &triggered_type)); // Safe due to WeakPtrFactory scope.
5893
5894 base::FilePath path = data_dir().AppendASCII("good.crx");
5895 InstallCRX(path, INSTALL_NEW);
5896
5897 EXPECT_TRUE(flare_was_called);
5898 EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
5899
5900 // Reset.
5901 flare_was_called = false;
5902 triggered_type = syncer::UNSPECIFIED;
5903
5904 // Once sync starts, flare should no longer be invoked.
5905 extension_sync_service()->MergeDataAndStartSyncing(
5906 syncer::EXTENSIONS,
5907 syncer::SyncDataList(),
5908 scoped_ptr<syncer::SyncChangeProcessor>(
5909 new syncer::FakeSyncChangeProcessor),
5910 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5911 path = data_dir().AppendASCII("page_action.crx");
5912 InstallCRX(path, INSTALL_NEW);
5913 EXPECT_FALSE(flare_was_called);
5914 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5915 }
5916
5917 TEST_F(ExtensionServiceTest, DisableExtensionFromSync) {
5918 // Start the extensions service with one external extension already installed.
5919 base::FilePath source_install_dir =
5920 data_dir().AppendASCII("good").AppendASCII("Extensions");
5921 base::FilePath pref_path =
5922 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5923
5924 InitializeInstalledExtensionService(pref_path, source_install_dir);
5925
5926 // The user has enabled sync.
5927 ProfileSyncService* sync_service =
5928 ProfileSyncServiceFactory::GetForProfile(profile());
5929 sync_service->SetSyncSetupCompleted();
5930
5931 service()->Init();
5932 ASSERT_TRUE(service()->is_ready());
5933
5934 ASSERT_EQ(3u, loaded_.size());
5935
5936 // We start enabled.
5937 const Extension* extension = service()->GetExtensionById(good0, true);
5938 ASSERT_TRUE(extension);
5939 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5940
5941 // Sync starts up.
5942 extension_sync_service()->MergeDataAndStartSyncing(
5943 syncer::EXTENSIONS,
5944 syncer::SyncDataList(),
5945 make_scoped_ptr(new syncer::FakeSyncChangeProcessor),
5946 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5947
5948 // Then sync data arrives telling us to disable |good0|.
5949 ExtensionSyncData disable_good_crx(*extension, false,
5950 Extension::DISABLE_USER_ACTION, false,
5951 false, ExtensionSyncData::BOOLEAN_UNSET);
5952 syncer::SyncChange sync_change(FROM_HERE,
5953 syncer::SyncChange::ACTION_UPDATE,
5954 disable_good_crx.GetSyncData());
5955 syncer::SyncChangeList list(1, sync_change);
5956 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5957
5958 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5959 }
5960
5961 TEST_F(ExtensionServiceTest, IgnoreSyncChangesWhenLocalStateIsMoreRecent) {
5962 // Start the extension service with three extensions already installed.
5963 base::FilePath source_install_dir =
5964 data_dir().AppendASCII("good").AppendASCII("Extensions");
5965 base::FilePath pref_path =
5966 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5967
5968 InitializeInstalledExtensionService(pref_path, source_install_dir);
5969
5970 // The user has enabled sync.
5971 ProfileSyncService* sync_service =
5972 ProfileSyncServiceFactory::GetForProfile(profile());
5973 sync_service->SetSyncSetupCompleted();
5974 // Make sure ExtensionSyncService is created, so it'll be notified of changes.
5975 extension_sync_service();
5976
5977 service()->Init();
5978 ASSERT_TRUE(service()->is_ready());
5979 ASSERT_EQ(3u, loaded_.size());
5980
5981 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5982 ASSERT_TRUE(service()->IsExtensionEnabled(good2));
5983
5984 // Disable and re-enable good0 before first sync data arrives.
5985 service()->DisableExtension(good0, Extension::DISABLE_USER_ACTION);
5986 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5987 service()->EnableExtension(good0);
5988 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5989 // Disable good2 before first sync data arrives (good1 is considered
5990 // non-syncable because it has plugin permission).
5991 service()->DisableExtension(good2, Extension::DISABLE_USER_ACTION);
5992 ASSERT_FALSE(service()->IsExtensionEnabled(good2));
5993
5994 const Extension* extension0 = service()->GetExtensionById(good0, true);
5995 const Extension* extension2 = service()->GetExtensionById(good2, true);
5996 ASSERT_TRUE(extensions::sync_helper::IsSyncable(extension0));
5997 ASSERT_TRUE(extensions::sync_helper::IsSyncable(extension2));
5998
5999 // Now sync data comes in that says to disable good0 and enable good2.
6000 ExtensionSyncData disable_good0(*extension0, false,
6001 Extension::DISABLE_USER_ACTION, false, false,
6002 ExtensionSyncData::BOOLEAN_UNSET);
6003 ExtensionSyncData enable_good2(*extension2, true, Extension::DISABLE_NONE,
6004 false, false,
6005 ExtensionSyncData::BOOLEAN_UNSET);
6006 syncer::SyncDataList sync_data;
6007 sync_data.push_back(disable_good0.GetSyncData());
6008 sync_data.push_back(enable_good2.GetSyncData());
6009 extension_sync_service()->MergeDataAndStartSyncing(
6010 syncer::EXTENSIONS,
6011 sync_data,
6012 make_scoped_ptr(new syncer::FakeSyncChangeProcessor),
6013 make_scoped_ptr(new syncer::SyncErrorFactoryMock));
6014
6015 // Both sync changes should be ignored, since the local state was changed
6016 // before sync started, and so the local state is considered more recent.
6017 EXPECT_TRUE(service()->IsExtensionEnabled(good0));
6018 EXPECT_FALSE(service()->IsExtensionEnabled(good2));
6019 }
6020
6021 TEST_F(ExtensionServiceTest, GetSyncData) {
6022 InitializeEmptyExtensionService();
6023 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6024 const Extension* extension = service()->GetInstalledExtension(good_crx);
6025 ASSERT_TRUE(extension);
6026
6027 extension_sync_service()->MergeDataAndStartSyncing(
6028 syncer::EXTENSIONS,
6029 syncer::SyncDataList(),
6030 scoped_ptr<syncer::SyncChangeProcessor>(
6031 new syncer::FakeSyncChangeProcessor),
6032 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6033
6034 syncer::SyncDataList list =
6035 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6036 ASSERT_EQ(list.size(), 1U);
6037 scoped_ptr<ExtensionSyncData> data =
6038 ExtensionSyncData::CreateFromSyncData(list[0]);
6039 ASSERT_TRUE(data.get());
6040 EXPECT_EQ(extension->id(), data->id());
6041 EXPECT_FALSE(data->uninstalled());
6042 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
6043 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
6044 data->incognito_enabled());
6045 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6046 EXPECT_TRUE(data->version().Equals(*extension->version()));
6047 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
6048 data->update_url());
6049 EXPECT_EQ(extension->name(), data->name());
6050 }
6051
6052 TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
6053 InitializeEmptyExtensionService();
6054 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6055 TerminateExtension(good_crx);
6056 const Extension* extension = service()->GetInstalledExtension(good_crx);
6057 ASSERT_TRUE(extension);
6058
6059 syncer::FakeSyncChangeProcessor processor;
6060 extension_sync_service()->MergeDataAndStartSyncing(
6061 syncer::EXTENSIONS,
6062 syncer::SyncDataList(),
6063 scoped_ptr<syncer::SyncChangeProcessor>(
6064 new syncer::FakeSyncChangeProcessor),
6065 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6066
6067 syncer::SyncDataList list =
6068 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6069 ASSERT_EQ(list.size(), 1U);
6070 scoped_ptr<ExtensionSyncData> data =
6071 ExtensionSyncData::CreateFromSyncData(list[0]);
6072 ASSERT_TRUE(data.get());
6073 EXPECT_EQ(extension->id(), data->id());
6074 EXPECT_FALSE(data->uninstalled());
6075 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
6076 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
6077 data->incognito_enabled());
6078 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6079 EXPECT_TRUE(data->version().Equals(*extension->version()));
6080 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
6081 data->update_url());
6082 EXPECT_EQ(extension->name(), data->name());
6083 }
6084
6085 TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
6086 InitializeEmptyExtensionService();
6087 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6088 const Extension* extension = service()->GetInstalledExtension(good_crx);
6089 ASSERT_TRUE(extension);
6090
6091 syncer::FakeSyncChangeProcessor processor;
6092 extension_sync_service()->MergeDataAndStartSyncing(
6093 syncer::APPS,
6094 syncer::SyncDataList(),
6095 scoped_ptr<syncer::SyncChangeProcessor>(
6096 new syncer::FakeSyncChangeProcessor),
6097 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6098
6099 syncer::SyncDataList list =
6100 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6101 ASSERT_EQ(list.size(), 0U);
6102 }
6103
6104 TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
6105 InitializeEmptyExtensionService();
6106 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6107 const Extension* extension = service()->GetInstalledExtension(good_crx);
6108 ASSERT_TRUE(extension);
6109
6110 syncer::FakeSyncChangeProcessor processor;
6111 extension_sync_service()->MergeDataAndStartSyncing(
6112 syncer::EXTENSIONS,
6113 syncer::SyncDataList(),
6114 scoped_ptr<syncer::SyncChangeProcessor>(
6115 new syncer::FakeSyncChangeProcessor),
6116 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6117
6118 {
6119 syncer::SyncDataList list =
6120 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6121 ASSERT_EQ(list.size(), 1U);
6122 scoped_ptr<ExtensionSyncData> data =
6123 ExtensionSyncData::CreateFromSyncData(list[0]);
6124 ASSERT_TRUE(data.get());
6125 EXPECT_TRUE(data->enabled());
6126 EXPECT_FALSE(data->incognito_enabled());
6127 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6128 }
6129
6130 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
6131 {
6132 syncer::SyncDataList list =
6133 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6134 ASSERT_EQ(list.size(), 1U);
6135 scoped_ptr<ExtensionSyncData> data =
6136 ExtensionSyncData::CreateFromSyncData(list[0]);
6137 ASSERT_TRUE(data.get());
6138 EXPECT_FALSE(data->enabled());
6139 EXPECT_FALSE(data->incognito_enabled());
6140 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6141 }
6142
6143 extensions::util::SetIsIncognitoEnabled(good_crx, profile(), true);
6144 extensions::util::SetAllowedScriptingOnAllUrls(
6145 good_crx, profile(), false);
6146 {
6147 syncer::SyncDataList list =
6148 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6149 ASSERT_EQ(list.size(), 1U);
6150 scoped_ptr<ExtensionSyncData> data =
6151 ExtensionSyncData::CreateFromSyncData(list[0]);
6152 ASSERT_TRUE(data.get());
6153 EXPECT_FALSE(data->enabled());
6154 EXPECT_TRUE(data->incognito_enabled());
6155 EXPECT_EQ(ExtensionSyncData::BOOLEAN_FALSE, data->all_urls_enabled());
6156 }
6157
6158 service()->EnableExtension(good_crx);
6159 extensions::util::SetAllowedScriptingOnAllUrls(
6160 good_crx, profile(), true);
6161 {
6162 syncer::SyncDataList list =
6163 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6164 ASSERT_EQ(list.size(), 1U);
6165 scoped_ptr<ExtensionSyncData> data =
6166 ExtensionSyncData::CreateFromSyncData(list[0]);
6167 ASSERT_TRUE(data.get());
6168 EXPECT_TRUE(data->enabled());
6169 EXPECT_TRUE(data->incognito_enabled());
6170 EXPECT_EQ(ExtensionSyncData::BOOLEAN_TRUE, data->all_urls_enabled());
6171 }
6172 }
6173
6174 TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
6175 InitializeEmptyExtensionService();
6176 InstallCRXWithLocation(
6177 data_dir().AppendASCII("good.crx"), Manifest::EXTERNAL_PREF, INSTALL_NEW);
6178 const Extension* extension = service()->GetInstalledExtension(good_crx);
6179 ASSERT_TRUE(extension);
6180
6181 syncer::FakeSyncChangeProcessor processor;
6182 extension_sync_service()->MergeDataAndStartSyncing(
6183 syncer::EXTENSIONS,
6184 syncer::SyncDataList(),
6185 scoped_ptr<syncer::SyncChangeProcessor>(
6186 new syncer::FakeSyncChangeProcessor),
6187 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6188
6189 UninstallExtension(good_crx, false);
6190 EXPECT_TRUE(
6191 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
6192
6193 sync_pb::EntitySpecifics specifics;
6194 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6195 sync_pb::ExtensionSpecifics* extension_specifics =
6196 app_specifics->mutable_extension();
6197 extension_specifics->set_id(good_crx);
6198 extension_specifics->set_version("1.0");
6199 extension_specifics->set_enabled(true);
6200
6201 syncer::SyncData sync_data =
6202 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6203 syncer::SyncChange sync_change(FROM_HERE,
6204 syncer::SyncChange::ACTION_UPDATE,
6205 sync_data);
6206 syncer::SyncChangeList list(1);
6207 list[0] = sync_change;
6208
6209 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6210 EXPECT_TRUE(
6211 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
6212 }
6213
6214 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
6215 InitializeEmptyExtensionService();
6216 const Extension* app =
6217 PackAndInstallCRX(data_dir().AppendASCII("app"), INSTALL_NEW);
6218 ASSERT_TRUE(app);
6219 ASSERT_TRUE(app->is_app());
6220
6221 syncer::FakeSyncChangeProcessor processor;
6222 extension_sync_service()->MergeDataAndStartSyncing(
6223 syncer::APPS,
6224 syncer::SyncDataList(),
6225 scoped_ptr<syncer::SyncChangeProcessor>(
6226 new syncer::FakeSyncChangeProcessor),
6227 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6228
6229 syncer::StringOrdinal initial_ordinal =
6230 syncer::StringOrdinal::CreateInitialOrdinal();
6231 {
6232 syncer::SyncDataList list =
6233 extension_sync_service()->GetAllSyncData(syncer::APPS);
6234 ASSERT_EQ(list.size(), 1U);
6235
6236 scoped_ptr<ExtensionSyncData> app_sync_data =
6237 ExtensionSyncData::CreateFromSyncData(list[0]);
6238 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->app_launch_ordinal()));
6239 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6240 }
6241
6242 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
6243 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
6244 {
6245 syncer::SyncDataList list =
6246 extension_sync_service()->GetAllSyncData(syncer::APPS);
6247 ASSERT_EQ(list.size(), 1U);
6248
6249 scoped_ptr<ExtensionSyncData> app_sync_data =
6250 ExtensionSyncData::CreateFromSyncData(list[0]);
6251 ASSERT_TRUE(app_sync_data.get());
6252 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6253 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6254 }
6255
6256 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
6257 {
6258 syncer::SyncDataList list =
6259 extension_sync_service()->GetAllSyncData(syncer::APPS);
6260 ASSERT_EQ(list.size(), 1U);
6261
6262 scoped_ptr<ExtensionSyncData> app_sync_data =
6263 ExtensionSyncData::CreateFromSyncData(list[0]);
6264 ASSERT_TRUE(app_sync_data.get());
6265 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6266 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->page_ordinal()));
6267 }
6268 }
6269
6270 // TODO (rdevlin.cronin): The OnExtensionMoved() method has been removed from
6271 // ExtensionService, so this test probably needs a new home. Unfortunately, it
6272 // relies pretty heavily on things like InitializeExtension[Sync]Service() and
6273 // PackAndInstallCRX(). When we clean up a bit more, this should move out.
6274 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
6275 InitializeEmptyExtensionService();
6276 const size_t kAppCount = 3;
6277 const Extension* apps[kAppCount];
6278 apps[0] = PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
6279 apps[1] = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
6280 apps[2] = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
6281 for (size_t i = 0; i < kAppCount; ++i) {
6282 ASSERT_TRUE(apps[i]);
6283 ASSERT_TRUE(apps[i]->is_app());
6284 }
6285
6286 syncer::FakeSyncChangeProcessor processor;
6287 extension_sync_service()->MergeDataAndStartSyncing(
6288 syncer::APPS,
6289 syncer::SyncDataList(),
6290 scoped_ptr<syncer::SyncChangeProcessor>(
6291 new syncer::FakeSyncChangeProcessor),
6292 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6293
6294 ExtensionPrefs::Get(service()->GetBrowserContext())
6295 ->app_sorting()
6296 ->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
6297 {
6298 syncer::SyncDataList list =
6299 extension_sync_service()->GetAllSyncData(syncer::APPS);
6300 ASSERT_EQ(list.size(), 3U);
6301
6302 scoped_ptr<ExtensionSyncData> data[kAppCount];
6303 for (size_t i = 0; i < kAppCount; ++i) {
6304 data[i] = ExtensionSyncData::CreateFromSyncData(list[i]);
6305 ASSERT_TRUE(data[i].get());
6306 }
6307
6308 // The sync data is not always in the same order our apps were installed in,
6309 // so we do that sorting here so we can make sure the values are changed as
6310 // expected.
6311 syncer::StringOrdinal app_launch_ordinals[kAppCount];
6312 for (size_t i = 0; i < kAppCount; ++i) {
6313 for (size_t j = 0; j < kAppCount; ++j) {
6314 if (apps[i]->id() == data[j]->id())
6315 app_launch_ordinals[i] = data[j]->app_launch_ordinal();
6316 }
6317 }
6318
6319 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
6320 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
6321 }
6322 }
6323
6324 TEST_F(ExtensionServiceTest, GetSyncDataList) {
6325 InitializeEmptyExtensionService();
6326 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6327 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
6328 InstallCRX(data_dir().AppendASCII("theme.crx"), INSTALL_NEW);
6329 InstallCRX(data_dir().AppendASCII("theme2.crx"), INSTALL_NEW);
6330
6331 syncer::FakeSyncChangeProcessor processor;
6332 extension_sync_service()->MergeDataAndStartSyncing(
6333 syncer::APPS,
6334 syncer::SyncDataList(),
6335 scoped_ptr<syncer::SyncChangeProcessor>(
6336 new syncer::FakeSyncChangeProcessor),
6337 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6338 extension_sync_service()->MergeDataAndStartSyncing(
6339 syncer::EXTENSIONS,
6340 syncer::SyncDataList(),
6341 scoped_ptr<syncer::SyncChangeProcessor>(
6342 new syncer::FakeSyncChangeProcessor),
6343 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6344
6345 service()->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
6346 TerminateExtension(theme2_crx);
6347
6348 EXPECT_EQ(0u, extension_sync_service()->GetAllSyncData(syncer::APPS).size());
6349 EXPECT_EQ(
6350 2u, extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS).size());
6351 }
6352
6353 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
6354 InitializeEmptyExtensionService();
6355 syncer::FakeSyncChangeProcessor processor;
6356 extension_sync_service()->MergeDataAndStartSyncing(
6357 syncer::EXTENSIONS,
6358 syncer::SyncDataList(),
6359 scoped_ptr<syncer::SyncChangeProcessor>(
6360 new syncer::FakeSyncChangeProcessor),
6361 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6362
6363 sync_pb::EntitySpecifics specifics;
6364 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6365 ext_specifics->set_id(good_crx);
6366 ext_specifics->set_version("1.0");
6367 syncer::SyncData sync_data =
6368 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6369 syncer::SyncChange sync_change(FROM_HERE,
6370 syncer::SyncChange::ACTION_DELETE,
6371 sync_data);
6372 syncer::SyncChangeList list(1);
6373 list[0] = sync_change;
6374
6375 // Should do nothing.
6376 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6377 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6378
6379 // Install the extension.
6380 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6381 InstallCRX(extension_path, INSTALL_NEW);
6382 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6383
6384 // Should uninstall the extension.
6385 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6386 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6387
6388 // Should again do nothing.
6389 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6390 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6391 }
6392
6393 TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
6394 InitializeEmptyExtensionService();
6395
6396 // Install the extension.
6397 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6398 InstallCRX(extension_path, INSTALL_NEW);
6399 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6400
6401 sync_pb::EntitySpecifics specifics;
6402 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6403 sync_pb::ExtensionSpecifics* extension_specifics =
6404 app_specifics->mutable_extension();
6405 extension_specifics->set_id(good_crx);
6406 extension_specifics->set_version(
6407 service()->GetInstalledExtension(good_crx)->version()->GetString());
6408
6409 {
6410 extension_specifics->set_enabled(true);
6411 syncer::SyncData sync_data =
6412 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6413 syncer::SyncChange sync_change(FROM_HERE,
6414 syncer::SyncChange::ACTION_DELETE,
6415 sync_data);
6416 syncer::SyncChangeList list(1);
6417 list[0] = sync_change;
6418
6419 // Should do nothing
6420 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6421 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6422 }
6423
6424 {
6425 extension_specifics->set_enabled(false);
6426 syncer::SyncData sync_data =
6427 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6428 syncer::SyncChange sync_change(FROM_HERE,
6429 syncer::SyncChange::ACTION_UPDATE,
6430 sync_data);
6431 syncer::SyncChangeList list(1);
6432 list[0] = sync_change;
6433
6434 // Should again do nothing.
6435 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6436 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
6437 }
6438 }
6439
6440 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
6441 InitializeEmptyExtensionService();
6442 syncer::FakeSyncChangeProcessor processor;
6443 extension_sync_service()->MergeDataAndStartSyncing(
6444 syncer::EXTENSIONS,
6445 syncer::SyncDataList(),
6446 scoped_ptr<syncer::SyncChangeProcessor>(
6447 new syncer::FakeSyncChangeProcessor),
6448 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6449
6450 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6451 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6452 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6453 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6454 good_crx, profile()));
6455 const bool kDefaultAllowedScripting =
6456 extensions::util::DefaultAllowedScriptingOnAllUrls();
6457 EXPECT_EQ(kDefaultAllowedScripting,
6458 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6459
6460 sync_pb::EntitySpecifics specifics;
6461 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6462 ext_specifics->set_id(good_crx);
6463 ext_specifics->set_version(
6464 service()->GetInstalledExtension(good_crx)->version()->GetString());
6465 ext_specifics->set_enabled(false);
6466
6467 {
6468 syncer::SyncData sync_data =
6469 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6470 syncer::SyncChange sync_change(FROM_HERE,
6471 syncer::SyncChange::ACTION_UPDATE,
6472 sync_data);
6473 syncer::SyncChangeList list(1);
6474 list[0] = sync_change;
6475 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6476 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6477 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6478 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6479 good_crx, profile()));
6480 EXPECT_EQ(kDefaultAllowedScripting,
6481 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6482 }
6483
6484 {
6485 ext_specifics->set_enabled(true);
6486 ext_specifics->set_incognito_enabled(true);
6487 syncer::SyncData sync_data =
6488 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6489 syncer::SyncChange sync_change(FROM_HERE,
6490 syncer::SyncChange::ACTION_UPDATE,
6491 sync_data);
6492 syncer::SyncChangeList list(1);
6493 list[0] = sync_change;
6494 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6495 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6496 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6497 }
6498
6499 {
6500 ext_specifics->set_enabled(false);
6501 ext_specifics->set_incognito_enabled(true);
6502 syncer::SyncData sync_data =
6503 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6504 syncer::SyncChange sync_change(FROM_HERE,
6505 syncer::SyncChange::ACTION_UPDATE,
6506 sync_data);
6507 syncer::SyncChangeList list(1);
6508 list[0] = sync_change;
6509 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6510 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6511 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6512 }
6513
6514 {
6515 ext_specifics->set_enabled(true);
6516 ext_specifics->set_all_urls_enabled(!kDefaultAllowedScripting);
6517 syncer::SyncData sync_data =
6518 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6519 syncer::SyncChange sync_change(FROM_HERE,
6520 syncer::SyncChange::ACTION_UPDATE,
6521 sync_data);
6522 syncer::SyncChangeList list(1);
6523 list[0] = sync_change;
6524 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6525 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6526 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6527 good_crx, profile()));
6528 EXPECT_EQ(!kDefaultAllowedScripting,
6529 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6530 }
6531
6532 {
6533 ext_specifics->set_all_urls_enabled(kDefaultAllowedScripting);
6534 syncer::SyncData sync_data =
6535 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6536 syncer::SyncChange sync_change(FROM_HERE,
6537 syncer::SyncChange::ACTION_UPDATE,
6538 sync_data);
6539 syncer::SyncChangeList list(1);
6540 list[0] = sync_change;
6541 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6542 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6543 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6544 good_crx, profile()));
6545 EXPECT_EQ(kDefaultAllowedScripting,
6546 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6547 }
6548
6549 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6550 }
6551
6552 TEST_F(ExtensionServiceTest, ProcessSyncDataNewExtension) {
6553 InitializeEmptyExtensionService();
6554 syncer::FakeSyncChangeProcessor processor;
6555 extension_sync_service()->MergeDataAndStartSyncing(
6556 syncer::EXTENSIONS,
6557 syncer::SyncDataList(),
6558 scoped_ptr<syncer::SyncChangeProcessor>(
6559 new syncer::FakeSyncChangeProcessor),
6560 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6561
6562 const base::FilePath path = data_dir().AppendASCII("good.crx");
6563 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6564
6565 struct TestCase {
6566 const char* name; // For failure output only.
6567 bool sync_enabled; // The "enabled" flag coming in from Sync.
6568 // The disable reason(s) coming in from Sync, or -1 for "not set".
6569 int sync_disable_reasons;
6570 // The disable reason(s) that should be set on the installed extension.
6571 // This will usually be the same as |sync_disable_reasons|, but see the
6572 // "Legacy" case.
6573 int expect_disable_reasons;
6574 // Whether the extension's permissions should be auto-granted during
6575 // installation.
6576 bool expect_permissions_granted;
6577 } test_cases[] = {
6578 // Standard case: Extension comes in enabled; permissions should be granted
6579 // during installation.
6580 { "Standard", true, 0, 0, true },
6581 // If the extension comes in disabled, its permissions should still be
6582 // granted (the user already approved them on another machine).
6583 { "Disabled", false, Extension::DISABLE_USER_ACTION,
6584 Extension::DISABLE_USER_ACTION, true },
6585 // Legacy case (<M45): No disable reasons come in from Sync (see
6586 // crbug.com/484214). After installation, the reason should be set to
6587 // DISABLE_UNKNOWN_FROM_SYNC.
6588 { "Legacy", false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC, true },
6589 // If the extension came in disabled due to a permissions increase, then the
6590 // user has *not* approved the permissions, and they shouldn't be granted.
6591 // crbug.com/484214
6592 { "PermissionsIncrease", false, Extension::DISABLE_PERMISSIONS_INCREASE,
6593 Extension::DISABLE_PERMISSIONS_INCREASE, false },
6594 };
6595
6596 for (const TestCase& test_case : test_cases) {
6597 SCOPED_TRACE(test_case.name);
6598
6599 sync_pb::EntitySpecifics specifics;
6600 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6601 ext_specifics->set_id(good_crx);
6602 ext_specifics->set_version(base::Version("1").GetString());
6603 ext_specifics->set_enabled(test_case.sync_enabled);
6604 if (test_case.sync_disable_reasons != -1)
6605 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6606
6607 syncer::SyncData sync_data =
6608 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6609 syncer::SyncChange sync_change(FROM_HERE,
6610 syncer::SyncChange::ACTION_UPDATE,
6611 sync_data);
6612 syncer::SyncChangeList list(1, sync_change);
6613 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6614
6615 ASSERT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
6616 UpdateExtension(good_crx, path, test_case.sync_enabled ? ENABLED
6617 : DISABLED);
6618 EXPECT_EQ(test_case.expect_disable_reasons,
6619 prefs->GetDisableReasons(good_crx));
6620 scoped_ptr<const PermissionSet> permissions =
6621 prefs->GetGrantedPermissions(good_crx);
6622 EXPECT_EQ(test_case.expect_permissions_granted, !permissions->IsEmpty());
6623 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6624
6625 // Remove the extension again, so we can install it again for the next case.
6626 UninstallExtension(good_crx, false,
6627 test_case.sync_enabled ? Extension::ENABLED
6628 : Extension::DISABLED);
6629 }
6630 }
6631
6632 TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
6633 InitializeExtensionServiceWithUpdater();
6634 syncer::FakeSyncChangeProcessor processor;
6635 extension_sync_service()->MergeDataAndStartSyncing(
6636 syncer::EXTENSIONS,
6637 syncer::SyncDataList(),
6638 scoped_ptr<syncer::SyncChangeProcessor>(
6639 new syncer::FakeSyncChangeProcessor),
6640 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6641
6642 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6643 TerminateExtension(good_crx);
6644 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6645 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6646
6647 sync_pb::EntitySpecifics specifics;
6648 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6649 ext_specifics->set_id(good_crx);
6650 ext_specifics->set_version(
6651 service()->GetInstalledExtension(good_crx)->version()->GetString());
6652 ext_specifics->set_enabled(false);
6653 ext_specifics->set_incognito_enabled(true);
6654 syncer::SyncData sync_data =
6655 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6656 syncer::SyncChange sync_change(FROM_HERE,
6657 syncer::SyncChange::ACTION_UPDATE,
6658 sync_data);
6659 syncer::SyncChangeList list(1);
6660 list[0] = sync_change;
6661
6662 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6663 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6664 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6665
6666 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6667 }
6668
6669 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
6670 InitializeExtensionServiceWithUpdater();
6671 syncer::FakeSyncChangeProcessor processor;
6672 extension_sync_service()->MergeDataAndStartSyncing(
6673 syncer::EXTENSIONS,
6674 syncer::SyncDataList(),
6675 scoped_ptr<syncer::SyncChangeProcessor>(
6676 new syncer::FakeSyncChangeProcessor),
6677 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6678
6679 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6680 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6681 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6682
6683 sync_pb::EntitySpecifics specifics;
6684 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6685 ext_specifics->set_id(good_crx);
6686 ext_specifics->set_enabled(true);
6687
6688 const base::Version installed_version =
6689 *service()->GetInstalledExtension(good_crx)->version();
6690
6691 {
6692 ext_specifics->set_version(installed_version.GetString());
6693 syncer::SyncData sync_data =
6694 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6695 syncer::SyncChange sync_change(FROM_HERE,
6696 syncer::SyncChange::ACTION_UPDATE,
6697 sync_data);
6698 syncer::SyncChangeList list(1, sync_change);
6699
6700 // Should do nothing if extension version == sync version.
6701 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6702 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6703 // Make sure the version we'll send back to sync didn't change.
6704 syncer::SyncDataList data =
6705 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6706 ASSERT_EQ(1u, data.size());
6707 scoped_ptr<ExtensionSyncData> extension_data =
6708 ExtensionSyncData::CreateFromSyncData(data[0]);
6709 ASSERT_TRUE(extension_data);
6710 EXPECT_TRUE(installed_version.Equals(extension_data->version()));
6711 }
6712
6713 // Should do nothing if extension version > sync version.
6714 {
6715 ext_specifics->set_version("0.0.0.0");
6716 syncer::SyncData sync_data =
6717 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6718 syncer::SyncChange sync_change(FROM_HERE,
6719 syncer::SyncChange::ACTION_UPDATE,
6720 sync_data);
6721 syncer::SyncChangeList list(1, sync_change);
6722
6723 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6724 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6725 // Make sure the version we'll send back to sync didn't change.
6726 syncer::SyncDataList data =
6727 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6728 ASSERT_EQ(1u, data.size());
6729 scoped_ptr<ExtensionSyncData> extension_data =
6730 ExtensionSyncData::CreateFromSyncData(data[0]);
6731 ASSERT_TRUE(extension_data);
6732 EXPECT_TRUE(installed_version.Equals(extension_data->version()));
6733 }
6734
6735 // Should kick off an update if extension version < sync version.
6736 {
6737 const base::Version new_version("9.9.9.9");
6738 ext_specifics->set_version(new_version.GetString());
6739 syncer::SyncData sync_data =
6740 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6741 syncer::SyncChange sync_change(FROM_HERE,
6742 syncer::SyncChange::ACTION_UPDATE,
6743 sync_data);
6744 syncer::SyncChangeList list(1, sync_change);
6745
6746 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6747 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6748 // Make sure that we'll send the NEW version back to sync, even though we
6749 // haven't actually updated yet. This is to prevent the data in sync from
6750 // flip-flopping back and forth until all clients are up to date.
6751 syncer::SyncDataList data =
6752 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6753 ASSERT_EQ(1u, data.size());
6754 scoped_ptr<ExtensionSyncData> extension_data =
6755 ExtensionSyncData::CreateFromSyncData(data[0]);
6756 ASSERT_TRUE(extension_data);
6757 EXPECT_TRUE(new_version.Equals(extension_data->version()));
6758 }
6759
6760 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6761 }
6762
6763 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
6764 InitializeExtensionServiceWithUpdater();
6765 syncer::FakeSyncChangeProcessor processor;
6766 extension_sync_service()->MergeDataAndStartSyncing(
6767 syncer::EXTENSIONS,
6768 syncer::SyncDataList(),
6769 scoped_ptr<syncer::SyncChangeProcessor>(
6770 new syncer::FakeSyncChangeProcessor),
6771 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6772
6773 sync_pb::EntitySpecifics specifics;
6774 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6775 ext_specifics->set_id(good_crx);
6776 ext_specifics->set_enabled(false);
6777 ext_specifics->set_incognito_enabled(true);
6778 ext_specifics->set_update_url("http://www.google.com/");
6779 ext_specifics->set_version("1.2.3.4");
6780 syncer::SyncData sync_data =
6781 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6782 syncer::SyncChange sync_change(FROM_HERE,
6783 syncer::SyncChange::ACTION_UPDATE,
6784 sync_data);
6785 syncer::SyncChangeList list(1);
6786 list[0] = sync_change;
6787
6788 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6789 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6790 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6791 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6792 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6793 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6794
6795 const extensions::PendingExtensionInfo* info;
6796 EXPECT_TRUE(
6797 (info = service()->pending_extension_manager()->GetById(good_crx)));
6798 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
6799 EXPECT_TRUE(info->is_from_sync());
6800 EXPECT_EQ(Manifest::INTERNAL, info->install_source());
6801 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
6802 }
6803
6804 TEST_F(ExtensionServiceTest, ProcessSyncDataEnableDisable) {
6805 InitializeEmptyExtensionService();
6806 extension_sync_service()->MergeDataAndStartSyncing(
6807 syncer::EXTENSIONS,
6808 syncer::SyncDataList(),
6809 scoped_ptr<syncer::SyncChangeProcessor>(
6810 new syncer::FakeSyncChangeProcessor),
6811 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6812
6813 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6814
6815 struct TestCase {
6816 const char* name; // For failure output only.
6817 // Set of disable reasons before any Sync data comes in. If this is != 0,
6818 // the extension is disabled.
6819 int previous_disable_reasons;
6820 bool sync_enable; // The enabled flag coming in from Sync.
6821 // The disable reason(s) coming in from Sync, or -1 for "not set".
6822 int sync_disable_reasons;
6823 // The expected set of disable reasons after processing the Sync update. The
6824 // extension should be disabled iff this is != 0.
6825 int expect_disable_reasons;
6826 } test_cases[] = {
6827 { "NopEnable", 0, true, 0, 0 },
6828 { "NopDisable", Extension::DISABLE_USER_ACTION, false,
6829 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6830 { "Disable", 0, false, Extension::DISABLE_USER_ACTION,
6831 Extension::DISABLE_USER_ACTION },
6832 { "DisableLegacy", 0, false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC },
6833 { "AddDisableReason", Extension::DISABLE_REMOTE_INSTALL, false,
6834 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION,
6835 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION },
6836 { "AddDisableReasonLegacy", Extension::DISABLE_USER_ACTION, false, -1,
6837 Extension::DISABLE_USER_ACTION | Extension::DISABLE_UNKNOWN_FROM_SYNC},
6838 { "RemoveDisableReason",
6839 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION, false,
6840 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6841 { "Enable", Extension::DISABLE_USER_ACTION, true, 0, 0 },
6842 { "EnableLegacy", Extension::DISABLE_USER_ACTION, true, -1, 0 },
6843 };
6844
6845 for (const TestCase& test_case : test_cases) {
6846 SCOPED_TRACE(test_case.name);
6847
6848 std::string id;
6849 std::string version;
6850 // Don't keep |extension| around longer than necessary.
6851 {
6852 const Extension* extension =
6853 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6854 // The extension should now be installed and enabled.
6855 ASSERT_TRUE(extension);
6856 id = extension->id();
6857 version = extension->VersionString();
6858 }
6859 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6860
6861 // Disable it if the test case says so.
6862 if (test_case.previous_disable_reasons) {
6863 service()->DisableExtension(id, test_case.previous_disable_reasons);
6864 ASSERT_TRUE(registry()->disabled_extensions().Contains(id));
6865 }
6866
6867 // Now a sync update comes in.
6868 sync_pb::EntitySpecifics specifics;
6869 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6870 ext_specifics->set_id(id);
6871 ext_specifics->set_enabled(test_case.sync_enable);
6872 ext_specifics->set_version(version);
6873 if (test_case.sync_disable_reasons != -1)
6874 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6875
6876 syncer::SyncData sync_data =
6877 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6878 syncer::SyncChange sync_change(FROM_HERE,
6879 syncer::SyncChange::ACTION_UPDATE,
6880 sync_data);
6881 syncer::SyncChangeList list(1, sync_change);
6882 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6883
6884 // Check expectations.
6885 const bool expect_enabled = !test_case.expect_disable_reasons;
6886 EXPECT_EQ(expect_enabled, service()->IsExtensionEnabled(id));
6887 EXPECT_EQ(test_case.expect_disable_reasons, prefs->GetDisableReasons(id));
6888
6889 // Remove the extension again, so we can install it again for the next case.
6890 UninstallExtension(id, false, expect_enabled ? Extension::ENABLED
6891 : Extension::DISABLED);
6892 }
6893 }
6894
6895 TEST_F(ExtensionServiceTest, ProcessSyncDataDeferredEnable) {
6896 InitializeEmptyExtensionService();
6897 extension_sync_service()->MergeDataAndStartSyncing(
6898 syncer::EXTENSIONS,
6899 syncer::SyncDataList(),
6900 scoped_ptr<syncer::SyncChangeProcessor>(
6901 new syncer::FakeSyncChangeProcessor),
6902 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6903
6904 base::FilePath base_path = data_dir().AppendASCII("permissions_increase");
6905 base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
6906
6907 base::FilePath path = base_path.AppendASCII("v1");
6908 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
6909 // The extension must now be installed and enabled.
6910 ASSERT_TRUE(extension);
6911 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
6912
6913 // Save the id, as the extension object will be destroyed during updating.
6914 std::string id = extension->id();
6915
6916 // Update to a new version with increased permissions.
6917 path = base_path.AppendASCII("v2");
6918 PackCRXAndUpdateExtension(id, path, pem_path, DISABLED);
6919
6920 // Now a sync update comes in, telling us to re-enable a *newer* version.
6921 sync_pb::EntitySpecifics specifics;
6922 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6923 ext_specifics->set_id(id);
6924 ext_specifics->set_version("3");
6925 ext_specifics->set_enabled(true);
6926 ext_specifics->set_disable_reasons(Extension::DISABLE_NONE);
6927
6928 syncer::SyncData sync_data =
6929 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6930 syncer::SyncChange sync_change(FROM_HERE,
6931 syncer::SyncChange::ACTION_UPDATE,
6932 sync_data);
6933 syncer::SyncChangeList list(1, sync_change);
6934 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6935
6936 // Since the version didn't match, the extension should still be disabled.
6937 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
6938
6939 // After we update to the matching version, the extension should get enabled.
6940 path = base_path.AppendASCII("v3");
6941 PackCRXAndUpdateExtension(id, path, pem_path, ENABLED);
6942 }
6943
6944 TEST_F(ExtensionServiceTest, ProcessSyncDataPermissionApproval) {
6945 // This is the update URL specified in the test extension. Setting it here is
6946 // necessary to make it considered syncable.
6947 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6948 switches::kAppsGalleryUpdateURL,
6949 "http://localhost/autoupdate/updates.xml");
6950
6951 InitializeEmptyExtensionService();
6952 extension_sync_service()->MergeDataAndStartSyncing(
6953 syncer::EXTENSIONS,
6954 syncer::SyncDataList(),
6955 scoped_ptr<syncer::SyncChangeProcessor>(
6956 new syncer::FakeSyncChangeProcessor),
6957 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6958
6959 const base::FilePath base_path =
6960 data_dir().AppendASCII("permissions_increase");
6961 const base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
6962 const base::FilePath path_v1 = base_path.AppendASCII("v1");
6963 const base::FilePath path_v2 = base_path.AppendASCII("v2");
6964
6965 base::ScopedTempDir crx_dir;
6966 ASSERT_TRUE(crx_dir.CreateUniqueTempDir());
6967 const base::FilePath crx_path_v1 = crx_dir.path().AppendASCII("temp1.crx");
6968 PackCRX(path_v1, pem_path, crx_path_v1);
6969 const base::FilePath crx_path_v2 = crx_dir.path().AppendASCII("temp2.crx");
6970 PackCRX(path_v2, pem_path, crx_path_v2);
6971
6972 const std::string v1("1");
6973 const std::string v2("2");
6974
6975 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6976
6977 struct TestCase {
6978 const char* name; // For failure output only.
6979 const std::string& sync_version; // The version coming in from Sync.
6980 // The disable reason(s) coming in from Sync, or -1 for "not set".
6981 int sync_disable_reasons;
6982 // The expected set of disable reasons after processing the Sync update. The
6983 // extension should be enabled iff this is 0.
6984 int expect_disable_reasons;
6985 // Whether the extension's permissions should be auto-granted.
6986 bool expect_permissions_granted;
6987 } test_cases[] = {
6988 // Sync tells us to re-enable an older version. No permissions should be
6989 // granted, since we can't be sure if the user actually approved the right
6990 // set of permissions.
6991 { "OldVersion", v1, 0, Extension::DISABLE_PERMISSIONS_INCREASE, false },
6992 // Legacy case: Sync tells us to re-enable the extension, but doesn't
6993 // specify disable reasons. No permissions should be granted.
6994 { "Legacy", v2, -1, Extension::DISABLE_PERMISSIONS_INCREASE, false },
6995 // Sync tells us to re-enable the extension and explicitly removes the
6996 // disable reasons. Now the extension should have its permissions granted.
6997 { "GrantPermissions", v2, 0, Extension::DISABLE_NONE, true },
6998 };
6999
7000 for (const TestCase& test_case : test_cases) {
7001 SCOPED_TRACE(test_case.name);
7002
7003 std::string id;
7004 // Don't keep |extension| around longer than necessary (it'll be destroyed
7005 // during updating).
7006 {
7007 const Extension* extension = InstallCRX(crx_path_v1, INSTALL_NEW);
7008 // The extension should now be installed and enabled.
7009 ASSERT_TRUE(extension);
7010 ASSERT_EQ(v1, extension->VersionString());
7011 id = extension->id();
7012 }
7013 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
7014
7015 scoped_ptr<const PermissionSet> granted_permissions_v1 =
7016 prefs->GetGrantedPermissions(id);
7017
7018 // Update to a new version with increased permissions.
7019 UpdateExtension(id, crx_path_v2, DISABLED);
7020
7021 // Now the extension should be disabled due to a permissions increase.
7022 {
7023 const Extension* extension =
7024 registry()->disabled_extensions().GetByID(id);
7025 ASSERT_TRUE(extension);
7026 ASSERT_EQ(v2, extension->VersionString());
7027 }
7028 ASSERT_TRUE(prefs->HasDisableReason(
7029 id, Extension::DISABLE_PERMISSIONS_INCREASE));
7030
7031 // No new permissions should have been granted.
7032 scoped_ptr<const PermissionSet> granted_permissions_v2 =
7033 prefs->GetGrantedPermissions(id);
7034 ASSERT_EQ(*granted_permissions_v1, *granted_permissions_v2);
7035
7036 // Now a sync update comes in.
7037 sync_pb::EntitySpecifics specifics;
7038 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
7039 ext_specifics->set_id(id);
7040 ext_specifics->set_enabled(true);
7041 ext_specifics->set_version(test_case.sync_version);
7042 if (test_case.sync_disable_reasons != -1)
7043 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
7044
7045 syncer::SyncData sync_data =
7046 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
7047 syncer::SyncChange sync_change(FROM_HERE,
7048 syncer::SyncChange::ACTION_UPDATE,
7049 sync_data);
7050 syncer::SyncChangeList list(1, sync_change);
7051 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
7052
7053 // Check expectations.
7054 const bool expect_enabled = !test_case.expect_disable_reasons;
7055 EXPECT_EQ(expect_enabled, service()->IsExtensionEnabled(id));
7056 EXPECT_EQ(test_case.expect_disable_reasons, prefs->GetDisableReasons(id));
7057 scoped_ptr<const PermissionSet> granted_permissions =
7058 prefs->GetGrantedPermissions(id);
7059 if (test_case.expect_permissions_granted) {
7060 scoped_ptr<const PermissionSet> active_permissions =
7061 prefs->GetActivePermissions(id);
7062 EXPECT_EQ(*granted_permissions, *active_permissions);
7063 } else {
7064 EXPECT_EQ(*granted_permissions, *granted_permissions_v1);
7065 }
7066
7067 // Remove the extension again, so we can install it again for the next case.
7068 UninstallExtension(id, false, expect_enabled ? Extension::ENABLED
7069 : Extension::DISABLED);
7070 }
7071 }
7072
7073 #if defined(ENABLE_SUPERVISED_USERS)
7074 class ExtensionServiceTestSupervised : public ExtensionServiceTest,
7075 public SupervisedUserService::Delegate {
7076 public:
7077 void SetUp() override {
7078 ExtensionServiceTest::SetUp();
7079
7080 // This is the update URL specified in the permissions test extension.
7081 // Setting it here is necessary to make the extension considered syncable.
7082 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
7083 switches::kAppsGalleryUpdateURL,
7084 "http://localhost/autoupdate/updates.xml");
7085 }
7086
7087 void TearDown() override {
7088 supervised_user_service()->SetDelegate(nullptr);
7089
7090 ExtensionServiceTest::TearDown();
7091 }
7092
7093 protected:
7094 void InitServices(bool profile_is_supervised) {
7095 ExtensionServiceInitParams params = CreateDefaultInitParams();
7096 params.profile_is_supervised = profile_is_supervised;
7097 InitializeExtensionService(params);
7098
7099 supervised_user_service()->SetDelegate(this);
7100 supervised_user_service()->Init();
7101 }
7102
7103 std::string InstallPermissionsTestExtension() {
7104 const std::string version("1");
7105
7106 const Extension* extension =
7107 PackAndInstallCRX(dir_path(version), pem_path(), INSTALL_NEW,
7108 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7109 // The extension must now be installed and enabled.
7110 EXPECT_TRUE(extension);
7111 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7112 EXPECT_EQ(version, extension->VersionString());
7113
7114 return extension->id();
7115 }
7116
7117 void UpdatePermissionsTestExtension(const std::string& id,
7118 const std::string& version,
7119 UpdateState expected_state) {
7120 PackCRXAndUpdateExtension(id, dir_path(version), pem_path(),
7121 expected_state);
7122 const Extension* extension = registry()->GetInstalledExtension(id);
7123 ASSERT_TRUE(extension);
7124 // The version should have been updated.
7125 EXPECT_EQ(version, extension->VersionString());
7126 }
7127
7128 SupervisedUserService* supervised_user_service() {
7129 return SupervisedUserServiceFactory::GetForProfile(profile());
7130 }
7131
7132 static std::string UpdateRequestId(const std::string& extension_id,
7133 const std::string& version) {
7134 return SupervisedUserService::GetExtensionUpdateRequestId(
7135 extension_id, base::Version(version));
7136 }
7137
7138 private:
7139 // This prevents the legacy supervised user init code from running.
7140 bool SetActive(bool active) override { return true; }
7141
7142 base::FilePath base_path() const {
7143 return data_dir().AppendASCII("permissions_increase");
7144 }
7145 base::FilePath dir_path(const std::string& version) const {
7146 return base_path().AppendASCII("v" + version);
7147 }
7148 base::FilePath pem_path() const {
7149 return base_path().AppendASCII("permissions.pem");
7150 }
7151 };
7152
7153 class MockPermissionRequestCreator : public PermissionRequestCreator {
7154 public:
7155 MockPermissionRequestCreator() {}
7156 ~MockPermissionRequestCreator() override {}
7157
7158 bool IsEnabled() const override { return true; }
7159
7160 void CreateURLAccessRequest(const GURL& url_requested,
7161 const SuccessCallback& callback) override {
7162 FAIL();
7163 }
7164
7165 MOCK_METHOD2(CreateExtensionUpdateRequest,
7166 void(const std::string& id,
7167 const SupervisedUserService::SuccessCallback& callback));
7168
7169 private:
7170 DISALLOW_COPY_AND_ASSIGN(MockPermissionRequestCreator);
7171 };
7172
7173 TEST_F(ExtensionServiceTestSupervised, InstallOnlyAllowedByCustodian) {
7174 InitServices(true /* profile_is_supervised */);
7175
7176 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7177 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7178 const Extension* extensions[] = {
7179 InstallCRX(path1, INSTALL_FAILED),
7180 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7181 };
7182
7183 // Only the extension with the "installed by custodian" flag should have been
7184 // installed and enabled.
7185 EXPECT_FALSE(extensions[0]);
7186 ASSERT_TRUE(extensions[1]);
7187 EXPECT_TRUE(registry()->enabled_extensions().Contains(extensions[1]->id()));
7188 }
7189
7190 TEST_F(ExtensionServiceTestSupervised, PreinstalledExtension) {
7191 InitServices(false /* profile_is_supervised */);
7192
7193 // Install an extension.
7194 base::FilePath path = data_dir().AppendASCII("good.crx");
7195 const Extension* extension = InstallCRX(path, INSTALL_NEW);
7196 std::string id = extension->id();
7197
7198 // Now make the profile supervised.
7199 profile()->AsTestingProfile()->SetSupervisedUserId(
7200 supervised_users::kChildAccountSUID);
7201
7202 // The extension should not be enabled anymore.
7203 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7204 }
7205
7206 TEST_F(ExtensionServiceTestSupervised, UpdateWithoutPermissionIncrease) {
7207 InitServices(true /* profile_is_supervised */);
7208
7209 base::FilePath base_path = data_dir().AppendASCII("autoupdate");
7210 base::FilePath pem_path = base_path.AppendASCII("key.pem");
7211
7212 const Extension* extension =
7213 PackAndInstallCRX(base_path.AppendASCII("v1"), pem_path, INSTALL_NEW,
7214 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7215 // The extension must now be installed and enabled.
7216 ASSERT_TRUE(extension);
7217 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7218
7219 // Save the id, as the extension object will be destroyed during updating.
7220 std::string id = extension->id();
7221
7222 std::string old_version = extension->VersionString();
7223
7224 // Update to a new version.
7225 PackCRXAndUpdateExtension(id, base_path.AppendASCII("v2"), pem_path, ENABLED);
7226
7227 // The extension should still be there and enabled.
7228 extension = registry()->enabled_extensions().GetByID(id);
7229 ASSERT_TRUE(extension);
7230 // The version should have changed.
7231 EXPECT_NE(extension->VersionString(), old_version);
7232 }
7233
7234 TEST_F(ExtensionServiceTestSupervised, UpdateWithPermissionIncreaseNoApproval) {
7235 // Explicitly disable the "need custodian approval" field trial.
7236 base::FieldTrialList field_trial_list(new base::MockEntropyProvider());
7237 base::FieldTrialList::CreateFieldTrial(
7238 "SupervisedUserExtensionPermissionIncrease", "");
7239
7240 InitServices(true /* profile_is_supervised */);
7241
7242 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
7243 supervised_user_service()->AddPermissionRequestCreator(
7244 make_scoped_ptr(creator));
7245
7246 std::string id = InstallPermissionsTestExtension();
7247
7248 // Update to a new version with increased permissions.
7249 // Since we don't require the custodian's approval, no permission request
7250 // should be created.
7251 const std::string version2("2");
7252 EXPECT_CALL(*creator, CreateExtensionUpdateRequest(
7253 UpdateRequestId(id, version2), testing::_))
7254 .Times(0);
7255 UpdatePermissionsTestExtension(id, version2, DISABLED);
7256 }
7257
7258 TEST_F(ExtensionServiceTestSupervised,
7259 UpdateWithPermissionIncreaseApprovalOldVersion) {
7260 // Explicitly enable the "need custodian approval" field trial.
7261 base::FieldTrialList field_trial_list(new base::MockEntropyProvider());
7262 base::FieldTrialList::CreateFieldTrial(
7263 "SupervisedUserExtensionPermissionIncrease", "NeedCustodianApproval");
7264
7265 InitServices(true /* profile_is_supervised */);
7266
7267 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
7268 supervised_user_service()->AddPermissionRequestCreator(
7269 make_scoped_ptr(creator));
7270
7271 const std::string version1("1");
7272 const std::string version2("2");
7273
7274 std::string id = InstallPermissionsTestExtension();
7275
7276 // Update to a new version with increased permissions.
7277 EXPECT_CALL(*creator, CreateExtensionUpdateRequest(
7278 UpdateRequestId(id, version2), testing::_));
7279 UpdatePermissionsTestExtension(id, version2, DISABLED);
7280
7281 // Simulate a custodian approval for re-enabling the extension coming in
7282 // through Sync, but set the old version. This can happen when there already
7283 // was a pending request for an earlier version of the extension.
7284 sync_pb::EntitySpecifics specifics;
7285 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
7286 ext_specifics->set_id(id);
7287 ext_specifics->set_enabled(true);
7288 ext_specifics->set_disable_reasons(Extension::DISABLE_NONE);
7289 ext_specifics->set_installed_by_custodian(true);
7290 ext_specifics->set_version(version1);
7291
7292 // Attempting to re-enable an old version should result in a permission
7293 // request for the current version.
7294 EXPECT_CALL(*creator, CreateExtensionUpdateRequest(
7295 UpdateRequestId(id, version2), testing::_));
7296
7297 syncer::SyncData sync_data =
7298 syncer::SyncData::CreateLocalData(id, "Name", specifics);
7299 syncer::SyncChange sync_change(FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
7300 sync_data);
7301 syncer::SyncChangeList change_list(1, sync_change);
7302 extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
7303 // The re-enable should be ignored, since the version doesn't match.
7304 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7305 EXPECT_FALSE(extension_sync_service()->HasPendingReenable(
7306 id, base::Version(version1)));
7307 EXPECT_FALSE(extension_sync_service()->HasPendingReenable(
7308 id, base::Version(version2)));
7309 }
7310
7311 TEST_F(ExtensionServiceTestSupervised,
7312 UpdateWithPermissionIncreaseApprovalMatchingVersion) {
7313 // Explicitly enable the "need custodian approval" field trial.
7314 base::FieldTrialList field_trial_list(new base::MockEntropyProvider());
7315 base::FieldTrialList::CreateFieldTrial(
7316 "SupervisedUserExtensionPermissionIncrease", "NeedCustodianApproval");
7317
7318 InitServices(true /* profile_is_supervised */);
7319
7320 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
7321 supervised_user_service()->AddPermissionRequestCreator(
7322 make_scoped_ptr(creator));
7323
7324 std::string id = InstallPermissionsTestExtension();
7325
7326 // Update to a new version with increased permissions.
7327 const std::string version2("2");
7328 EXPECT_CALL(*creator, CreateExtensionUpdateRequest(
7329 UpdateRequestId(id, version2), testing::_));
7330 UpdatePermissionsTestExtension(id, version2, DISABLED);
7331
7332 // Simulate a custodian approval for re-enabling the extension coming in
7333 // through Sync.
7334 sync_pb::EntitySpecifics specifics;
7335 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
7336 ext_specifics->set_id(id);
7337 ext_specifics->set_enabled(true);
7338 ext_specifics->set_disable_reasons(Extension::DISABLE_NONE);
7339 ext_specifics->set_installed_by_custodian(true);
7340 ext_specifics->set_version(version2);
7341
7342 syncer::SyncData sync_data =
7343 syncer::SyncData::CreateLocalData(id, "Name", specifics);
7344 syncer::SyncChange sync_change(FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
7345 sync_data);
7346 syncer::SyncChangeList change_list(1, sync_change);
7347 extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
7348 // The extension should have gotten re-enabled.
7349 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
7350 }
7351
7352 TEST_F(ExtensionServiceTestSupervised,
7353 UpdateWithPermissionIncreaseApprovalNewVersion) {
7354 // Explicitly enable the "need custodian approval" field trial.
7355 base::FieldTrialList field_trial_list(new base::MockEntropyProvider());
7356 base::FieldTrialList::CreateFieldTrial(
7357 "SupervisedUserExtensionPermissionIncrease", "NeedCustodianApproval");
7358
7359 InitServices(true /* profile_is_supervised */);
7360
7361 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
7362 supervised_user_service()->AddPermissionRequestCreator(
7363 make_scoped_ptr(creator));
7364
7365 std::string id = InstallPermissionsTestExtension();
7366
7367 // Update to a new version with increased permissions.
7368 const std::string version2("2");
7369 EXPECT_CALL(*creator, CreateExtensionUpdateRequest(
7370 UpdateRequestId(id, version2), testing::_));
7371 UpdatePermissionsTestExtension(id, version2, DISABLED);
7372
7373 // Simulate a custodian approval for re-enabling the extension coming in
7374 // through Sync. Set a newer version than we have installed.
7375 const std::string version3("3");
7376 sync_pb::EntitySpecifics specifics;
7377 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
7378 ext_specifics->set_id(id);
7379 ext_specifics->set_enabled(true);
7380 ext_specifics->set_disable_reasons(Extension::DISABLE_NONE);
7381 ext_specifics->set_installed_by_custodian(true);
7382 ext_specifics->set_version(version3);
7383
7384 // This should *not* result in a new permission request.
7385 EXPECT_CALL(*creator, CreateExtensionUpdateRequest(
7386 UpdateRequestId(id, version3), testing::_))
7387 .Times(0);
7388
7389 syncer::SyncData sync_data =
7390 syncer::SyncData::CreateLocalData(id, "Name", specifics);
7391 syncer::SyncChange sync_change(FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
7392 sync_data);
7393 syncer::SyncChangeList change_list(1, sync_change);
7394 extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
7395 // The re-enable should be delayed until the extension is updated to the
7396 // matching version.
7397 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7398 EXPECT_TRUE(extension_sync_service()->HasPendingReenable(
7399 id, base::Version(version3)));
7400
7401 // Update to the matching version. Now the extension should get enabled.
7402 UpdatePermissionsTestExtension(id, version3, ENABLED);
7403 }
7404
7405 TEST_F(ExtensionServiceTest, SyncUninstallByCustodianSkipsPolicy) {
7406 InitializeEmptyExtensionService();
7407 extension_sync_service()->MergeDataAndStartSyncing(
7408 syncer::EXTENSIONS,
7409 syncer::SyncDataList(),
7410 scoped_ptr<syncer::SyncChangeProcessor>(
7411 new syncer::FakeSyncChangeProcessor),
7412 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
7413
7414 // Install two extensions.
7415 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7416 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7417 const Extension* extensions[] = {
7418 InstallCRX(path1, INSTALL_NEW),
7419 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7420 };
7421
7422 // Add a policy provider that will disallow any changes.
7423 extensions::TestManagementPolicyProvider provider(
7424 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
7425 GetManagementPolicy()->RegisterProvider(&provider);
7426
7427 // Create a sync deletion for each extension.
7428 syncer::SyncChangeList change_list;
7429 for (size_t i = 0; i < arraysize(extensions); i++) {
7430 const std::string& id = extensions[i]->id();
7431 sync_pb::EntitySpecifics specifics;
7432 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
7433 ext_specifics->set_id(id);
7434 ext_specifics->set_version("1.0");
7435 ext_specifics->set_installed_by_custodian(
7436 extensions[i]->was_installed_by_custodian());
7437 syncer::SyncData sync_data =
7438 syncer::SyncData::CreateLocalData(id, "Name", specifics);
7439 change_list.push_back(syncer::SyncChange(FROM_HERE,
7440 syncer::SyncChange::ACTION_DELETE,
7441 sync_data));
7442 }
7443
7444 // Save the extension ids, as uninstalling destroys the Extension instance.
7445 std::string extension_ids[] = {
7446 extensions[0]->id(),
7447 extensions[1]->id()
7448 };
7449
7450 // Now apply the uninstallations.
7451 extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
7452
7453 // Uninstalling the extension without installed_by_custodian should have been
7454 // blocked by policy, so it should still be there.
7455 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_ids[0]));
7456
7457 // But installed_by_custodian should result in bypassing the policy check.
7458 EXPECT_FALSE(
7459 registry()->GenerateInstalledExtensionsSet()->Contains(extension_ids[1]));
7460 }
7461 #endif // defined(ENABLE_SUPERVISED_USERS)
7462
7463 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) { 5257 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
7464 InitializeEmptyExtensionService(); 5258 InitializeEmptyExtensionService();
7465 5259
7466 base::FilePath path = data_dir().AppendASCII("good.crx"); 5260 base::FilePath path = data_dir().AppendASCII("good.crx");
7467 InstallCRX(path, INSTALL_NEW); 5261 InstallCRX(path, INSTALL_NEW);
7468 ValidatePrefKeyCount(1u); 5262 ValidatePrefKeyCount(1u);
7469 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 5263 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7470 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL); 5264 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7471 5265
7472 extensions::PendingExtensionManager* pending = 5266 extensions::PendingExtensionManager* pending =
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
8376 6170
8377 service()->Observe(chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED, 6171 service()->Observe(chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
8378 content::Source<Profile>(profile()), 6172 content::Source<Profile>(profile()),
8379 content::NotificationService::NoDetails()); 6173 content::NotificationService::NoDetails());
8380 EXPECT_EQ(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_); 6174 EXPECT_EQ(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8381 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 6175 EXPECT_EQ(0u, registry()->enabled_extensions().size());
8382 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 6176 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8383 EXPECT_EQ(0u, registry()->terminated_extensions().size()); 6177 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8384 EXPECT_EQ(0u, registry()->blacklisted_extensions().size()); 6178 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
8385 } 6179 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698