| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/json/json_file_value_serializer.h" | 5 #include "base/json/json_file_value_serializer.h" |
| 6 #include "base/json/json_writer.h" | 6 #include "base/json/json_writer.h" |
| 7 #include "base/strings/string_util.h" | 7 #include "base/strings/string_util.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/browser/extensions/api/developer_private/extension_info_generat
or.h" | 9 #include "chrome/browser/extensions/api/developer_private/extension_info_generat
or.h" |
| 10 #include "chrome/browser/extensions/api/developer_private/inspectable_views_find
er.h" | 10 #include "chrome/browser/extensions/api/developer_private/inspectable_views_find
er.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 public: | 48 public: |
| 49 ExtensionInfoGeneratorUnitTest() {} | 49 ExtensionInfoGeneratorUnitTest() {} |
| 50 ~ExtensionInfoGeneratorUnitTest() override {} | 50 ~ExtensionInfoGeneratorUnitTest() override {} |
| 51 | 51 |
| 52 protected: | 52 protected: |
| 53 void SetUp() override { | 53 void SetUp() override { |
| 54 ExtensionServiceTestBase::SetUp(); | 54 ExtensionServiceTestBase::SetUp(); |
| 55 InitializeEmptyExtensionService(); | 55 InitializeEmptyExtensionService(); |
| 56 } | 56 } |
| 57 | 57 |
| 58 void OnInfosGenerated(linked_ptr<developer::ExtensionInfo>* info_out, |
| 59 const ExtensionInfoGenerator::ExtensionInfoList& list) { |
| 60 EXPECT_EQ(1u, list.size()); |
| 61 if (!list.empty()) |
| 62 *info_out = list[0]; |
| 63 quit_closure_.Run(); |
| 64 quit_closure_.Reset(); |
| 65 } |
| 66 |
| 67 scoped_ptr<developer::ExtensionInfo> GenerateExtensionInfo( |
| 68 const std::string& extension_id) { |
| 69 linked_ptr<developer::ExtensionInfo> info; |
| 70 base::RunLoop run_loop; |
| 71 quit_closure_ = run_loop.QuitClosure(); |
| 72 scoped_ptr<ExtensionInfoGenerator> generator( |
| 73 new ExtensionInfoGenerator(browser_context())); |
| 74 generator->CreateExtensionInfo( |
| 75 extension_id, |
| 76 base::Bind(&ExtensionInfoGeneratorUnitTest::OnInfosGenerated, |
| 77 base::Unretained(this), |
| 78 base::Unretained(&info))); |
| 79 run_loop.Run(); |
| 80 return make_scoped_ptr(info.release()); |
| 81 } |
| 82 |
| 58 const scoped_refptr<const Extension> CreateExtension( | 83 const scoped_refptr<const Extension> CreateExtension( |
| 59 const std::string& name, | 84 const std::string& name, |
| 60 ListBuilder& permissions) { | 85 ListBuilder& permissions) { |
| 61 const std::string kId = crx_file::id_util::GenerateId(name); | 86 const std::string kId = crx_file::id_util::GenerateId(name); |
| 62 scoped_refptr<const Extension> extension = | 87 scoped_refptr<const Extension> extension = |
| 63 ExtensionBuilder().SetManifest( | 88 ExtensionBuilder().SetManifest( |
| 64 DictionaryBuilder() | 89 DictionaryBuilder() |
| 65 .Set("name", name) | 90 .Set("name", name) |
| 66 .Set("description", "an extension") | 91 .Set("description", "an extension") |
| 67 .Set("manifest_version", 2) | 92 .Set("manifest_version", 2) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 83 | 108 |
| 84 base::FilePath manifest_path = extension_path.Append(kManifestFilename); | 109 base::FilePath manifest_path = extension_path.Append(kManifestFilename); |
| 85 scoped_ptr<base::DictionaryValue> extension_data = | 110 scoped_ptr<base::DictionaryValue> extension_data = |
| 86 DeserializeJSONTestData(manifest_path, &error); | 111 DeserializeJSONTestData(manifest_path, &error); |
| 87 EXPECT_EQ(std::string(), error); | 112 EXPECT_EQ(std::string(), error); |
| 88 | 113 |
| 89 scoped_refptr<Extension> extension(Extension::Create( | 114 scoped_refptr<Extension> extension(Extension::Create( |
| 90 extension_path, location, *extension_data, Extension::REQUIRE_KEY, | 115 extension_path, location, *extension_data, Extension::REQUIRE_KEY, |
| 91 &error)); | 116 &error)); |
| 92 CHECK(extension.get()); | 117 CHECK(extension.get()); |
| 118 service()->AddExtension(extension.get()); |
| 93 EXPECT_EQ(std::string(), error); | 119 EXPECT_EQ(std::string(), error); |
| 94 | 120 |
| 95 return ExtensionInfoGenerator(browser_context()).CreateExtensionInfo( | 121 return GenerateExtensionInfo(extension->id()); |
| 96 *extension, | |
| 97 api::developer_private::EXTENSION_STATE_ENABLED); | |
| 98 } | 122 } |
| 99 | 123 |
| 100 void CompareExpectedAndActualOutput( | 124 void CompareExpectedAndActualOutput( |
| 101 const base::FilePath& extension_path, | 125 const base::FilePath& extension_path, |
| 102 const InspectableViewsFinder::ViewList& views, | 126 const InspectableViewsFinder::ViewList& views, |
| 103 const base::FilePath& expected_output_path) { | 127 const base::FilePath& expected_output_path) { |
| 104 std::string error; | 128 std::string error; |
| 105 scoped_ptr<base::DictionaryValue> expected_output_data( | 129 scoped_ptr<base::DictionaryValue> expected_output_data( |
| 106 DeserializeJSONTestData(expected_output_path, &error)); | 130 DeserializeJSONTestData(expected_output_path, &error)); |
| 107 EXPECT_EQ(std::string(), error); | 131 EXPECT_EQ(std::string(), error); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 129 if (!actual_value) | 153 if (!actual_value) |
| 130 continue; | 154 continue; |
| 131 if (!actual_value->Equals(expected_value)) { | 155 if (!actual_value->Equals(expected_value)) { |
| 132 base::JSONWriter::Write(expected_value, &expected_string); | 156 base::JSONWriter::Write(expected_value, &expected_string); |
| 133 base::JSONWriter::Write(actual_value, &actual_string); | 157 base::JSONWriter::Write(actual_value, &actual_string); |
| 134 EXPECT_EQ(expected_string, actual_string) << | 158 EXPECT_EQ(expected_string, actual_string) << |
| 135 field.key() << paths_details; | 159 field.key() << paths_details; |
| 136 } | 160 } |
| 137 } | 161 } |
| 138 } | 162 } |
| 163 |
| 164 private: |
| 165 base::Closure quit_closure_; |
| 166 |
| 167 DISALLOW_COPY_AND_ASSIGN(ExtensionInfoGeneratorUnitTest); |
| 139 }; | 168 }; |
| 140 | 169 |
| 141 // Test some of the basic fields. | 170 // Test some of the basic fields. |
| 142 TEST_F(ExtensionInfoGeneratorUnitTest, BasicInfoTest) { | 171 TEST_F(ExtensionInfoGeneratorUnitTest, BasicInfoTest) { |
| 143 // Enable error console for testing. | 172 // Enable error console for testing. |
| 144 ResetThreadBundle(content::TestBrowserThreadBundle::DEFAULT); | 173 ResetThreadBundle(content::TestBrowserThreadBundle::DEFAULT); |
| 145 FeatureSwitch::ScopedOverride error_console_override( | 174 FeatureSwitch::ScopedOverride error_console_override( |
| 146 FeatureSwitch::error_console(), true); | 175 FeatureSwitch::error_console(), true); |
| 147 profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true); | 176 profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true); |
| 148 | 177 |
| 149 const char kName[] = "extension name"; | 178 const char kName[] = "extension name"; |
| 150 const char kVersion[] = "1.0.0.1"; | 179 const char kVersion[] = "1.0.0.1"; |
| 151 std::string id = crx_file::id_util::GenerateId(kName); | 180 std::string id = crx_file::id_util::GenerateId("alpha"); |
| 152 scoped_ptr<base::DictionaryValue> manifest = | 181 scoped_ptr<base::DictionaryValue> manifest = |
| 153 DictionaryBuilder().Set("name", kName) | 182 DictionaryBuilder().Set("name", kName) |
| 154 .Set("version", kVersion) | 183 .Set("version", kVersion) |
| 155 .Set("manifest_version", 2) | 184 .Set("manifest_version", 2) |
| 156 .Set("description", "an extension") | 185 .Set("description", "an extension") |
| 157 .Set("permissions", | 186 .Set("permissions", |
| 158 ListBuilder().Append("file://*/*")).Build(); | 187 ListBuilder().Append("file://*/*")).Build(); |
| 159 scoped_ptr<base::DictionaryValue> manifest_copy(manifest->DeepCopy()); | 188 scoped_ptr<base::DictionaryValue> manifest_copy(manifest->DeepCopy()); |
| 160 scoped_refptr<const Extension> extension = | 189 scoped_refptr<const Extension> extension = |
| 161 ExtensionBuilder().SetManifest(manifest.Pass()) | 190 ExtensionBuilder().SetManifest(manifest.Pass()) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 base::UTF8ToUTF16("function"))), | 225 base::UTF8ToUTF16("function"))), |
| 197 GURL("url"), | 226 GURL("url"), |
| 198 logging::LOG_VERBOSE, | 227 logging::LOG_VERBOSE, |
| 199 1, | 228 1, |
| 200 1))); | 229 1))); |
| 201 | 230 |
| 202 // It's not feasible to validate every field here, because that would be | 231 // It's not feasible to validate every field here, because that would be |
| 203 // a duplication of the logic in the method itself. Instead, test a handful | 232 // a duplication of the logic in the method itself. Instead, test a handful |
| 204 // of fields for sanity. | 233 // of fields for sanity. |
| 205 scoped_ptr<api::developer_private::ExtensionInfo> info = | 234 scoped_ptr<api::developer_private::ExtensionInfo> info = |
| 206 ExtensionInfoGenerator(browser_context()).CreateExtensionInfo( | 235 GenerateExtensionInfo(extension->id()); |
| 207 *extension, developer::EXTENSION_STATE_ENABLED); | 236 ASSERT_TRUE(info.get()); |
| 208 ASSERT_TRUE(info); | |
| 209 EXPECT_EQ(kName, info->name); | 237 EXPECT_EQ(kName, info->name); |
| 210 EXPECT_EQ(id, info->id); | 238 EXPECT_EQ(id, info->id); |
| 211 EXPECT_EQ(kVersion, info->version); | 239 EXPECT_EQ(kVersion, info->version); |
| 212 EXPECT_EQ(info->location, developer::LOCATION_UNPACKED); | 240 EXPECT_EQ(info->location, developer::LOCATION_UNPACKED); |
| 213 ASSERT_TRUE(info->path); | 241 ASSERT_TRUE(info->path); |
| 214 EXPECT_EQ(data_dir(), base::FilePath::FromUTF8Unsafe(*info->path)); | 242 EXPECT_EQ(data_dir(), base::FilePath::FromUTF8Unsafe(*info->path)); |
| 215 EXPECT_EQ(api::developer_private::EXTENSION_STATE_ENABLED, info->state); | 243 EXPECT_EQ(api::developer_private::EXTENSION_STATE_ENABLED, info->state); |
| 216 EXPECT_EQ(api::developer_private::EXTENSION_TYPE_EXTENSION, info->type); | 244 EXPECT_EQ(api::developer_private::EXTENSION_TYPE_EXTENSION, info->type); |
| 217 EXPECT_TRUE(info->file_access.is_enabled); | 245 EXPECT_TRUE(info->file_access.is_enabled); |
| 218 EXPECT_FALSE(info->file_access.is_active); | 246 EXPECT_FALSE(info->file_access.is_active); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 231 *info->runtime_errors[1]; | 259 *info->runtime_errors[1]; |
| 232 EXPECT_EQ(api::developer_private::ERROR_LEVEL_LOG, | 260 EXPECT_EQ(api::developer_private::ERROR_LEVEL_LOG, |
| 233 runtime_error_verbose.severity); | 261 runtime_error_verbose.severity); |
| 234 const api::developer_private::ManifestError& manifest_error = | 262 const api::developer_private::ManifestError& manifest_error = |
| 235 *info->manifest_errors[0]; | 263 *info->manifest_errors[0]; |
| 236 EXPECT_EQ(extension->id(), manifest_error.extension_id); | 264 EXPECT_EQ(extension->id(), manifest_error.extension_id); |
| 237 | 265 |
| 238 // Test an extension that isn't unpacked. | 266 // Test an extension that isn't unpacked. |
| 239 manifest_copy->SetString("update_url", | 267 manifest_copy->SetString("update_url", |
| 240 "https://clients2.google.com/service/update2/crx"); | 268 "https://clients2.google.com/service/update2/crx"); |
| 269 id = crx_file::id_util::GenerateId("beta"); |
| 241 extension = ExtensionBuilder().SetManifest(manifest_copy.Pass()) | 270 extension = ExtensionBuilder().SetManifest(manifest_copy.Pass()) |
| 242 .SetLocation(Manifest::EXTERNAL_PREF) | 271 .SetLocation(Manifest::EXTERNAL_PREF) |
| 243 .SetID(id) | 272 .SetID(id) |
| 244 .Build(); | 273 .Build(); |
| 245 info = ExtensionInfoGenerator(browser_context()).CreateExtensionInfo( | 274 service()->AddExtension(extension.get()); |
| 246 *extension, developer::EXTENSION_STATE_ENABLED); | 275 info = GenerateExtensionInfo(extension->id()); |
| 247 EXPECT_EQ(developer::LOCATION_THIRD_PARTY, info->location); | 276 EXPECT_EQ(developer::LOCATION_THIRD_PARTY, info->location); |
| 248 EXPECT_FALSE(info->path); | 277 EXPECT_FALSE(info->path); |
| 249 } | 278 } |
| 250 | 279 |
| 251 // Test three generated json outputs. | 280 // Test three generated json outputs. |
| 252 TEST_F(ExtensionInfoGeneratorUnitTest, GenerateExtensionsJSONData) { | 281 TEST_F(ExtensionInfoGeneratorUnitTest, GenerateExtensionsJSONData) { |
| 253 // Test Extension1 | 282 // Test Extension1 |
| 254 base::FilePath extension_path = | 283 base::FilePath extension_path = |
| 255 data_dir().AppendASCII("good") | 284 data_dir().AppendASCII("good") |
| 256 .AppendASCII("Extensions") | 285 .AppendASCII("Extensions") |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // Start with the switch enabled. | 344 // Start with the switch enabled. |
| 316 scoped_ptr<FeatureSwitch::ScopedOverride> enable_scripts_switch( | 345 scoped_ptr<FeatureSwitch::ScopedOverride> enable_scripts_switch( |
| 317 new FeatureSwitch::ScopedOverride( | 346 new FeatureSwitch::ScopedOverride( |
| 318 FeatureSwitch::scripts_require_action(), true)); | 347 FeatureSwitch::scripts_require_action(), true)); |
| 319 // Two extensions - one with all urls, one without. | 348 // Two extensions - one with all urls, one without. |
| 320 scoped_refptr<const Extension> all_urls_extension = CreateExtension( | 349 scoped_refptr<const Extension> all_urls_extension = CreateExtension( |
| 321 "all_urls", ListBuilder().Append(kAllHostsPermission).Pass()); | 350 "all_urls", ListBuilder().Append(kAllHostsPermission).Pass()); |
| 322 scoped_refptr<const Extension> no_urls_extension = | 351 scoped_refptr<const Extension> no_urls_extension = |
| 323 CreateExtension("no urls", ListBuilder().Pass()); | 352 CreateExtension("no urls", ListBuilder().Pass()); |
| 324 | 353 |
| 325 ExtensionInfoGenerator generator(browser_context()); | |
| 326 scoped_ptr<developer::ExtensionInfo> info = | 354 scoped_ptr<developer::ExtensionInfo> info = |
| 327 generator.CreateExtensionInfo( | 355 GenerateExtensionInfo(all_urls_extension->id()); |
| 328 *all_urls_extension, | |
| 329 api::developer_private::EXTENSION_STATE_ENABLED); | |
| 330 | 356 |
| 331 // The extension should want all urls, but not currently have it. | 357 // The extension should want all urls, but not currently have it. |
| 332 EXPECT_TRUE(info->run_on_all_urls.is_enabled); | 358 EXPECT_TRUE(info->run_on_all_urls.is_enabled); |
| 333 EXPECT_FALSE(info->run_on_all_urls.is_active); | 359 EXPECT_FALSE(info->run_on_all_urls.is_active); |
| 334 | 360 |
| 335 // Give the extension all urls. | 361 // Give the extension all urls. |
| 336 util::SetAllowedScriptingOnAllUrls(all_urls_extension->id(), profile(), true); | 362 util::SetAllowedScriptingOnAllUrls(all_urls_extension->id(), profile(), true); |
| 337 | 363 |
| 338 // Now the extension should both want and have all urls. | 364 // Now the extension should both want and have all urls. |
| 339 info = generator.CreateExtensionInfo(*all_urls_extension, | 365 info = GenerateExtensionInfo(all_urls_extension->id()); |
| 340 developer::EXTENSION_STATE_ENABLED); | |
| 341 EXPECT_TRUE(info->run_on_all_urls.is_enabled); | 366 EXPECT_TRUE(info->run_on_all_urls.is_enabled); |
| 342 EXPECT_TRUE(info->run_on_all_urls.is_active); | 367 EXPECT_TRUE(info->run_on_all_urls.is_active); |
| 343 | 368 |
| 344 // The other extension should neither want nor have all urls. | 369 // The other extension should neither want nor have all urls. |
| 345 info = generator.CreateExtensionInfo(*no_urls_extension, | 370 info = GenerateExtensionInfo(no_urls_extension->id()); |
| 346 developer::EXTENSION_STATE_ENABLED); | |
| 347 EXPECT_FALSE(info->run_on_all_urls.is_enabled); | 371 EXPECT_FALSE(info->run_on_all_urls.is_enabled); |
| 348 EXPECT_FALSE(info->run_on_all_urls.is_active); | 372 EXPECT_FALSE(info->run_on_all_urls.is_active); |
| 349 | 373 |
| 350 // Revoke the first extension's permissions. | 374 // Revoke the first extension's permissions. |
| 351 util::SetAllowedScriptingOnAllUrls( | 375 util::SetAllowedScriptingOnAllUrls( |
| 352 all_urls_extension->id(), profile(), false); | 376 all_urls_extension->id(), profile(), false); |
| 353 | 377 |
| 354 // Turn off the switch and load another extension (so permissions are | 378 // Turn off the switch and load another extension (so permissions are |
| 355 // re-initialized). | 379 // re-initialized). |
| 356 enable_scripts_switch.reset(); | 380 enable_scripts_switch.reset(); |
| 357 | 381 |
| 358 // Since the extension doesn't have access to all urls (but normally would), | 382 // Since the extension doesn't have access to all urls (but normally would), |
| 359 // the extension should have the "want" flag even with the switch off. | 383 // the extension should have the "want" flag even with the switch off. |
| 360 info = generator.CreateExtensionInfo(*all_urls_extension, | 384 info = GenerateExtensionInfo(all_urls_extension->id()); |
| 361 developer::EXTENSION_STATE_ENABLED); | |
| 362 EXPECT_TRUE(info->run_on_all_urls.is_enabled); | 385 EXPECT_TRUE(info->run_on_all_urls.is_enabled); |
| 363 EXPECT_FALSE(info->run_on_all_urls.is_active); | 386 EXPECT_FALSE(info->run_on_all_urls.is_active); |
| 364 | 387 |
| 365 // If we grant the extension all urls, then the checkbox should still be | 388 // If we grant the extension all urls, then the checkbox should still be |
| 366 // there, since it has an explicitly-set user preference. | 389 // there, since it has an explicitly-set user preference. |
| 367 util::SetAllowedScriptingOnAllUrls(all_urls_extension->id(), profile(), true); | 390 util::SetAllowedScriptingOnAllUrls(all_urls_extension->id(), profile(), true); |
| 368 info = generator.CreateExtensionInfo(*all_urls_extension, | 391 info = GenerateExtensionInfo(all_urls_extension->id()); |
| 369 developer::EXTENSION_STATE_ENABLED); | |
| 370 EXPECT_TRUE(info->run_on_all_urls.is_enabled); | 392 EXPECT_TRUE(info->run_on_all_urls.is_enabled); |
| 371 EXPECT_TRUE(info->run_on_all_urls.is_active); | 393 EXPECT_TRUE(info->run_on_all_urls.is_active); |
| 372 | 394 |
| 373 // Load another extension with all urls (so permissions get re-init'd). | 395 // Load another extension with all urls (so permissions get re-init'd). |
| 374 all_urls_extension = CreateExtension( | 396 all_urls_extension = CreateExtension( |
| 375 "all_urls_II", ListBuilder().Append(kAllHostsPermission).Pass()); | 397 "all_urls_II", ListBuilder().Append(kAllHostsPermission).Pass()); |
| 376 | 398 |
| 377 // Even though the extension has all_urls permission, the checkbox shouldn't | 399 // Even though the extension has all_urls permission, the checkbox shouldn't |
| 378 // show up without the switch. | 400 // show up without the switch. |
| 379 info = generator.CreateExtensionInfo(*all_urls_extension, | 401 info = GenerateExtensionInfo(all_urls_extension->id()); |
| 380 developer::EXTENSION_STATE_ENABLED); | |
| 381 EXPECT_FALSE(info->run_on_all_urls.is_enabled); | 402 EXPECT_FALSE(info->run_on_all_urls.is_enabled); |
| 382 EXPECT_TRUE(info->run_on_all_urls.is_active); | 403 EXPECT_TRUE(info->run_on_all_urls.is_active); |
| 383 } | 404 } |
| 384 | 405 |
| 385 } // namespace extensions | 406 } // namespace extensions |
| OLD | NEW |