event_listener_map_unittest.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  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
  3. // found in the LICENSE file.
  4. #include "extensions/browser/event_listener_map.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/strings/stringprintf.h"
  8. #include "base/values.h"
  9. #include "content/public/test/mock_render_process_host.h"
  10. #include "content/public/test/test_browser_context.h"
  11. #include "extensions/browser/event_router.h"
  12. #include "extensions/browser/extensions_test.h"
  13. #include "extensions/common/mojom/event_dispatcher.mojom.h"
  14. #include "testing/gtest/include/gtest/gtest.h"
  15. #include "url/gurl.h"
  16. using base::DictionaryValue;
  17. using base::ListValue;
  18. using base::Value;
  19. namespace extensions {
  20. namespace {
  21. const char kExt1Id[] = "extension_1";
  22. const char kExt2Id[] = "extension_2";
  23. const char kEvent1Name[] = "event1";
  24. const char kEvent2Name[] = "event2";
  25. const char kURL[] = "https://google.com/some/url";
  26. // Returns appropriate worker version id for tests.
  27. int64_t GetWorkerVersionId(bool lazy) {
  28. static constexpr int64_t kDummyServiceWorkerVersionId = 199;
  29. return lazy ? blink::mojom::kInvalidServiceWorkerVersionId
  30. : kDummyServiceWorkerVersionId;
  31. }
  32. // Returns appropriate worker thread id for tests.
  33. int GetWorkerThreadId(bool lazy) {
  34. static constexpr int kDummyServiceWorkerThreadId = 99;
  35. return lazy ? kMainThreadId : kDummyServiceWorkerThreadId;
  36. }
  37. using EventListenerConstructor =
  38. base::RepeatingCallback<std::unique_ptr<EventListener>(
  39. const std::string& /* event_name */,
  40. content::RenderProcessHost* /* process */,
  41. std::unique_ptr<base::DictionaryValue> /* filter */)>;
  42. class EmptyDelegate : public EventListenerMap::Delegate {
  43. void OnListenerAdded(const EventListener* listener) override {}
  44. void OnListenerRemoved(const EventListener* listener) override {}
  45. };
  46. class EventListenerMapTest : public ExtensionsTest {
  47. public:
  48. EventListenerMapTest()
  49. : delegate_(std::make_unique<EmptyDelegate>()),
  50. listeners_(std::make_unique<EventListenerMap>(delegate_.get())) {}
  51. // testing::Test overrides:
  52. void SetUp() override {
  53. ExtensionsTest::SetUp();
  54. process_ =
  55. std::make_unique<content::MockRenderProcessHost>(browser_context());
  56. }
  57. void TearDown() override {
  58. process_->Cleanup();
  59. process_ = nullptr;
  60. ExtensionsTest::TearDown();
  61. }
  62. std::unique_ptr<DictionaryValue> CreateHostSuffixFilter(
  63. const std::string& suffix) {
  64. base::Value::Dict filter_dict;
  65. filter_dict.Set("hostSuffix", suffix);
  66. base::Value::List filter_list;
  67. filter_list.Append(std::move(filter_dict));
  68. auto filter = std::make_unique<DictionaryValue>();
  69. filter->GetDict().Set("url", base::Value(std::move(filter_list)));
  70. return filter;
  71. }
  72. std::unique_ptr<Event> CreateNamedEvent(const std::string& event_name) {
  73. return CreateEvent(event_name, GURL());
  74. }
  75. std::unique_ptr<Event> CreateEvent(const std::string& event_name,
  76. const GURL& url) {
  77. mojom::EventFilteringInfoPtr info = mojom::EventFilteringInfo::New();
  78. info->url = url;
  79. return std::make_unique<Event>(
  80. events::FOR_TEST, event_name, base::Value::List(), nullptr, GURL(),
  81. EventRouter::USER_GESTURE_UNKNOWN, std::move(info));
  82. }
  83. std::unique_ptr<EventListener> CreateLazyListener(
  84. const std::string& event_name,
  85. const ExtensionId& extension_id,
  86. std::unique_ptr<base::DictionaryValue> filter,
  87. bool is_for_service_worker) {
  88. if (is_for_service_worker) {
  89. return EventListener::ForExtensionServiceWorker(
  90. event_name, extension_id, nullptr,
  91. Extension::GetBaseURLFromExtensionId(extension_id),
  92. GetWorkerVersionId(true), GetWorkerThreadId(true), std::move(filter));
  93. }
  94. return EventListener::ForExtension(event_name, extension_id, nullptr,
  95. std::move(filter));
  96. }
  97. protected:
  98. void TestUnfilteredEventsGoToAllListeners(
  99. const EventListenerConstructor& constructor);
  100. void TestRemovingByProcess(const EventListenerConstructor& constructor);
  101. void TestRemovingByListener(const EventListenerConstructor& constructor);
  102. void TestAddExistingUnfilteredListener(
  103. const EventListenerConstructor& constructor);
  104. void TestHasListenerForEvent(const EventListenerConstructor& constructor);
  105. std::unique_ptr<EventListenerMap::Delegate> delegate_;
  106. std::unique_ptr<EventListenerMap> listeners_;
  107. std::unique_ptr<content::RenderProcessHost> process_;
  108. };
  109. // Parameterized version of test to run with |is_for_service_worker|.
  110. class EventListenerMapWithContextTest
  111. : public EventListenerMapTest,
  112. public testing::WithParamInterface<bool /* is_for_service_worker */> {};
  113. std::unique_ptr<EventListener> CreateEventListenerForExtension(
  114. const std::string& extension_id,
  115. const std::string& event_name,
  116. content::RenderProcessHost* process,
  117. std::unique_ptr<base::DictionaryValue> filter) {
  118. return EventListener::ForExtension(event_name, extension_id, process,
  119. std::move(filter));
  120. }
  121. std::unique_ptr<EventListener> CreateEventListenerForURL(
  122. const GURL& listener_url,
  123. const std::string& event_name,
  124. content::RenderProcessHost* process,
  125. std::unique_ptr<base::DictionaryValue> filter) {
  126. return EventListener::ForURL(event_name, listener_url, process,
  127. std::move(filter));
  128. }
  129. std::unique_ptr<EventListener> CreateEventListenerForExtensionServiceWorker(
  130. const std::string& extension_id,
  131. const std::string& event_name,
  132. content::RenderProcessHost* process,
  133. std::unique_ptr<base::DictionaryValue> filter) {
  134. return EventListener::ForExtensionServiceWorker(
  135. event_name, extension_id, process,
  136. Extension::GetBaseURLFromExtensionId(extension_id),
  137. GetWorkerVersionId(false), GetWorkerThreadId(false), std::move(filter));
  138. }
  139. void EventListenerMapTest::TestUnfilteredEventsGoToAllListeners(
  140. const EventListenerConstructor& constructor) {
  141. listeners_->AddListener(constructor.Run(
  142. kEvent1Name, nullptr, std::make_unique<base::DictionaryValue>()));
  143. std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  144. ASSERT_EQ(1u, listeners_->GetEventListeners(*event).size());
  145. }
  146. TEST_F(EventListenerMapTest, UnfilteredEventsGoToAllListenersForExtensions) {
  147. TestUnfilteredEventsGoToAllListeners(
  148. base::BindRepeating(&CreateEventListenerForExtension, kExt1Id));
  149. }
  150. TEST_F(EventListenerMapTest, UnfilteredEventsGoToAllListenersForURLs) {
  151. TestUnfilteredEventsGoToAllListeners(
  152. base::BindRepeating(&CreateEventListenerForURL, GURL(kURL)));
  153. }
  154. TEST_F(EventListenerMapTest,
  155. UnfilteredEventsGoToAllListenersForExtensionServiceWorkers) {
  156. TestUnfilteredEventsGoToAllListeners(base::BindRepeating(
  157. &CreateEventListenerForExtensionServiceWorker, kExt1Id));
  158. }
  159. TEST_F(EventListenerMapTest, FilteredEventsGoToAllMatchingListeners) {
  160. auto create_filter = [&](const std::string& filter_str) {
  161. return CreateHostSuffixFilter(filter_str);
  162. };
  163. auto create_empty_filter = []() {
  164. return std::make_unique<base::DictionaryValue>();
  165. };
  166. for (bool is_for_service_worker : {false, true}) {
  167. listeners_->AddListener(CreateLazyListener(kEvent1Name, kExt1Id,
  168. create_filter("google.com"),
  169. is_for_service_worker));
  170. listeners_->AddListener(CreateLazyListener(
  171. kEvent1Name, kExt1Id, create_empty_filter(), is_for_service_worker));
  172. }
  173. std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  174. event->filter_info->url = GURL("http://www.google.com");
  175. std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  176. ASSERT_EQ(4u, targets.size());
  177. }
  178. TEST_P(EventListenerMapWithContextTest,
  179. FilteredEventsOnlyGoToMatchingListeners) {
  180. const bool is_for_service_worker = GetParam();
  181. struct TestCase {
  182. const std::string filter_host_suffix;
  183. const std::string url_of_event;
  184. } kTestCases[] = {
  185. {"google.com", "http://www.google.com"},
  186. {"yahoo.com", "http://www.yahoo.com"},
  187. };
  188. for (const TestCase& test_case : kTestCases) {
  189. listeners_->AddListener(
  190. CreateLazyListener(kEvent1Name, kExt1Id,
  191. CreateHostSuffixFilter(test_case.filter_host_suffix),
  192. is_for_service_worker));
  193. }
  194. // Matching filters.
  195. for (const TestCase& test_case : kTestCases) {
  196. SCOPED_TRACE(base::StringPrintf("host_suffix = %s, url = %s",
  197. test_case.filter_host_suffix.c_str(),
  198. test_case.url_of_event.c_str()));
  199. std::unique_ptr<Event> event(
  200. CreateEvent(kEvent1Name, GURL(test_case.url_of_event)));
  201. std::set<const EventListener*> targets(
  202. listeners_->GetEventListeners(*event));
  203. ASSERT_EQ(1u, targets.size());
  204. EXPECT_TRUE(
  205. CreateLazyListener(kEvent1Name, kExt1Id,
  206. CreateHostSuffixFilter(test_case.filter_host_suffix),
  207. is_for_service_worker)
  208. ->Equals(*targets.begin()));
  209. }
  210. // Non-matching filter.
  211. {
  212. std::unique_ptr<Event> event(
  213. CreateEvent(kEvent1Name, GURL("http://does_not_match.com")));
  214. std::set<const EventListener*> targets(
  215. listeners_->GetEventListeners(*event));
  216. EXPECT_TRUE(targets.empty());
  217. }
  218. }
  219. TEST_F(EventListenerMapTest, LazyAndUnlazyListenersGetReturned) {
  220. listeners_->AddListener(EventListener::ForExtension(
  221. kEvent1Name, kExt1Id, nullptr, CreateHostSuffixFilter("google.com")));
  222. listeners_->AddListener(
  223. EventListener::ForExtension(kEvent1Name, kExt1Id, process_.get(),
  224. CreateHostSuffixFilter("google.com")));
  225. std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  226. event->filter_info->url = GURL("http://www.google.com");
  227. std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  228. ASSERT_EQ(2u, targets.size());
  229. }
  230. void EventListenerMapTest::TestRemovingByProcess(
  231. const EventListenerConstructor& constructor) {
  232. listeners_->AddListener(constructor.Run(
  233. kEvent1Name, nullptr, CreateHostSuffixFilter("google.com")));
  234. listeners_->AddListener(constructor.Run(
  235. kEvent1Name, process_.get(), CreateHostSuffixFilter("google.com")));
  236. listeners_->RemoveListenersForProcess(process_.get());
  237. std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  238. event->filter_info->url = GURL("http://www.google.com");
  239. ASSERT_EQ(1u, listeners_->GetEventListeners(*event).size());
  240. }
  241. TEST_F(EventListenerMapTest, TestRemovingByProcessForExtension) {
  242. TestRemovingByProcess(
  243. base::BindRepeating(&CreateEventListenerForExtension, kExt1Id));
  244. }
  245. TEST_F(EventListenerMapTest, TestRemovingByProcessForURL) {
  246. TestRemovingByProcess(
  247. base::BindRepeating(&CreateEventListenerForURL, GURL(kURL)));
  248. }
  249. TEST_F(EventListenerMapTest, TestRemovingByProcessForExtensionServiceWorker) {
  250. TestRemovingByProcess(base::BindRepeating(
  251. &CreateEventListenerForExtensionServiceWorker, kExt1Id));
  252. }
  253. void EventListenerMapTest::TestRemovingByListener(
  254. const EventListenerConstructor& constructor) {
  255. listeners_->AddListener(constructor.Run(
  256. kEvent1Name, nullptr, CreateHostSuffixFilter("google.com")));
  257. listeners_->AddListener(constructor.Run(
  258. kEvent1Name, process_.get(), CreateHostSuffixFilter("google.com")));
  259. std::unique_ptr<EventListener> listener(constructor.Run(
  260. kEvent1Name, process_.get(), CreateHostSuffixFilter("google.com")));
  261. listeners_->RemoveListener(listener.get());
  262. std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  263. event->filter_info->url = GURL("http://www.google.com");
  264. ASSERT_EQ(1u, listeners_->GetEventListeners(*event).size());
  265. }
  266. TEST_F(EventListenerMapTest, TestRemovingByListenerForExtension) {
  267. TestRemovingByListener(
  268. base::BindRepeating(&CreateEventListenerForExtension, kExt1Id));
  269. }
  270. TEST_F(EventListenerMapTest, TestRemovingByListenerForURL) {
  271. TestRemovingByListener(
  272. base::BindRepeating(&CreateEventListenerForURL, GURL(kURL)));
  273. }
  274. TEST_F(EventListenerMapTest, TestRemovingByListenerForExtensionServiceWorker) {
  275. TestRemovingByListener(base::BindRepeating(
  276. &CreateEventListenerForExtensionServiceWorker, kExt1Id));
  277. }
  278. TEST_P(EventListenerMapWithContextTest, TestLazyDoubleAddIsUndoneByRemove) {
  279. const bool is_for_service_worker = GetParam();
  280. listeners_->AddListener(CreateLazyListener(
  281. kEvent1Name, kExt1Id, CreateHostSuffixFilter("google.com"),
  282. is_for_service_worker));
  283. listeners_->AddListener(CreateLazyListener(
  284. kEvent1Name, kExt1Id, CreateHostSuffixFilter("google.com"),
  285. is_for_service_worker));
  286. std::unique_ptr<EventListener> listener = CreateLazyListener(
  287. kEvent1Name, kExt1Id, CreateHostSuffixFilter("google.com"),
  288. is_for_service_worker);
  289. listeners_->RemoveListener(listener.get());
  290. std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  291. event->filter_info->url = GURL("http://www.google.com");
  292. std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  293. ASSERT_EQ(0u, targets.size());
  294. }
  295. TEST_F(EventListenerMapTest, HostSuffixFilterEquality) {
  296. std::unique_ptr<DictionaryValue> filter1(
  297. CreateHostSuffixFilter("google.com"));
  298. std::unique_ptr<DictionaryValue> filter2(
  299. CreateHostSuffixFilter("google.com"));
  300. ASSERT_EQ(*filter1, *filter2);
  301. }
  302. TEST_F(EventListenerMapTest, RemoveListenersForExtension) {
  303. for (bool is_for_service_worker : {false, true}) {
  304. listeners_->AddListener(CreateLazyListener(
  305. kEvent1Name, kExt1Id, CreateHostSuffixFilter("google.com"),
  306. is_for_service_worker));
  307. listeners_->AddListener(CreateLazyListener(
  308. kEvent2Name, kExt1Id, CreateHostSuffixFilter("google.com"),
  309. is_for_service_worker));
  310. }
  311. listeners_->RemoveListenersForExtension(kExt1Id);
  312. std::unique_ptr<Event> event1(CreateNamedEvent(kEvent1Name));
  313. event1->filter_info->url = GURL("http://www.google.com");
  314. std::set<const EventListener*> targets(
  315. listeners_->GetEventListeners(*event1));
  316. ASSERT_EQ(0u, targets.size());
  317. std::unique_ptr<Event> event2(CreateNamedEvent(kEvent2Name));
  318. event2->filter_info->url = GURL("http://www.google.com");
  319. targets = listeners_->GetEventListeners(*event2);
  320. ASSERT_EQ(0u, targets.size());
  321. }
  322. TEST_P(EventListenerMapWithContextTest, AddExistingFilteredListener) {
  323. const bool is_for_service_worker = GetParam();
  324. bool first_new = listeners_->AddListener(CreateLazyListener(
  325. kEvent1Name, kExt1Id, CreateHostSuffixFilter("google.com"),
  326. is_for_service_worker));
  327. bool second_new = listeners_->AddListener(CreateLazyListener(
  328. kEvent1Name, kExt1Id, CreateHostSuffixFilter("google.com"),
  329. is_for_service_worker));
  330. ASSERT_TRUE(first_new);
  331. ASSERT_FALSE(second_new);
  332. }
  333. void EventListenerMapTest::TestAddExistingUnfilteredListener(
  334. const EventListenerConstructor& constructor) {
  335. bool first_add = listeners_->AddListener(constructor.Run(
  336. kEvent1Name, nullptr, std::make_unique<base::DictionaryValue>()));
  337. bool second_add = listeners_->AddListener(constructor.Run(
  338. kEvent1Name, nullptr, std::make_unique<base::DictionaryValue>()));
  339. std::unique_ptr<EventListener> listener(constructor.Run(
  340. kEvent1Name, nullptr, std::make_unique<base::DictionaryValue>()));
  341. bool first_remove = listeners_->RemoveListener(listener.get());
  342. bool second_remove = listeners_->RemoveListener(listener.get());
  343. ASSERT_TRUE(first_add);
  344. ASSERT_FALSE(second_add);
  345. ASSERT_TRUE(first_remove);
  346. ASSERT_FALSE(second_remove);
  347. }
  348. TEST_F(EventListenerMapTest, AddExistingUnfilteredListenerForExtensions) {
  349. TestAddExistingUnfilteredListener(
  350. base::BindRepeating(&CreateEventListenerForExtension, kExt1Id));
  351. }
  352. TEST_F(EventListenerMapTest, AddExistingUnfilteredListenerForURLs) {
  353. TestAddExistingUnfilteredListener(
  354. base::BindRepeating(&CreateEventListenerForURL, GURL(kURL)));
  355. }
  356. TEST_F(EventListenerMapTest,
  357. AddExistingUnfilteredListenerForExtensionServiceWorker) {
  358. TestAddExistingUnfilteredListener(base::BindRepeating(
  359. &CreateEventListenerForExtensionServiceWorker, kExt1Id));
  360. }
  361. TEST_F(EventListenerMapTest, RemovingRouters) {
  362. listeners_->AddListener(
  363. EventListener::ForExtension(kEvent1Name, kExt1Id, process_.get(),
  364. std::unique_ptr<DictionaryValue>()));
  365. listeners_->AddListener(
  366. EventListener::ForURL(kEvent1Name, GURL(kURL), process_.get(),
  367. std::unique_ptr<DictionaryValue>()));
  368. listeners_->AddListener(CreateEventListenerForExtensionServiceWorker(
  369. kExt1Id, kEvent1Name, process_.get(),
  370. std::unique_ptr<base::DictionaryValue>()));
  371. listeners_->RemoveListenersForProcess(process_.get());
  372. ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent1Name));
  373. }
  374. void EventListenerMapTest::TestHasListenerForEvent(
  375. const EventListenerConstructor& constructor) {
  376. ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent1Name));
  377. listeners_->AddListener(constructor.Run(
  378. kEvent1Name, process_.get(), std::make_unique<base::DictionaryValue>()));
  379. ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent2Name));
  380. ASSERT_TRUE(listeners_->HasListenerForEvent(kEvent1Name));
  381. listeners_->RemoveListenersForProcess(process_.get());
  382. ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent1Name));
  383. }
  384. TEST_F(EventListenerMapTest, HasListenerForEventForExtension) {
  385. TestHasListenerForEvent(
  386. base::BindRepeating(&CreateEventListenerForExtension, kExt1Id));
  387. }
  388. TEST_F(EventListenerMapTest, HasListenerForEventForURL) {
  389. TestHasListenerForEvent(
  390. base::BindRepeating(&CreateEventListenerForURL, GURL(kURL)));
  391. }
  392. TEST_F(EventListenerMapTest, HasListenerForEventForExtensionServiceWorker) {
  393. TestHasListenerForEvent(base::BindRepeating(
  394. &CreateEventListenerForExtensionServiceWorker, kExt1Id));
  395. }
  396. TEST_F(EventListenerMapTest, HasListenerForExtension) {
  397. ASSERT_FALSE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name));
  398. auto create_event_listener = [&](bool is_for_service_worker, bool lazy) {
  399. auto filter = std::unique_ptr<base::DictionaryValue>();
  400. if (is_for_service_worker) {
  401. return EventListener::ForExtensionServiceWorker(
  402. kEvent1Name, kExt1Id, lazy ? nullptr : process_.get(),
  403. Extension::GetBaseURLFromExtensionId(kExt1Id),
  404. GetWorkerVersionId(lazy), GetWorkerThreadId(lazy), std::move(filter));
  405. }
  406. return EventListener::ForExtension(kEvent1Name, kExt1Id,
  407. lazy ? nullptr : process_.get(),
  408. std::move(filter));
  409. };
  410. for (bool is_for_service_worker : {false, true}) {
  411. // Non-lazy listener.
  412. listeners_->AddListener(
  413. create_event_listener(is_for_service_worker, false));
  414. // Lazy listener.
  415. listeners_->AddListener(create_event_listener(is_for_service_worker, true));
  416. ASSERT_FALSE(listeners_->HasListenerForExtension(kExt1Id, kEvent2Name));
  417. ASSERT_TRUE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name));
  418. ASSERT_FALSE(listeners_->HasListenerForExtension(kExt2Id, kEvent1Name));
  419. listeners_->RemoveListenersForProcess(process_.get());
  420. ASSERT_TRUE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name));
  421. listeners_->RemoveListenersForExtension(kExt1Id);
  422. ASSERT_FALSE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name));
  423. }
  424. }
  425. TEST_P(EventListenerMapWithContextTest, AddLazyListenersFromPreferences) {
  426. const bool is_for_service_worker = GetParam();
  427. struct TestCase {
  428. const std::string filter_host_suffix;
  429. const std::string url_of_event;
  430. } kTestCases[] = {
  431. {"google.com", "http://www.google.com"},
  432. {"yahoo.com", "http://www.yahoo.com"},
  433. };
  434. auto filter_list = std::make_unique<ListValue>();
  435. for (const TestCase& test_case : kTestCases)
  436. filter_list->Append(base::Value::FromUniquePtrValue(
  437. CreateHostSuffixFilter(test_case.filter_host_suffix)));
  438. DictionaryValue filtered_listeners;
  439. filtered_listeners.Set(kEvent1Name, std::move(filter_list));
  440. listeners_->LoadFilteredLazyListeners(kExt1Id, is_for_service_worker,
  441. filtered_listeners);
  442. // Matching filters.
  443. for (const TestCase& test_case : kTestCases) {
  444. SCOPED_TRACE(base::StringPrintf("host_suffix = %s, url = %s",
  445. test_case.filter_host_suffix.c_str(),
  446. test_case.url_of_event.c_str()));
  447. std::unique_ptr<Event> event(
  448. CreateEvent(kEvent1Name, GURL(test_case.url_of_event)));
  449. std::set<const EventListener*> targets(
  450. listeners_->GetEventListeners(*event));
  451. ASSERT_EQ(1u, targets.size());
  452. EXPECT_TRUE(
  453. CreateLazyListener(kEvent1Name, kExt1Id,
  454. CreateHostSuffixFilter(test_case.filter_host_suffix),
  455. is_for_service_worker)
  456. ->Equals(*targets.begin()));
  457. }
  458. // Non-matching filter.
  459. {
  460. std::unique_ptr<Event> event(
  461. CreateEvent(kEvent1Name, GURL("http://does_not_match.com")));
  462. std::set<const EventListener*> targets(
  463. listeners_->GetEventListeners(*event));
  464. EXPECT_EQ(0u, targets.size());
  465. }
  466. }
  467. TEST_F(EventListenerMapTest, CorruptedExtensionPrefsShouldntCrash) {
  468. DictionaryValue filtered_listeners;
  469. // kEvent1Name should be associated with a list, not a dictionary.
  470. filtered_listeners.Set(kEvent1Name, CreateHostSuffixFilter("google.com"));
  471. listeners_->LoadFilteredLazyListeners(kExt1Id, false, filtered_listeners);
  472. listeners_->LoadFilteredLazyListeners(kExt1Id, true, filtered_listeners);
  473. std::unique_ptr<Event> event(
  474. CreateEvent(kEvent1Name, GURL("http://www.google.com")));
  475. std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  476. ASSERT_EQ(0u, targets.size());
  477. }
  478. INSTANTIATE_TEST_SUITE_P(NonServiceWorker,
  479. EventListenerMapWithContextTest,
  480. testing::Values(false));
  481. INSTANTIATE_TEST_SUITE_P(ServiceWorker,
  482. EventListenerMapWithContextTest,
  483. testing::Values(true));
  484. } // namespace
  485. } // namespace extensions