| 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 <utility> | 5 #include <utility> |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" |
| 7 #include "base/json/json_file_value_serializer.h" | 8 #include "base/json/json_file_value_serializer.h" |
| 8 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 9 #include "base/macros.h" | 10 #include "base/macros.h" |
| 10 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 12 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 13 #include "chrome/browser/extensions/api/developer_private/extension_info_generat
or.h" | 14 #include "chrome/browser/extensions/api/developer_private/extension_info_generat
or.h" |
| 14 #include "chrome/browser/extensions/api/developer_private/inspectable_views_find
er.h" | 15 #include "chrome/browser/extensions/api/developer_private/inspectable_views_find
er.h" |
| 15 #include "chrome/browser/extensions/error_console/error_console.h" | 16 #include "chrome/browser/extensions/error_console/error_console.h" |
| 16 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 public: | 51 public: |
| 51 ExtensionInfoGeneratorUnitTest() {} | 52 ExtensionInfoGeneratorUnitTest() {} |
| 52 ~ExtensionInfoGeneratorUnitTest() override {} | 53 ~ExtensionInfoGeneratorUnitTest() override {} |
| 53 | 54 |
| 54 protected: | 55 protected: |
| 55 void SetUp() override { | 56 void SetUp() override { |
| 56 ExtensionServiceTestBase::SetUp(); | 57 ExtensionServiceTestBase::SetUp(); |
| 57 InitializeEmptyExtensionService(); | 58 InitializeEmptyExtensionService(); |
| 58 } | 59 } |
| 59 | 60 |
| 60 void OnInfosGenerated(linked_ptr<developer::ExtensionInfo>* info_out, | 61 void OnInfosGenerated(scoped_ptr<developer::ExtensionInfo>* info_out, |
| 61 const ExtensionInfoGenerator::ExtensionInfoList& list) { | 62 ExtensionInfoGenerator::ExtensionInfoList list) { |
| 62 EXPECT_EQ(1u, list.size()); | 63 EXPECT_EQ(1u, list.size()); |
| 63 if (!list.empty()) | 64 if (!list.empty()) |
| 64 *info_out = list[0]; | 65 info_out->reset(new developer::ExtensionInfo(std::move(list[0]))); |
| 65 quit_closure_.Run(); | 66 base::ResetAndReturn(&quit_closure_).Run(); |
| 66 quit_closure_.Reset(); | |
| 67 } | 67 } |
| 68 | 68 |
| 69 scoped_ptr<developer::ExtensionInfo> GenerateExtensionInfo( | 69 scoped_ptr<developer::ExtensionInfo> GenerateExtensionInfo( |
| 70 const std::string& extension_id) { | 70 const std::string& extension_id) { |
| 71 linked_ptr<developer::ExtensionInfo> info; | 71 scoped_ptr<developer::ExtensionInfo> info; |
| 72 base::RunLoop run_loop; | 72 base::RunLoop run_loop; |
| 73 quit_closure_ = run_loop.QuitClosure(); | 73 quit_closure_ = run_loop.QuitClosure(); |
| 74 scoped_ptr<ExtensionInfoGenerator> generator( | 74 scoped_ptr<ExtensionInfoGenerator> generator( |
| 75 new ExtensionInfoGenerator(browser_context())); | 75 new ExtensionInfoGenerator(browser_context())); |
| 76 generator->CreateExtensionInfo( | 76 generator->CreateExtensionInfo( |
| 77 extension_id, | 77 extension_id, |
| 78 base::Bind(&ExtensionInfoGeneratorUnitTest::OnInfosGenerated, | 78 base::Bind(&ExtensionInfoGeneratorUnitTest::OnInfosGenerated, |
| 79 base::Unretained(this), | 79 base::Unretained(this), |
| 80 base::Unretained(&info))); | 80 base::Unretained(&info))); |
| 81 run_loop.Run(); | 81 run_loop.Run(); |
| 82 return make_scoped_ptr(info.release()); | 82 return info; |
| 83 } | 83 } |
| 84 | 84 |
| 85 const scoped_refptr<const Extension> CreateExtension( | 85 const scoped_refptr<const Extension> CreateExtension( |
| 86 const std::string& name, | 86 const std::string& name, |
| 87 scoped_ptr<base::ListValue> permissions) { | 87 scoped_ptr<base::ListValue> permissions) { |
| 88 const std::string kId = crx_file::id_util::GenerateId(name); | 88 const std::string kId = crx_file::id_util::GenerateId(name); |
| 89 scoped_refptr<const Extension> extension = | 89 scoped_refptr<const Extension> extension = |
| 90 ExtensionBuilder() | 90 ExtensionBuilder() |
| 91 .SetManifest(DictionaryBuilder() | 91 .SetManifest(DictionaryBuilder() |
| 92 .Set("name", name) | 92 .Set("name", name) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 119 &error)); | 119 &error)); |
| 120 CHECK(extension.get()); | 120 CHECK(extension.get()); |
| 121 service()->AddExtension(extension.get()); | 121 service()->AddExtension(extension.get()); |
| 122 EXPECT_EQ(std::string(), error); | 122 EXPECT_EQ(std::string(), error); |
| 123 | 123 |
| 124 return GenerateExtensionInfo(extension->id()); | 124 return GenerateExtensionInfo(extension->id()); |
| 125 } | 125 } |
| 126 | 126 |
| 127 void CompareExpectedAndActualOutput( | 127 void CompareExpectedAndActualOutput( |
| 128 const base::FilePath& extension_path, | 128 const base::FilePath& extension_path, |
| 129 const InspectableViewsFinder::ViewList& views, | 129 InspectableViewsFinder::ViewList views, |
| 130 const base::FilePath& expected_output_path) { | 130 const base::FilePath& expected_output_path) { |
| 131 std::string error; | 131 std::string error; |
| 132 scoped_ptr<base::DictionaryValue> expected_output_data( | 132 scoped_ptr<base::DictionaryValue> expected_output_data( |
| 133 DeserializeJSONTestData(expected_output_path, &error)); | 133 DeserializeJSONTestData(expected_output_path, &error)); |
| 134 EXPECT_EQ(std::string(), error); | 134 EXPECT_EQ(std::string(), error); |
| 135 | 135 |
| 136 // Produce test output. | 136 // Produce test output. |
| 137 scoped_ptr<developer::ExtensionInfo> info = | 137 scoped_ptr<developer::ExtensionInfo> info = |
| 138 CreateExtensionInfoFromPath(extension_path, Manifest::INVALID_LOCATION); | 138 CreateExtensionInfoFromPath(extension_path, Manifest::INVALID_LOCATION); |
| 139 info->views = views; | 139 info->views = std::move(views); |
| 140 scoped_ptr<base::DictionaryValue> actual_output_data = info->ToValue(); | 140 scoped_ptr<base::DictionaryValue> actual_output_data = info->ToValue(); |
| 141 ASSERT_TRUE(actual_output_data); | 141 ASSERT_TRUE(actual_output_data); |
| 142 | 142 |
| 143 // Compare the outputs. | 143 // Compare the outputs. |
| 144 // Ignore unknown fields in the actual output data. | 144 // Ignore unknown fields in the actual output data. |
| 145 std::string paths_details = " - expected (" + | 145 std::string paths_details = " - expected (" + |
| 146 expected_output_path.MaybeAsASCII() + ") vs. actual (" + | 146 expected_output_path.MaybeAsASCII() + ") vs. actual (" + |
| 147 extension_path.MaybeAsASCII() + ")"; | 147 extension_path.MaybeAsASCII() + ")"; |
| 148 std::string expected_string; | 148 std::string expected_string; |
| 149 std::string actual_string; | 149 std::string actual_string; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 ASSERT_TRUE(info->path); | 246 ASSERT_TRUE(info->path); |
| 247 EXPECT_EQ(data_dir(), base::FilePath::FromUTF8Unsafe(*info->path)); | 247 EXPECT_EQ(data_dir(), base::FilePath::FromUTF8Unsafe(*info->path)); |
| 248 EXPECT_EQ(api::developer_private::EXTENSION_STATE_ENABLED, info->state); | 248 EXPECT_EQ(api::developer_private::EXTENSION_STATE_ENABLED, info->state); |
| 249 EXPECT_EQ(api::developer_private::EXTENSION_TYPE_EXTENSION, info->type); | 249 EXPECT_EQ(api::developer_private::EXTENSION_TYPE_EXTENSION, info->type); |
| 250 EXPECT_TRUE(info->file_access.is_enabled); | 250 EXPECT_TRUE(info->file_access.is_enabled); |
| 251 EXPECT_FALSE(info->file_access.is_active); | 251 EXPECT_FALSE(info->file_access.is_active); |
| 252 EXPECT_TRUE(info->incognito_access.is_enabled); | 252 EXPECT_TRUE(info->incognito_access.is_enabled); |
| 253 EXPECT_FALSE(info->incognito_access.is_active); | 253 EXPECT_FALSE(info->incognito_access.is_active); |
| 254 ASSERT_EQ(2u, info->runtime_errors.size()); | 254 ASSERT_EQ(2u, info->runtime_errors.size()); |
| 255 const api::developer_private::RuntimeError& runtime_error = | 255 const api::developer_private::RuntimeError& runtime_error = |
| 256 *info->runtime_errors[0]; | 256 info->runtime_errors[0]; |
| 257 EXPECT_EQ(extension->id(), runtime_error.extension_id); | 257 EXPECT_EQ(extension->id(), runtime_error.extension_id); |
| 258 EXPECT_EQ(api::developer_private::ERROR_TYPE_RUNTIME, runtime_error.type); | 258 EXPECT_EQ(api::developer_private::ERROR_TYPE_RUNTIME, runtime_error.type); |
| 259 EXPECT_EQ(api::developer_private::ERROR_LEVEL_ERROR, | 259 EXPECT_EQ(api::developer_private::ERROR_LEVEL_ERROR, |
| 260 runtime_error.severity); | 260 runtime_error.severity); |
| 261 EXPECT_EQ(1u, runtime_error.stack_trace.size()); | 261 EXPECT_EQ(1u, runtime_error.stack_trace.size()); |
| 262 ASSERT_EQ(1u, info->manifest_errors.size()); | 262 ASSERT_EQ(1u, info->manifest_errors.size()); |
| 263 const api::developer_private::RuntimeError& runtime_error_verbose = | 263 const api::developer_private::RuntimeError& runtime_error_verbose = |
| 264 *info->runtime_errors[1]; | 264 info->runtime_errors[1]; |
| 265 EXPECT_EQ(api::developer_private::ERROR_LEVEL_LOG, | 265 EXPECT_EQ(api::developer_private::ERROR_LEVEL_LOG, |
| 266 runtime_error_verbose.severity); | 266 runtime_error_verbose.severity); |
| 267 const api::developer_private::ManifestError& manifest_error = | 267 const api::developer_private::ManifestError& manifest_error = |
| 268 *info->manifest_errors[0]; | 268 info->manifest_errors[0]; |
| 269 EXPECT_EQ(extension->id(), manifest_error.extension_id); | 269 EXPECT_EQ(extension->id(), manifest_error.extension_id); |
| 270 | 270 |
| 271 // Test an extension that isn't unpacked. | 271 // Test an extension that isn't unpacked. |
| 272 manifest_copy->SetString("update_url", | 272 manifest_copy->SetString("update_url", |
| 273 "https://clients2.google.com/service/update2/crx"); | 273 "https://clients2.google.com/service/update2/crx"); |
| 274 id = crx_file::id_util::GenerateId("beta"); | 274 id = crx_file::id_util::GenerateId("beta"); |
| 275 extension = ExtensionBuilder() | 275 extension = ExtensionBuilder() |
| 276 .SetManifest(std::move(manifest_copy)) | 276 .SetManifest(std::move(manifest_copy)) |
| 277 .SetLocation(Manifest::EXTERNAL_PREF) | 277 .SetLocation(Manifest::EXTERNAL_PREF) |
| 278 .SetID(id) | 278 .SetID(id) |
| 279 .Build(); | 279 .Build(); |
| 280 service()->AddExtension(extension.get()); | 280 service()->AddExtension(extension.get()); |
| 281 info = GenerateExtensionInfo(extension->id()); | 281 info = GenerateExtensionInfo(extension->id()); |
| 282 EXPECT_EQ(developer::LOCATION_THIRD_PARTY, info->location); | 282 EXPECT_EQ(developer::LOCATION_THIRD_PARTY, info->location); |
| 283 EXPECT_FALSE(info->path); | 283 EXPECT_FALSE(info->path); |
| 284 } | 284 } |
| 285 | 285 |
| 286 // Test three generated json outputs. | 286 // Test three generated json outputs. |
| 287 TEST_F(ExtensionInfoGeneratorUnitTest, GenerateExtensionsJSONData) { | 287 TEST_F(ExtensionInfoGeneratorUnitTest, GenerateExtensionsJSONData) { |
| 288 // Test Extension1 | 288 // Test Extension1 |
| 289 base::FilePath extension_path = | 289 base::FilePath extension_path = |
| 290 data_dir().AppendASCII("good") | 290 data_dir().AppendASCII("good") |
| 291 .AppendASCII("Extensions") | 291 .AppendASCII("Extensions") |
| 292 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") | 292 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") |
| 293 .AppendASCII("1.0.0.0"); | 293 .AppendASCII("1.0.0.0"); |
| 294 | 294 |
| 295 InspectableViewsFinder::ViewList views; | |
| 296 views.push_back(InspectableViewsFinder::ConstructView( | |
| 297 GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/bar.html"), | |
| 298 42, 88, true, false, VIEW_TYPE_TAB_CONTENTS)); | |
| 299 views.push_back(InspectableViewsFinder::ConstructView( | |
| 300 GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/dog.html"), | |
| 301 0, 0, false, true, VIEW_TYPE_TAB_CONTENTS)); | |
| 302 | |
| 303 base::FilePath expected_outputs_path = | 295 base::FilePath expected_outputs_path = |
| 304 data_dir().AppendASCII("api_test") | 296 data_dir().AppendASCII("api_test") |
| 305 .AppendASCII("developer") | 297 .AppendASCII("developer") |
| 306 .AppendASCII("generated_output"); | 298 .AppendASCII("generated_output"); |
| 307 | 299 |
| 308 CompareExpectedAndActualOutput( | 300 { |
| 309 extension_path, | 301 InspectableViewsFinder::ViewList views; |
| 310 views, | 302 views.push_back(InspectableViewsFinder::ConstructView( |
| 311 expected_outputs_path.AppendASCII( | 303 GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/bar.html"), |
| 312 "behllobkkfkfnphdnhnkndlbkcpglgmj.json")); | 304 42, 88, true, false, VIEW_TYPE_TAB_CONTENTS)); |
| 305 views.push_back(InspectableViewsFinder::ConstructView( |
| 306 GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/dog.html"), 0, |
| 307 0, false, true, VIEW_TYPE_TAB_CONTENTS)); |
| 308 |
| 309 CompareExpectedAndActualOutput( |
| 310 extension_path, std::move(views), |
| 311 expected_outputs_path.AppendASCII( |
| 312 "behllobkkfkfnphdnhnkndlbkcpglgmj.json")); |
| 313 } |
| 313 | 314 |
| 314 #if !defined(OS_CHROMEOS) | 315 #if !defined(OS_CHROMEOS) |
| 315 // Test Extension2 | 316 // Test Extension2 |
| 316 extension_path = data_dir().AppendASCII("good") | 317 extension_path = data_dir().AppendASCII("good") |
| 317 .AppendASCII("Extensions") | 318 .AppendASCII("Extensions") |
| 318 .AppendASCII("hpiknbiabeeppbpihjehijgoemciehgk") | 319 .AppendASCII("hpiknbiabeeppbpihjehijgoemciehgk") |
| 319 .AppendASCII("2"); | 320 .AppendASCII("2"); |
| 320 | 321 |
| 321 // It's OK to have duplicate URLs, so long as the IDs are different. | 322 { |
| 322 views[0]->url = | 323 // It's OK to have duplicate URLs, so long as the IDs are different. |
| 323 "chrome-extension://hpiknbiabeeppbpihjehijgoemciehgk/bar.html"; | 324 InspectableViewsFinder::ViewList views; |
| 324 views[1]->url = views[0]->url; | 325 views.push_back(InspectableViewsFinder::ConstructView( |
| 326 GURL("chrome-extension://hpiknbiabeeppbpihjehijgoemciehgk/bar.html"), |
| 327 42, 88, true, false, VIEW_TYPE_TAB_CONTENTS)); |
| 328 views.push_back(InspectableViewsFinder::ConstructView( |
| 329 GURL("chrome-extension://hpiknbiabeeppbpihjehijgoemciehgk/bar.html"), 0, |
| 330 0, false, true, VIEW_TYPE_TAB_CONTENTS)); |
| 325 | 331 |
| 326 CompareExpectedAndActualOutput( | 332 CompareExpectedAndActualOutput( |
| 327 extension_path, | 333 extension_path, std::move(views), |
| 328 views, | 334 expected_outputs_path.AppendASCII( |
| 329 expected_outputs_path.AppendASCII( | 335 "hpiknbiabeeppbpihjehijgoemciehgk.json")); |
| 330 "hpiknbiabeeppbpihjehijgoemciehgk.json")); | 336 } |
| 331 #endif | 337 #endif |
| 332 | 338 |
| 333 // Test Extension3 | 339 // Test Extension3 |
| 334 extension_path = data_dir().AppendASCII("good") | 340 extension_path = data_dir().AppendASCII("good") |
| 335 .AppendASCII("Extensions") | 341 .AppendASCII("Extensions") |
| 336 .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa") | 342 .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa") |
| 337 .AppendASCII("1.0"); | 343 .AppendASCII("1.0"); |
| 338 views.clear(); | 344 CompareExpectedAndActualOutput(extension_path, |
| 339 | 345 InspectableViewsFinder::ViewList(), |
| 340 CompareExpectedAndActualOutput( | 346 expected_outputs_path.AppendASCII( |
| 341 extension_path, | 347 "bjafgdebaacbbbecmhlhpofkepfkgcpa.json")); |
| 342 views, | |
| 343 expected_outputs_path.AppendASCII( | |
| 344 "bjafgdebaacbbbecmhlhpofkepfkgcpa.json")); | |
| 345 } | 348 } |
| 346 | 349 |
| 347 // Test that the all_urls checkbox only shows up for extensions that want all | 350 // Test that the all_urls checkbox only shows up for extensions that want all |
| 348 // urls, and only when the switch is on. | 351 // urls, and only when the switch is on. |
| 349 TEST_F(ExtensionInfoGeneratorUnitTest, ExtensionInfoRunOnAllUrls) { | 352 TEST_F(ExtensionInfoGeneratorUnitTest, ExtensionInfoRunOnAllUrls) { |
| 350 // Start with the switch enabled. | 353 // Start with the switch enabled. |
| 351 scoped_ptr<FeatureSwitch::ScopedOverride> enable_scripts_switch( | 354 scoped_ptr<FeatureSwitch::ScopedOverride> enable_scripts_switch( |
| 352 new FeatureSwitch::ScopedOverride( | 355 new FeatureSwitch::ScopedOverride( |
| 353 FeatureSwitch::scripts_require_action(), true)); | 356 FeatureSwitch::scripts_require_action(), true)); |
| 354 // Two extensions - one with all urls, one without. | 357 // Two extensions - one with all urls, one without. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 "all_urls_II", ListBuilder().Append(kAllHostsPermission).Build()); | 406 "all_urls_II", ListBuilder().Append(kAllHostsPermission).Build()); |
| 404 | 407 |
| 405 // Even though the extension has all_urls permission, the checkbox shouldn't | 408 // Even though the extension has all_urls permission, the checkbox shouldn't |
| 406 // show up without the switch. | 409 // show up without the switch. |
| 407 info = GenerateExtensionInfo(all_urls_extension->id()); | 410 info = GenerateExtensionInfo(all_urls_extension->id()); |
| 408 EXPECT_FALSE(info->run_on_all_urls.is_enabled); | 411 EXPECT_FALSE(info->run_on_all_urls.is_enabled); |
| 409 EXPECT_TRUE(info->run_on_all_urls.is_active); | 412 EXPECT_TRUE(info->run_on_all_urls.is_active); |
| 410 } | 413 } |
| 411 | 414 |
| 412 } // namespace extensions | 415 } // namespace extensions |
| OLD | NEW |