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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « extensions/browser/event_router.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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 "extensions/browser/event_router.h" 5 #include "extensions/browser/event_router.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/compiler_specific.h" 12 #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.
13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
15 #include "base/test/histogram_tester.h" 14 #include "base/test/histogram_tester.h"
16 #include "base/values.h" 15 #include "base/values.h"
16 #include "components/pref_registry/pref_registry_syncable.h"
17 #include "components/prefs/pref_service_factory.h"
18 #include "components/prefs/testing_pref_store.h"
19 #include "content/public/browser/browser_context.h"
20 #include "content/public/test/mock_render_process_host.h"
17 #include "content/public/test/test_browser_thread_bundle.h" 21 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "extensions/browser/event_listener_map.h" 22 #include "extensions/browser/event_listener_map.h"
23 #include "extensions/browser/extension_pref_value_map.h"
24 #include "extensions/browser/extension_prefs.h"
25 #include "extensions/browser/extension_prefs_factory.h"
19 #include "extensions/browser/extensions_test.h" 26 #include "extensions/browser/extensions_test.h"
20 #include "extensions/common/extension_builder.h" 27 #include "extensions/common/extension_builder.h"
21 #include "extensions/common/test_util.h" 28 #include "extensions/common/test_util.h"
22 #include "testing/gtest/include/gtest/gtest.h" 29 #include "testing/gtest/include/gtest/gtest.h"
23 30
31 using base::DictionaryValue;
32 using base::ListValue;
33 using base::StringValue;
34
24 namespace extensions { 35 namespace extensions {
25 36
26 namespace { 37 namespace {
27 38
28 // A simple mock to keep track of listener additions and removals. 39 // A simple mock to keep track of listener additions and removals.
29 class MockEventRouterObserver : public EventRouter::Observer { 40 class MockEventRouterObserver : public EventRouter::Observer {
30 public: 41 public:
31 MockEventRouterObserver() 42 MockEventRouterObserver()
32 : listener_added_count_(0), 43 : listener_added_count_(0),
33 listener_removed_count_(0) {} 44 listener_removed_count_(0) {}
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 manifest->SetInteger("manifest_version", 2); 110 manifest->SetInteger("manifest_version", 2);
100 manifest->SetString("background.page", "background.html"); 111 manifest->SetString("background.page", "background.html");
101 manifest->SetBoolean("background.persistent", persistent); 112 manifest->SetBoolean("background.persistent", persistent);
102 builder.SetManifest(std::move(manifest)); 113 builder.SetManifest(std::move(manifest));
103 if (component) 114 if (component)
104 builder.SetLocation(Manifest::Location::COMPONENT); 115 builder.SetLocation(Manifest::Location::COMPONENT);
105 116
106 return builder.Build(); 117 return builder.Build();
107 } 118 }
108 119
120 std::unique_ptr<DictionaryValue> CreateHostSuffixFilter(
121 const std::string& suffix) {
122 std::unique_ptr<DictionaryValue> filter(new DictionaryValue());
123 std::unique_ptr<ListValue> filter_list(new ListValue());
124 std::unique_ptr<DictionaryValue> filter_dict(new DictionaryValue());
125
126 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.
127 filter_list->Append(std::move(filter_dict));
128 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.
129
130 return filter;
131 }
132
109 } // namespace 133 } // namespace
110 134
111 class EventRouterTest : public ExtensionsTest { 135 class EventRouterTest : public ExtensionsTest {
112 public: 136 public:
113 EventRouterTest() {} 137 EventRouterTest() {}
114 138
115 protected: 139 protected:
116 // Tests adding and removing observers from EventRouter. 140 // Tests adding and removing observers from EventRouter.
117 void RunEventRouterObserverTest(const EventListenerConstructor& constructor); 141 void RunEventRouterObserverTest(const EventListenerConstructor& constructor);
118 142
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 180 }
157 } 181 }
158 182
159 private: 183 private:
160 content::TestBrowserThreadBundle thread_bundle_; 184 content::TestBrowserThreadBundle thread_bundle_;
161 base::HistogramTester histogram_tester_; 185 base::HistogramTester histogram_tester_;
162 186
163 DISALLOW_COPY_AND_ASSIGN(EventRouterTest); 187 DISALLOW_COPY_AND_ASSIGN(EventRouterTest);
164 }; 188 };
165 189
190 class EventRouterFilterTest : public ExtensionsTest {
191 public:
192 EventRouterFilterTest() {}
193
194 void SetUp() override {
195 // extensions::ExtensionServiceTestBase::SetUp();
Devlin 2016/12/02 21:41:24 dd
lazyboy 2016/12/03 00:12:25 Done.
196 ExtensionsTest::SetUp();
197
198 render_process_host_.reset(
199 new content::MockRenderProcessHost(browser_context()));
200
201 // Set up all the dependencies of ExtensionPrefs.
202 extension_pref_value_map_.reset(new ExtensionPrefValueMap());
203 PrefServiceFactory factory;
204 factory.set_user_prefs(new TestingPrefStore());
205 factory.set_extension_prefs(new TestingPrefStore());
206 user_prefs::PrefRegistrySyncable* pref_registry =
207 new user_prefs::PrefRegistrySyncable();
208 // Prefs should be registered before the PrefService is created.
209 ExtensionPrefs::RegisterProfilePrefs(pref_registry);
210 pref_service_ = factory.Create(pref_registry);
211
212 std::unique_ptr<ExtensionPrefs> extension_prefs(ExtensionPrefs::Create(
213 browser_context(), pref_service_.get(),
214 browser_context()->GetPath().AppendASCII("Extensions"),
215 extension_pref_value_map_.get(), false /* extensions_disabled */,
216 std::vector<ExtensionPrefsObserver*>()));
217
218 ExtensionPrefsFactory::GetInstance()->SetInstanceForTesting(
219 browser_context(), std::move(extension_prefs));
220
221 ASSERT_TRUE(EventRouter::Get(browser_context())); // constructs EventRouter
222 }
223
224 void TearDown() override {
225 render_process_host_.reset();
226 ExtensionsTest::TearDown();
227 }
228
229 content::RenderProcessHost* render_process_host() const {
230 return render_process_host_.get();
231 }
232
233 EventRouter* event_router() { return EventRouter::Get(browser_context()); }
234
235 const DictionaryValue* GetFilteredEvents(const std::string& extension_id) {
236 return event_router()->GetFilteredEvents(extension_id);
237 }
238
239 bool ContainsFilter(const std::string& extension_id,
240 const std::string& event_name,
241 const DictionaryValue& to_check) {
242 const ListValue* filter_list = GetFilterList(extension_id, event_name);
243 if (!filter_list) {
244 ADD_FAILURE();
245 return false;
246 }
247
248 for (size_t i = 0; i < filter_list->GetSize(); ++i) {
249 const DictionaryValue* filter = nullptr;
250 if (!filter_list->GetDictionary(i, &filter)) {
251 ADD_FAILURE();
252 return false;
253 }
254 if (filter->Equals(&to_check))
255 return true;
256 }
257 return false;
258 }
259
260 private:
261 const ListValue* GetFilterList(const std::string& extension_id,
262 const std::string& event_name) {
263 const base::DictionaryValue* filtered_events =
264 GetFilteredEvents(extension_id);
265 DictionaryValue::Iterator iter(*filtered_events);
266 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
267 return nullptr;
268
269 const base::ListValue* filter_list = nullptr;
270 if (!iter.value().GetAsList(&filter_list))
271 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.
272
273 return filter_list;
274 }
275
276 std::unique_ptr<content::RenderProcessHost> render_process_host_;
277 std::unique_ptr<ExtensionPrefValueMap> extension_pref_value_map_;
278 std::unique_ptr<PrefService> pref_service_;
279
280 DISALLOW_COPY_AND_ASSIGN(EventRouterFilterTest);
281 };
282
166 TEST_F(EventRouterTest, GetBaseEventName) { 283 TEST_F(EventRouterTest, GetBaseEventName) {
167 // Normal event names are passed through unchanged. 284 // Normal event names are passed through unchanged.
168 EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar")); 285 EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar"));
169 286
170 // Sub-events are converted to the part before the slash. 287 // Sub-events are converted to the part before the slash.
171 EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar/123")); 288 EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar/123"));
172 } 289 }
173 290
174 // Tests adding and removing observers from EventRouter. 291 // Tests adding and removing observers from EventRouter.
175 void EventRouterTest::RunEventRouterObserverTest( 292 void EventRouterTest::RunEventRouterObserverTest(
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 385
269 scoped_refptr<Extension> component_event = CreateExtension(true, false); 386 scoped_refptr<Extension> component_event = CreateExtension(true, false);
270 router.ReportEvent(events::HistogramValue::FOR_TEST, component_event.get(), 387 router.ReportEvent(events::HistogramValue::FOR_TEST, component_event.get(),
271 false /** did_enqueue */); 388 false /** did_enqueue */);
272 ExpectHistogramCounts(6, 2, 2, 1, 0, 2); 389 ExpectHistogramCounts(6, 2, 2, 1, 0, 2);
273 router.ReportEvent(events::HistogramValue::FOR_TEST, component_event.get(), 390 router.ReportEvent(events::HistogramValue::FOR_TEST, component_event.get(),
274 true /** did_enqueue */); 391 true /** did_enqueue */);
275 ExpectHistogramCounts(7, 3, 2, 2, 1, 2); 392 ExpectHistogramCounts(7, 3, 2, 2, 1, 2);
276 } 393 }
277 394
395 // Tests adding and removing events with filters.
396 TEST_F(EventRouterFilterTest, Basic) {
397 // For the purpose of this test, "." is important in |event_name| as it
398 // exercises the code path that uses |event_name| as a key in DictionaryValue.
399 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.
400
401 const std::string extension_id = "mbflcebpggnecokmikipoihdbecnjfoj";
402 std::string host_suffixes[] = {"foo.com", "bar.com", "baz.com"};
403 std::vector<std::unique_ptr<DictionaryValue>> filters;
404 for (size_t i = 0; i < arraysize(host_suffixes); ++i) {
405 std::unique_ptr<base::DictionaryValue> filter1 =
406 CreateHostSuffixFilter(host_suffixes[i]);
407 EventRouter::Get(browser_context())
408 ->AddFilteredEventListener(event_name, render_process_host(),
409 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.
410 filters.push_back(std::move(filter1));
411 }
412
413 const base::DictionaryValue* filtered_events =
414 GetFilteredEvents(extension_id);
415 ASSERT_TRUE(filtered_events);
416 ASSERT_EQ(1u, filtered_events->size());
417
418 DictionaryValue::Iterator iter(*filtered_events);
419 ASSERT_EQ(event_name, iter.key());
420 const base::ListValue* filter_list = nullptr;
421 ASSERT_TRUE(iter.value().GetAsList(&filter_list));
422 ASSERT_TRUE(filter_list);
423 ASSERT_EQ(3u, filter_list->GetSize());
424
425 ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[0].get()));
426 ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[1].get()));
427 ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[2].get()));
428
429 // Remove the second filter.
430 event_router()->RemoveFilteredEventListener(
431 event_name, render_process_host(), extension_id, *filters[1].get(), true);
432 ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[0].get()));
433 ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[1].get()));
434 ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[2].get()));
435
436 // Remove the first filter.
437 event_router()->RemoveFilteredEventListener(
438 event_name, render_process_host(), extension_id, *filters[0].get(), true);
439 ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[0].get()));
440 ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[1].get()));
441 ASSERT_TRUE(ContainsFilter(extension_id, event_name, *filters[2].get()));
442
443 // Remove the third filter.
444 event_router()->RemoveFilteredEventListener(
445 event_name, render_process_host(), extension_id, *filters[2].get(), true);
446 ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[0].get()));
447 ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[1].get()));
448 ASSERT_FALSE(ContainsFilter(extension_id, event_name, *filters[2].get()));
449 }
450
278 } // namespace extensions 451 } // namespace extensions
OLDNEW
« 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