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.
5 #include "extensions/browser/event_listener_map.h"
7 #include "content/public/test/mock_render_process_host.h"
8 #include "content/public/test/test_browser_context.h"
9 #include "extensions/browser/event_router.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 using base::DictionaryValue
;
13 using base::ListValue
;
14 using base::StringValue
;
16 namespace extensions
{
20 const char kExt1Id
[] = "extension_1";
21 const char kExt2Id
[] = "extension_2";
22 const char kEvent1Name
[] = "event1";
23 const char kEvent2Name
[] = "event2";
25 class EmptyDelegate
: public EventListenerMap::Delegate
{
26 virtual void OnListenerAdded(const EventListener
* listener
) OVERRIDE
{};
27 virtual void OnListenerRemoved(const EventListener
* listener
) OVERRIDE
{};
30 class EventListenerMapUnittest
: public testing::Test
{
32 EventListenerMapUnittest()
33 : delegate_(new EmptyDelegate
),
34 listeners_(new EventListenerMap(delegate_
.get())),
35 browser_context_(new content::TestBrowserContext
),
36 process_(new content::MockRenderProcessHost(browser_context_
.get())) {
39 scoped_ptr
<DictionaryValue
> CreateHostSuffixFilter(
40 const std::string
& suffix
) {
41 scoped_ptr
<DictionaryValue
> filter(new DictionaryValue
);
42 scoped_ptr
<ListValue
> filter_list(new ListValue
);
43 scoped_ptr
<DictionaryValue
> filter_dict(new DictionaryValue
);
45 filter_dict
->Set("hostSuffix", new StringValue(suffix
));
47 filter_list
->Append(filter_dict
.release());
48 filter
->Set("url", filter_list
.release());
52 scoped_ptr
<Event
> CreateNamedEvent(const std::string
& event_name
) {
53 return CreateEvent(event_name
, GURL());
56 scoped_ptr
<Event
> CreateEvent(const std::string
& event_name
,
58 EventFilteringInfo info
;
60 scoped_ptr
<Event
> result(new Event(event_name
,
61 make_scoped_ptr(new ListValue()), NULL
, GURL(),
62 EventRouter::USER_GESTURE_UNKNOWN
, info
));
67 scoped_ptr
<EventListenerMap::Delegate
> delegate_
;
68 scoped_ptr
<EventListenerMap
> listeners_
;
69 scoped_ptr
<content::TestBrowserContext
> browser_context_
;
70 scoped_ptr
<content::MockRenderProcessHost
> process_
;
73 TEST_F(EventListenerMapUnittest
, UnfilteredEventsGoToAllListeners
) {
74 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
75 kEvent1Name
, kExt1Id
, NULL
, scoped_ptr
<DictionaryValue
>())));
77 scoped_ptr
<Event
> event(CreateNamedEvent(kEvent1Name
));
78 std::set
<const EventListener
*> targets(listeners_
->GetEventListeners(*event
));
79 ASSERT_EQ(1u, targets
.size());
82 TEST_F(EventListenerMapUnittest
, FilteredEventsGoToAllMatchingListeners
) {
83 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
84 kEvent1Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("google.com"))));
85 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
86 kEvent1Name
, kExt1Id
, NULL
, scoped_ptr
<DictionaryValue
>(
87 new DictionaryValue
))));
89 scoped_ptr
<Event
> event(CreateNamedEvent(kEvent1Name
));
90 event
->filter_info
.SetURL(GURL("http://www.google.com"));
91 std::set
<const EventListener
*> targets(listeners_
->GetEventListeners(*event
));
92 ASSERT_EQ(2u, targets
.size());
95 TEST_F(EventListenerMapUnittest
, FilteredEventsOnlyGoToMatchingListeners
) {
96 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
97 kEvent1Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("google.com"))));
98 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
99 kEvent1Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("yahoo.com"))));
101 scoped_ptr
<Event
> event(CreateNamedEvent(kEvent1Name
));
102 event
->filter_info
.SetURL(GURL("http://www.google.com"));
103 std::set
<const EventListener
*> targets(listeners_
->GetEventListeners(*event
));
104 ASSERT_EQ(1u, targets
.size());
107 TEST_F(EventListenerMapUnittest
, LazyAndUnlazyListenersGetReturned
) {
108 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
109 kEvent1Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("google.com"))));
111 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
112 kEvent1Name
, kExt1Id
, process_
.get(),
113 CreateHostSuffixFilter("google.com"))));
115 scoped_ptr
<Event
> event(CreateNamedEvent(kEvent1Name
));
116 event
->filter_info
.SetURL(GURL("http://www.google.com"));
117 std::set
<const EventListener
*> targets(listeners_
->GetEventListeners(*event
));
118 ASSERT_EQ(2u, targets
.size());
121 TEST_F(EventListenerMapUnittest
, TestRemovingByProcess
) {
122 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
123 kEvent1Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("google.com"))));
125 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
126 kEvent1Name
, kExt1Id
, process_
.get(),
127 CreateHostSuffixFilter("google.com"))));
129 listeners_
->RemoveListenersForProcess(process_
.get());
131 scoped_ptr
<Event
> event(CreateNamedEvent(kEvent1Name
));
132 event
->filter_info
.SetURL(GURL("http://www.google.com"));
133 std::set
<const EventListener
*> targets(listeners_
->GetEventListeners(*event
));
134 ASSERT_EQ(1u, targets
.size());
137 TEST_F(EventListenerMapUnittest
, TestRemovingByListener
) {
138 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
139 kEvent1Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("google.com"))));
141 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
142 kEvent1Name
, kExt1Id
, process_
.get(),
143 CreateHostSuffixFilter("google.com"))));
145 scoped_ptr
<EventListener
> listener(new EventListener(kEvent1Name
, kExt1Id
,
146 process_
.get(), CreateHostSuffixFilter("google.com")));
147 listeners_
->RemoveListener(listener
.get());
149 scoped_ptr
<Event
> event(CreateNamedEvent(kEvent1Name
));
150 event
->filter_info
.SetURL(GURL("http://www.google.com"));
151 std::set
<const EventListener
*> targets(listeners_
->GetEventListeners(*event
));
152 ASSERT_EQ(1u, targets
.size());
155 TEST_F(EventListenerMapUnittest
, TestLazyDoubleAddIsUndoneByRemove
) {
156 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
157 kEvent1Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("google.com"))));
158 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
159 kEvent1Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("google.com"))));
161 scoped_ptr
<EventListener
> listener(new EventListener(
162 kEvent1Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("google.com")));
163 listeners_
->RemoveListener(listener
.get());
165 scoped_ptr
<Event
> event(CreateNamedEvent(kEvent1Name
));
166 event
->filter_info
.SetURL(GURL("http://www.google.com"));
167 std::set
<const EventListener
*> targets(listeners_
->GetEventListeners(*event
));
168 ASSERT_EQ(0u, targets
.size());
171 TEST_F(EventListenerMapUnittest
, HostSuffixFilterEquality
) {
172 scoped_ptr
<DictionaryValue
> filter1(CreateHostSuffixFilter("google.com"));
173 scoped_ptr
<DictionaryValue
> filter2(CreateHostSuffixFilter("google.com"));
174 ASSERT_TRUE(filter1
->Equals(filter2
.get()));
177 TEST_F(EventListenerMapUnittest
, RemoveLazyListenersForExtension
) {
178 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
179 kEvent1Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("google.com"))));
180 listeners_
->AddListener(scoped_ptr
<EventListener
>(new EventListener(
181 kEvent2Name
, kExt1Id
, NULL
, CreateHostSuffixFilter("google.com"))));
183 listeners_
->RemoveLazyListenersForExtension(kExt1Id
);
185 scoped_ptr
<Event
> event(CreateNamedEvent(kEvent1Name
));
186 event
->filter_info
.SetURL(GURL("http://www.google.com"));
187 std::set
<const EventListener
*> targets(listeners_
->GetEventListeners(*event
));
188 ASSERT_EQ(0u, targets
.size());
190 event
->event_name
= kEvent2Name
;
191 targets
= listeners_
->GetEventListeners(*event
);
192 ASSERT_EQ(0u, targets
.size());
195 TEST_F(EventListenerMapUnittest
, AddExistingFilteredListener
) {
196 bool first_new
= listeners_
->AddListener(scoped_ptr
<EventListener
>(
197 new EventListener(kEvent1Name
, kExt1Id
, NULL
,
198 CreateHostSuffixFilter("google.com"))));
199 bool second_new
= listeners_
->AddListener(scoped_ptr
<EventListener
>(
200 new EventListener(kEvent1Name
, kExt1Id
, NULL
,
201 CreateHostSuffixFilter("google.com"))));
203 ASSERT_TRUE(first_new
);
204 ASSERT_FALSE(second_new
);
207 TEST_F(EventListenerMapUnittest
, AddExistingUnfilteredListener
) {
208 bool first_add
= listeners_
->AddListener(scoped_ptr
<EventListener
>(
209 new EventListener(kEvent1Name
, kExt1Id
, NULL
,
210 scoped_ptr
<DictionaryValue
>())));
211 bool second_add
= listeners_
->AddListener(scoped_ptr
<EventListener
>(
212 new EventListener(kEvent1Name
, kExt1Id
, NULL
,
213 scoped_ptr
<DictionaryValue
>())));
215 scoped_ptr
<EventListener
> listener(
216 new EventListener(kEvent1Name
, kExt1Id
, NULL
,
217 scoped_ptr
<DictionaryValue
>()));
218 bool first_remove
= listeners_
->RemoveListener(listener
.get());
219 bool second_remove
= listeners_
->RemoveListener(listener
.get());
221 ASSERT_TRUE(first_add
);
222 ASSERT_FALSE(second_add
);
223 ASSERT_TRUE(first_remove
);
224 ASSERT_FALSE(second_remove
);
227 TEST_F(EventListenerMapUnittest
, RemovingRouters
) {
228 listeners_
->AddListener(scoped_ptr
<EventListener
>(
229 new EventListener(kEvent1Name
, kExt1Id
, process_
.get(),
230 scoped_ptr
<DictionaryValue
>())));
231 listeners_
->RemoveListenersForProcess(process_
.get());
232 ASSERT_FALSE(listeners_
->HasListenerForEvent(kEvent1Name
));
235 TEST_F(EventListenerMapUnittest
, HasListenerForEvent
) {
236 ASSERT_FALSE(listeners_
->HasListenerForEvent(kEvent1Name
));
238 listeners_
->AddListener(scoped_ptr
<EventListener
>(
239 new EventListener(kEvent1Name
, kExt1Id
, process_
.get(),
240 scoped_ptr
<DictionaryValue
>())));
242 ASSERT_FALSE(listeners_
->HasListenerForEvent(kEvent2Name
));
243 ASSERT_TRUE(listeners_
->HasListenerForEvent(kEvent1Name
));
244 listeners_
->RemoveListenersForProcess(process_
.get());
245 ASSERT_FALSE(listeners_
->HasListenerForEvent(kEvent1Name
));
248 TEST_F(EventListenerMapUnittest
, HasListenerForExtension
) {
249 ASSERT_FALSE(listeners_
->HasListenerForExtension(kExt1Id
, kEvent1Name
));
251 // Non-lazy listener.
252 listeners_
->AddListener(scoped_ptr
<EventListener
>(
253 new EventListener(kEvent1Name
, kExt1Id
, process_
.get(),
254 scoped_ptr
<DictionaryValue
>())));
256 listeners_
->AddListener(scoped_ptr
<EventListener
>(
257 new EventListener(kEvent1Name
, kExt1Id
, NULL
,
258 scoped_ptr
<DictionaryValue
>())));
260 ASSERT_FALSE(listeners_
->HasListenerForExtension(kExt1Id
, kEvent2Name
));
261 ASSERT_TRUE(listeners_
->HasListenerForExtension(kExt1Id
, kEvent1Name
));
262 ASSERT_FALSE(listeners_
->HasListenerForExtension(kExt2Id
, kEvent1Name
));
263 listeners_
->RemoveListenersForProcess(process_
.get());
264 ASSERT_TRUE(listeners_
->HasListenerForExtension(kExt1Id
, kEvent1Name
));
265 listeners_
->RemoveLazyListenersForExtension(kExt1Id
);
266 ASSERT_FALSE(listeners_
->HasListenerForExtension(kExt1Id
, kEvent1Name
));
269 TEST_F(EventListenerMapUnittest
, AddLazyListenersFromPreferences
) {
270 scoped_ptr
<DictionaryValue
> filter1(CreateHostSuffixFilter("google.com"));
271 scoped_ptr
<DictionaryValue
> filter2(CreateHostSuffixFilter("yahoo.com"));
273 DictionaryValue filtered_listeners
;
274 ListValue
* filter_list
= new ListValue();
275 filtered_listeners
.Set(kEvent1Name
, filter_list
);
277 filter_list
->Append(filter1
.release());
278 filter_list
->Append(filter2
.release());
280 listeners_
->LoadFilteredLazyListeners(kExt1Id
, filtered_listeners
);
282 scoped_ptr
<Event
> event(CreateEvent(kEvent1Name
,
283 GURL("http://www.google.com")));
284 std::set
<const EventListener
*> targets(listeners_
->GetEventListeners(*event
));
285 ASSERT_EQ(1u, targets
.size());
286 scoped_ptr
<EventListener
> listener(new EventListener(kEvent1Name
, kExt1Id
,
287 NULL
, CreateHostSuffixFilter("google.com")));
288 ASSERT_TRUE((*targets
.begin())->Equals(listener
.get()));
291 TEST_F(EventListenerMapUnittest
, CorruptedExtensionPrefsShouldntCrash
) {
292 scoped_ptr
<DictionaryValue
> filter1(CreateHostSuffixFilter("google.com"));
294 DictionaryValue filtered_listeners
;
295 // kEvent1Name should be associated with a list, not a dictionary.
296 filtered_listeners
.Set(kEvent1Name
, filter1
.release());
298 listeners_
->LoadFilteredLazyListeners(kExt1Id
, filtered_listeners
);
300 scoped_ptr
<Event
> event(CreateEvent(kEvent1Name
,
301 GURL("http://www.google.com")));
302 std::set
<const EventListener
*> targets(listeners_
->GetEventListeners(*event
));
303 ASSERT_EQ(0u, targets
.size());
308 } // namespace extensions