blob: 007ca7ad428d91ad4f05eed740b9b7afac81505c [file] [log] [blame]
[email protected]c761a962013-11-20 04:19:411// 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
[email protected]34423532013-11-21 18:13:105#include "extensions/browser/event_router.h"
[email protected]c761a962013-11-20 04:19:416
7#include <string>
8
[email protected]c1abb3232014-07-30 18:28:399#include "base/bind.h"
[email protected]c761a962013-11-20 04:19:4110#include "base/compiler_specific.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/values.h"
[email protected]b3c3fde2014-08-02 05:55:1713#include "content/public/browser/notification_service.h"
[email protected]a0e26d42013-11-20 07:04:0414#include "extensions/browser/event_listener_map.h"
[email protected]4243f9a2014-08-04 18:53:1215#include "extensions/browser/extensions_test.h"
[email protected]c761a962013-11-20 04:19:4116#include "testing/gtest/include/gtest/gtest.h"
17
18namespace extensions {
19
20namespace {
21
22// A simple mock to keep track of listener additions and removals.
23class MockEventRouterObserver : public EventRouter::Observer {
24 public:
25 MockEventRouterObserver()
26 : listener_added_count_(0),
27 listener_removed_count_(0) {}
28 virtual ~MockEventRouterObserver() {}
29
30 int listener_added_count() const { return listener_added_count_; }
31 int listener_removed_count() const { return listener_removed_count_; }
32 const std::string& last_event_name() const { return last_event_name_; }
33
34 void Reset() {
35 listener_added_count_ = 0;
36 listener_removed_count_ = 0;
37 last_event_name_.clear();
38 }
39
40 // EventRouter::Observer overrides:
dcheng9168b2f2014-10-21 12:38:2441 void OnListenerAdded(const EventListenerInfo& details) override {
[email protected]c761a962013-11-20 04:19:4142 listener_added_count_++;
43 last_event_name_ = details.event_name;
44 }
45
dcheng9168b2f2014-10-21 12:38:2446 void OnListenerRemoved(const EventListenerInfo& details) override {
[email protected]c761a962013-11-20 04:19:4147 listener_removed_count_++;
48 last_event_name_ = details.event_name;
49 }
50
51 private:
52 int listener_added_count_;
53 int listener_removed_count_;
54 std::string last_event_name_;
55
56 DISALLOW_COPY_AND_ASSIGN(MockEventRouterObserver);
57};
58
[email protected]c1abb3232014-07-30 18:28:3959typedef base::Callback<scoped_ptr<EventListener>(
60 const std::string&, // event_name
61 content::RenderProcessHost*, // process
62 base::DictionaryValue* // filter (takes ownership)
63 )> EventListenerConstructor;
64
65scoped_ptr<EventListener> CreateEventListenerForExtension(
66 const std::string& extension_id,
67 const std::string& event_name,
68 content::RenderProcessHost* process,
69 base::DictionaryValue* filter) {
70 return EventListener::ForExtension(
71 event_name, extension_id, process, make_scoped_ptr(filter));
72}
73
74scoped_ptr<EventListener> CreateEventListenerForURL(
75 const GURL& listener_url,
76 const std::string& event_name,
77 content::RenderProcessHost* process,
78 base::DictionaryValue* filter) {
79 return EventListener::ForURL(
80 event_name, listener_url, process, make_scoped_ptr(filter));
81}
82
[email protected]c761a962013-11-20 04:19:4183} // namespace
84
[email protected]4243f9a2014-08-04 18:53:1285class EventRouterTest : public ExtensionsTest {
[email protected]b3c3fde2014-08-02 05:55:1786 public:
87 EventRouterTest()
88 : notification_service_(content::NotificationService::Create()) {}
89
[email protected]c1abb3232014-07-30 18:28:3990 protected:
91 // Tests adding and removing observers from EventRouter.
92 void RunEventRouterObserverTest(const EventListenerConstructor& constructor);
[email protected]b3c3fde2014-08-02 05:55:1793
94 private:
95 scoped_ptr<content::NotificationService> notification_service_;
96
97 DISALLOW_COPY_AND_ASSIGN(EventRouterTest);
[email protected]c1abb3232014-07-30 18:28:3998};
[email protected]c761a962013-11-20 04:19:4199
100TEST_F(EventRouterTest, GetBaseEventName) {
101 // Normal event names are passed through unchanged.
102 EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar"));
103
104 // Sub-events are converted to the part before the slash.
105 EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar/123"));
106}
107
108// Tests adding and removing observers from EventRouter.
[email protected]c1abb3232014-07-30 18:28:39109void EventRouterTest::RunEventRouterObserverTest(
110 const EventListenerConstructor& constructor) {
[email protected]c761a962013-11-20 04:19:41111 EventRouter router(NULL, NULL);
[email protected]c1abb3232014-07-30 18:28:39112 scoped_ptr<EventListener> listener =
113 constructor.Run("event_name", NULL, new base::DictionaryValue());
[email protected]c761a962013-11-20 04:19:41114
115 // Add/remove works without any observers.
[email protected]c1abb3232014-07-30 18:28:39116 router.OnListenerAdded(listener.get());
117 router.OnListenerRemoved(listener.get());
[email protected]c761a962013-11-20 04:19:41118
119 // Register observers that both match and don't match the event above.
120 MockEventRouterObserver matching_observer;
121 router.RegisterObserver(&matching_observer, "event_name");
122 MockEventRouterObserver non_matching_observer;
123 router.RegisterObserver(&non_matching_observer, "other");
124
125 // Adding a listener notifies the appropriate observers.
[email protected]c1abb3232014-07-30 18:28:39126 router.OnListenerAdded(listener.get());
[email protected]c761a962013-11-20 04:19:41127 EXPECT_EQ(1, matching_observer.listener_added_count());
128 EXPECT_EQ(0, non_matching_observer.listener_added_count());
129
130 // Removing a listener notifies the appropriate observers.
[email protected]c1abb3232014-07-30 18:28:39131 router.OnListenerRemoved(listener.get());
[email protected]c761a962013-11-20 04:19:41132 EXPECT_EQ(1, matching_observer.listener_removed_count());
133 EXPECT_EQ(0, non_matching_observer.listener_removed_count());
134
135 // Adding the listener again notifies again.
[email protected]c1abb3232014-07-30 18:28:39136 router.OnListenerAdded(listener.get());
[email protected]c761a962013-11-20 04:19:41137 EXPECT_EQ(2, matching_observer.listener_added_count());
138 EXPECT_EQ(0, non_matching_observer.listener_added_count());
139
140 // Removing the listener again notifies again.
[email protected]c1abb3232014-07-30 18:28:39141 router.OnListenerRemoved(listener.get());
[email protected]c761a962013-11-20 04:19:41142 EXPECT_EQ(2, matching_observer.listener_removed_count());
143 EXPECT_EQ(0, non_matching_observer.listener_removed_count());
144
145 // Adding a listener with a sub-event notifies the main observer with
146 // proper details.
147 matching_observer.Reset();
[email protected]c1abb3232014-07-30 18:28:39148 scoped_ptr<EventListener> sub_event_listener =
149 constructor.Run("event_name/1", NULL, new base::DictionaryValue());
150 router.OnListenerAdded(sub_event_listener.get());
[email protected]c761a962013-11-20 04:19:41151 EXPECT_EQ(1, matching_observer.listener_added_count());
152 EXPECT_EQ(0, matching_observer.listener_removed_count());
153 EXPECT_EQ("event_name/1", matching_observer.last_event_name());
154
155 // Ditto for removing the listener.
156 matching_observer.Reset();
[email protected]c1abb3232014-07-30 18:28:39157 router.OnListenerRemoved(sub_event_listener.get());
[email protected]c761a962013-11-20 04:19:41158 EXPECT_EQ(0, matching_observer.listener_added_count());
159 EXPECT_EQ(1, matching_observer.listener_removed_count());
160 EXPECT_EQ("event_name/1", matching_observer.last_event_name());
161}
162
[email protected]c1abb3232014-07-30 18:28:39163TEST_F(EventRouterTest, EventRouterObserverForExtensions) {
164 RunEventRouterObserverTest(
165 base::Bind(&CreateEventListenerForExtension, "extension_id"));
166}
167
168TEST_F(EventRouterTest, EventRouterObserverForURLs) {
169 RunEventRouterObserverTest(
170 base::Bind(&CreateEventListenerForURL, GURL("http://google.com/path")));
171}
172
[email protected]c761a962013-11-20 04:19:41173} // namespace extensions