Index: chrome/browser/extensions/events_apitest.cc |
diff --git a/chrome/browser/extensions/events_apitest.cc b/chrome/browser/extensions/events_apitest.cc |
index 8787df1e60d083be72a850e2172ccf85857c39bf..143a82d733d684781eac5d82d07b4c60a7ddb6cb 100644 |
--- a/chrome/browser/extensions/events_apitest.cc |
+++ b/chrome/browser/extensions/events_apitest.cc |
@@ -5,8 +5,12 @@ |
#include "base/files/file_path.h" |
#include "base/files/file_util.h" |
#include "chrome/browser/extensions/extension_apitest.h" |
+#include "chrome/browser/extensions/extension_service.h" |
+#include "chrome/test/base/ui_test_utils.h" |
#include "extensions/browser/event_router.h" |
#include "extensions/browser/extension_registry.h" |
+#include "extensions/browser/scoped_ignore_content_verifier_for_test.h" |
+#include "extensions/test/result_catcher.h" |
namespace extensions { |
@@ -65,4 +69,146 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, EventsAreUnregistered) { |
event_router->ExtensionHasEventListener(id, "webNavigation.onCompleted")); |
} |
+class EventsApiTest : public ExtensionApiTest { |
+ public: |
+ EventsApiTest() {} |
+ |
+ protected: |
+ void SetUpOnMainThread() override { |
+ ExtensionApiTest::SetUpOnMainThread(); |
+ EXPECT_TRUE(scoped_temp_dir_.CreateUniqueTempDir()); |
+ } |
+ |
+ struct ExtensionCRXData { |
+ std::string unpacked_relative_path; |
+ base::FilePath crx_path; |
+ explicit ExtensionCRXData(const std::string& unpacked_relative_path) |
+ : unpacked_relative_path(unpacked_relative_path) {} |
+ }; |
+ |
+ void SetUpCRX(const std::string& root_dir, |
+ const std::string& pem_filename, |
+ std::vector<ExtensionCRXData>* crx_data_list) { |
+ const base::FilePath test_dir = test_data_dir_.AppendASCII(root_dir); |
+ const base::FilePath pem_path = test_dir.AppendASCII(pem_filename); |
+ for (ExtensionCRXData& crx_data : *crx_data_list) { |
+ crx_data.crx_path = PackExtensionWithOptions( |
+ test_dir.AppendASCII(crx_data.unpacked_relative_path), |
+ scoped_temp_dir_.GetPath().AppendASCII( |
+ crx_data.unpacked_relative_path + ".crx"), |
+ pem_path, base::FilePath()); |
+ } |
+ } |
+ |
+ private: |
+ base::ScopedTempDir scoped_temp_dir_; |
+ ScopedIgnoreContentVerifierForTest ignore_content_verification_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(EventsApiTest); |
+}; |
+ |
+// Tests that updating an extension sends runtime.onInstalled event to the |
+// updated extension. |
+IN_PROC_BROWSER_TEST_F(EventsApiTest, ExtensionUpdateSendsOnInstalledEvent) { |
+ std::vector<ExtensionCRXData> data; |
+ data.emplace_back("v1"); |
+ data.emplace_back("v2"); |
+ SetUpCRX("lazy_events/on_installed", "pem.pem", &data); |
+ |
+ ExtensionId extension_id; |
+ { |
+ // Install version 1 of the extension and expect runtime.onInstalled. |
+ ResultCatcher catcher; |
+ const int expected_change = 1; |
+ const Extension* extension_v1 = |
+ InstallExtension(data[0].crx_path, expected_change); |
+ extension_id = extension_v1->id(); |
+ ASSERT_TRUE(extension_v1); |
+ EXPECT_TRUE(catcher.GetNextResult()); |
+ } |
+ { |
+ // Update to version 2, also expect runtime.onInstalled. |
+ ResultCatcher catcher; |
+ const int expected_change = 0; |
+ const Extension* extension_v2 = |
+ UpdateExtension(extension_id, data[1].crx_path, expected_change); |
+ ASSERT_TRUE(extension_v2); |
+ EXPECT_TRUE(catcher.GetNextResult()); |
+ } |
+} |
+ |
+// Tests that if updating an extension makes the extension disabled (due to |
+// permissions increase), then enabling the extension fires runtime.onInstalled |
+// correctly to the updated extension. |
+IN_PROC_BROWSER_TEST_F(EventsApiTest, |
+ UpdateDispatchesOnInstalledAfterEnablement) { |
+ std::vector<ExtensionCRXData> data; |
+ data.emplace_back("v1"); |
+ data.emplace_back("v2"); |
+ SetUpCRX("lazy_events/on_installed_permissions_increase", "pem.pem", &data); |
+ |
+ ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); |
+ ExtensionId extension_id; |
+ { |
+ // Install version 1 of the extension and expect runtime.onInstalled. |
+ ResultCatcher catcher; |
+ const int expected_change = 1; |
+ const Extension* extension_v1 = |
+ InstallExtension(data[0].crx_path, expected_change); |
+ extension_id = extension_v1->id(); |
+ ASSERT_TRUE(extension_v1); |
+ EXPECT_TRUE(catcher.GetNextResult()); |
+ } |
+ { |
+ // Update to version 2, which will be disabled due to permissions increase. |
+ ResultCatcher catcher; |
+ const int expected_change = -1; // Expect extension to be disabled. |
+ ASSERT_FALSE( |
+ UpdateExtension(extension_id, data[1].crx_path, expected_change)); |
+ |
+ const Extension* extension_v2 = |
+ registry->disabled_extensions().GetByID(extension_id); |
+ ASSERT_TRUE(extension_v2); |
+ // Enable the extension. |
+ extension_service()->GrantPermissionsAndEnableExtension(extension_v2); |
+ EXPECT_TRUE(catcher.GetNextResult()); |
+ } |
+} |
+ |
+// Tests that if an extension's updated version has a new lazy listener, it |
+// fires properly after the update. |
+IN_PROC_BROWSER_TEST_F(EventsApiTest, NewlyIntroducedListener) { |
+ std::vector<ExtensionCRXData> data; |
+ data.emplace_back("v1"); |
+ data.emplace_back("v2"); |
+ SetUpCRX("lazy_events/new_event_in_new_version", "pem.pem", &data); |
+ |
+ ExtensionId extension_id; |
+ { |
+ // Install version 1 of the extension. |
+ ResultCatcher catcher; |
+ const int expected_change = 1; |
+ const Extension* extension_v1 = |
+ InstallExtension(data[0].crx_path, expected_change); |
+ EXPECT_TRUE(extension_v1); |
+ extension_id = extension_v1->id(); |
+ ASSERT_TRUE(extension_v1); |
+ EXPECT_TRUE(catcher.GetNextResult()); |
+ } |
+ { |
+ // Update to version 2, that has tabs.onCreated event listener. |
+ ResultCatcher catcher; |
+ const int expected_change = 0; |
+ const Extension* extension_v2 = |
+ UpdateExtension(extension_id, data[1].crx_path, expected_change); |
+ ASSERT_TRUE(extension_v2); |
+ ui_test_utils::NavigateToURLWithDisposition( |
+ browser(), GURL(url::kAboutBlankURL), |
+ WindowOpenDisposition::NEW_BACKGROUND_TAB, |
+ ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
+ // Expect tabs.onCreated to fire. |
+ EXPECT_TRUE(catcher.GetNextResult()); |
+ } |
+} |
+ |
} // namespace extensions |