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

Unified Diff: extensions/browser/event_router_unittest.cc

Issue 2523913003: Fix bugs in filtered event removal code (Closed)
Patch Set: . Created 4 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « extensions/browser/event_router.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/browser/event_router_unittest.cc
diff --git a/extensions/browser/event_router_unittest.cc b/extensions/browser/event_router_unittest.cc
index 7fc725f34fca7ed15d21a10ab9e7f13b118e0d38..e977bd0e6d66273f4d0d1d94dfe0791593aead6a 100644
--- a/extensions/browser/event_router_unittest.cc
+++ b/extensions/browser/event_router_unittest.cc
@@ -9,18 +9,29 @@
#include <utility>
#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/macros.h"
+#include "base/compiler_specific.h" #include "base/macros.h"
Devlin 2016/12/02 21:41:24 typo
lazyboy 2016/12/03 00:12:25 Done.
#include "base/memory/ptr_util.h"
#include "base/test/histogram_tester.h"
#include "base/values.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/pref_service_factory.h"
+#include "components/prefs/testing_pref_store.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/event_listener_map.h"
+#include "extensions/browser/extension_pref_value_map.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_prefs_factory.h"
#include "extensions/browser/extensions_test.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+using base::DictionaryValue;
+using base::ListValue;
+using base::StringValue;
+
namespace extensions {
namespace {
@@ -106,6 +117,19 @@ scoped_refptr<Extension> CreateExtension(bool component, bool persistent) {
return builder.Build();
}
+std::unique_ptr<DictionaryValue> CreateHostSuffixFilter(
+ const std::string& suffix) {
+ std::unique_ptr<DictionaryValue> filter(new DictionaryValue());
+ std::unique_ptr<ListValue> filter_list(new ListValue());
+ std::unique_ptr<DictionaryValue> filter_dict(new DictionaryValue());
+
+ filter_dict->Set("hostSuffix", new StringValue(suffix));
Devlin 2016/12/02 21:41:25 ditto with line 128
lazyboy 2016/12/03 00:12:25 Done.
+ filter_list->Append(std::move(filter_dict));
+ filter->Set("url", filter_list.release());
Devlin 2016/12/02 21:41:25 nit: DictionaryValue::Set() can take a unique_ptr
lazyboy 2016/12/03 00:12:25 Done.
+
+ return filter;
+}
+
} // namespace
class EventRouterTest : public ExtensionsTest {
@@ -163,6 +187,99 @@ class EventRouterTest : public ExtensionsTest {
DISALLOW_COPY_AND_ASSIGN(EventRouterTest);
};
+class EventRouterFilterTest : public ExtensionsTest {
+ public:
+ EventRouterFilterTest() {}
+
+ void SetUp() override {
+ // extensions::ExtensionServiceTestBase::SetUp();
Devlin 2016/12/02 21:41:24 dd
lazyboy 2016/12/03 00:12:25 Done.
+ ExtensionsTest::SetUp();
+
+ render_process_host_.reset(
+ new content::MockRenderProcessHost(browser_context()));
+
+ // Set up all the dependencies of ExtensionPrefs.
+ extension_pref_value_map_.reset(new ExtensionPrefValueMap());
+ PrefServiceFactory factory;
+ factory.set_user_prefs(new TestingPrefStore());
+ factory.set_extension_prefs(new TestingPrefStore());
+ user_prefs::PrefRegistrySyncable* pref_registry =
+ new user_prefs::PrefRegistrySyncable();
+ // Prefs should be registered before the PrefService is created.
+ ExtensionPrefs::RegisterProfilePrefs(pref_registry);
+ pref_service_ = factory.Create(pref_registry);
+
+ std::unique_ptr<ExtensionPrefs> extension_prefs(ExtensionPrefs::Create(
+ browser_context(), pref_service_.get(),
+ browser_context()->GetPath().AppendASCII("Extensions"),
+ extension_pref_value_map_.get(), false /* extensions_disabled */,
+ std::vector<ExtensionPrefsObserver*>()));
+
+ ExtensionPrefsFactory::GetInstance()->SetInstanceForTesting(
+ browser_context(), std::move(extension_prefs));
+
+ ASSERT_TRUE(EventRouter::Get(browser_context())); // constructs EventRouter
+ }
+
+ void TearDown() override {
+ render_process_host_.reset();
+ ExtensionsTest::TearDown();
+ }
+
+ content::RenderProcessHost* render_process_host() const {
+ return render_process_host_.get();
+ }
+
+ EventRouter* event_router() { return EventRouter::Get(browser_context()); }
+
+ const DictionaryValue* GetFilteredEvents(const std::string& extension_id) {
+ return event_router()->GetFilteredEvents(extension_id);
+ }
+
+ bool ContainsFilter(const std::string& extension_id,
+ const std::string& event_name,
+ const DictionaryValue& to_check) {
+ const ListValue* filter_list = GetFilterList(extension_id, event_name);
+ if (!filter_list) {
+ ADD_FAILURE();
+ return false;
+ }
+
+ for (size_t i = 0; i < filter_list->GetSize(); ++i) {
+ const DictionaryValue* filter = nullptr;
+ if (!filter_list->GetDictionary(i, &filter)) {
+ ADD_FAILURE();
+ return false;
+ }
+ if (filter->Equals(&to_check))
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ const ListValue* GetFilterList(const std::string& extension_id,
+ const std::string& event_name) {
+ const base::DictionaryValue* filtered_events =
+ GetFilteredEvents(extension_id);
+ DictionaryValue::Iterator iter(*filtered_events);
+ if (iter.key() != event_name)
Devlin 2016/12/02 21:41:25 This confuses me. Why do we only check one entry?
lazyboy 2016/12/03 00:12:25 The pref dictionary value looks like this: { "on
+ return nullptr;
+
+ const base::ListValue* filter_list = nullptr;
+ if (!iter.value().GetAsList(&filter_list))
+ return nullptr;
Devlin 2016/12/02 21:41:24 assuming we keep this impl, we could just ignore t
lazyboy 2016/12/03 00:12:25 Done.
+
+ return filter_list;
+ }
+
+ std::unique_ptr<content::RenderProcessHost> render_process_host_;
+ std::unique_ptr<ExtensionPrefValueMap> extension_pref_value_map_;
+ std::unique_ptr<PrefService> pref_service_;
+
+ DISALLOW_COPY_AND_ASSIGN(EventRouterFilterTest);
+};
+
TEST_F(EventRouterTest, GetBaseEventName) {
// Normal event names are passed through unchanged.
EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar"));
@@ -275,4 +392,60 @@ TEST_F(EventRouterTest, TestReportEvent) {
ExpectHistogramCounts(7, 3, 2, 2, 1, 2);
}
+// Tests adding and removing events with filters.
+TEST_F(EventRouterFilterTest, Basic) {
+ // For the purpose of this test, "." is important in |event_name| as it
+ // exercises the code path that uses |event_name| as a key in DictionaryValue.
+ const std::string event_name = "chrome.onMyEvent";
Devlin 2016/12/02 21:41:24 nit: prefer kEventName, kExtensionId, etc for cons
Devlin 2016/12/02 21:41:24 Just for test clarity, it might be better to use a
lazyboy 2016/12/03 00:12:25 Done.
lazyboy 2016/12/03 00:12:25 Done.
+
+ const std::string extension_id = "mbflcebpggnecokmikipoihdbecnjfoj";
+ std::string host_suffixes[] = {"foo.com", "bar.com", "baz.com"};
+ std::vector<std::unique_ptr<DictionaryValue>> filters;
+ for (size_t i = 0; i < arraysize(host_suffixes); ++i) {
+ std::unique_ptr<base::DictionaryValue> filter1 =
+ CreateHostSuffixFilter(host_suffixes[i]);
+ EventRouter::Get(browser_context())
+ ->AddFilteredEventListener(event_name, render_process_host(),
+ extension_id, *filter1.get(), true);
Devlin 2016/12/02 21:41:25 *foo.get() is redundant; -> *foo.
lazyboy 2016/12/03 00:12:25 Done.
+ filters.push_back(std::move(filter1));
+ }
+
+ const base::DictionaryValue* filtered_events =
+ GetFilteredEvents(extension_id);
+ ASSERT_TRUE(filtered_events);
+ ASSERT_EQ(1u, filtered_events->size());
+
+ DictionaryValue::Iterator iter(*filtered_events);
+ ASSERT_EQ(event_name, iter.key());
+ const base::ListValue* filter_list = nullptr;
+ ASSERT_TRUE(iter.value().GetAsList(&filter_list));
+ ASSERT_TRUE(filter_list);
+ ASSERT_EQ(3u, filter_list->GetSize());
+
+ ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[0].get()));
+ ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[1].get()));
+ ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[2].get()));
+
+ // Remove the second filter.
+ event_router()->RemoveFilteredEventListener(
+ event_name, render_process_host(), extension_id, *filters[1].get(), true);
+ ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[0].get()));
+ ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[1].get()));
+ ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[2].get()));
+
+ // Remove the first filter.
+ event_router()->RemoveFilteredEventListener(
+ event_name, render_process_host(), extension_id, *filters[0].get(), true);
+ ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[0].get()));
+ ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[1].get()));
+ ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[2].get()));
+
+ // Remove the third filter.
+ event_router()->RemoveFilteredEventListener(
+ event_name, render_process_host(), extension_id, *filters[2].get(), true);
+ ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[0].get()));
+ ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[1].get()));
+ ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[2].get()));
+}
+
} // namespace extensions
« no previous file with comments | « extensions/browser/event_router.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698