1// Copyright (c) 2012 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 5#include "base/memory/scoped_ptr.h" 6#include "base/values.h" 7#include "extensions/common/event_filter.h" 8#include "extensions/common/event_filtering_info.h" 9#include "extensions/common/event_matcher.h" 10#include "ipc/ipc_message.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13namespace extensions { 14 15class EventFilterUnittest : public testing::Test { 16 public: 17 EventFilterUnittest() { 18 google_event_.SetURL(GURL("http://google.com")); 19 yahoo_event_.SetURL(GURL("http://yahoo.com")); 20 random_url_event_.SetURL(GURL("http://www.something-else.com")); 21 empty_url_event_.SetURL(GURL()); 22 } 23 24 protected: 25 scoped_ptr<base::Value> HostSuffixDict(const std::string& host_suffix) { 26 scoped_ptr<base::DictionaryValue> dict(new DictionaryValue()); 27 dict->Set("hostSuffix", base::Value::CreateStringValue(host_suffix)); 28 return scoped_ptr<base::Value>(dict.release()); 29 } 30 31 scoped_ptr<base::ListValue> ValueAsList(scoped_ptr<base::Value> value) { 32 scoped_ptr<base::ListValue> result(new base::ListValue()); 33 result->Append(value.release()); 34 return result.Pass(); 35 } 36 37 scoped_ptr<EventMatcher> AllURLs() { 38 return scoped_ptr<EventMatcher>(new EventMatcher( 39 scoped_ptr<DictionaryValue>(new DictionaryValue), MSG_ROUTING_NONE)); 40 } 41 42 scoped_ptr<EventMatcher> HostSuffixMatcher(const std::string& host_suffix) { 43 return MatcherFromURLFilterList(ValueAsList(HostSuffixDict(host_suffix))); 44 } 45 46 scoped_ptr<EventMatcher> MatcherFromURLFilterList( 47 scoped_ptr<ListValue> url_filter_list) { 48 scoped_ptr<DictionaryValue> filter_dict(new DictionaryValue); 49 filter_dict->Set("url", url_filter_list.release()); 50 return scoped_ptr<EventMatcher>( 51 new EventMatcher(filter_dict.Pass(), MSG_ROUTING_NONE)); 52 } 53 54 EventFilter event_filter_; 55 EventFilteringInfo empty_event_; 56 EventFilteringInfo google_event_; 57 EventFilteringInfo yahoo_event_; 58 EventFilteringInfo random_url_event_; 59 EventFilteringInfo empty_url_event_; 60}; 61 62TEST_F(EventFilterUnittest, NoMatchersMatchIfEmpty) { 63 std::set<int> matches = event_filter_.MatchEvent("some-event", 64 empty_event_, 65 MSG_ROUTING_NONE); 66 ASSERT_EQ(0u, matches.size()); 67} 68 69TEST_F(EventFilterUnittest, AddingEventMatcherDoesntCrash) { 70 event_filter_.AddEventMatcher("event1", AllURLs()); 71} 72 73TEST_F(EventFilterUnittest, 74 DontMatchAgainstMatchersForDifferentEvents) { 75 event_filter_.AddEventMatcher("event1", AllURLs()); 76 std::set<int> matches = event_filter_.MatchEvent("event2", 77 empty_event_, 78 MSG_ROUTING_NONE); 79 ASSERT_EQ(0u, matches.size()); 80} 81 82TEST_F(EventFilterUnittest, DoMatchAgainstMatchersForSameEvent) { 83 int id = event_filter_.AddEventMatcher("event1", AllURLs()); 84 std::set<int> matches = event_filter_.MatchEvent("event1", 85 google_event_, MSG_ROUTING_NONE); 86 ASSERT_EQ(1u, matches.size()); 87 ASSERT_EQ(1u, matches.count(id)); 88} 89 90TEST_F(EventFilterUnittest, DontMatchUnlessMatcherMatches) { 91 EventFilteringInfo info; 92 info.SetURL(GURL("http://www.yahoo.com")); 93 event_filter_.AddEventMatcher("event1", HostSuffixMatcher("google.com")); 94 std::set<int> matches = event_filter_.MatchEvent( 95 "event1", info, MSG_ROUTING_NONE); 96 ASSERT_TRUE(matches.empty()); 97} 98 99TEST_F(EventFilterUnittest, RemovingAnEventMatcherStopsItMatching) { 100 int id = event_filter_.AddEventMatcher("event1", AllURLs()); 101 event_filter_.RemoveEventMatcher(id); 102 std::set<int> matches = event_filter_.MatchEvent("event1", 103 empty_event_, 104 MSG_ROUTING_NONE); 105 ASSERT_TRUE(matches.empty()); 106} 107 108TEST_F(EventFilterUnittest, MultipleEventMatches) { 109 int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); 110 int id2 = event_filter_.AddEventMatcher("event1", AllURLs()); 111 std::set<int> matches = event_filter_.MatchEvent("event1", 112 google_event_, MSG_ROUTING_NONE); 113 ASSERT_EQ(2u, matches.size()); 114 ASSERT_EQ(1u, matches.count(id1)); 115 ASSERT_EQ(1u, matches.count(id2)); 116} 117 118TEST_F(EventFilterUnittest, TestURLMatching) { 119 EventFilteringInfo info; 120 info.SetURL(GURL("http://www.google.com")); 121 int id = event_filter_.AddEventMatcher("event1", 122 HostSuffixMatcher("google.com")); 123 std::set<int> matches = event_filter_.MatchEvent( 124 "event1", info, MSG_ROUTING_NONE); 125 ASSERT_EQ(1u, matches.size()); 126 ASSERT_EQ(1u, matches.count(id)); 127} 128 129TEST_F(EventFilterUnittest, TestMultipleURLFiltersMatchOnAny) { 130 scoped_ptr<base::ListValue> filters(new base::ListValue()); 131 filters->Append(HostSuffixDict("google.com").release()); 132 filters->Append(HostSuffixDict("yahoo.com").release()); 133 134 scoped_ptr<EventMatcher> matcher(MatcherFromURLFilterList(filters.Pass())); 135 int id = event_filter_.AddEventMatcher("event1", matcher.Pass()); 136 137 { 138 std::set<int> matches = event_filter_.MatchEvent("event1", 139 google_event_, MSG_ROUTING_NONE); 140 ASSERT_EQ(1u, matches.size()); 141 ASSERT_EQ(1u, matches.count(id)); 142 } 143 { 144 std::set<int> matches = event_filter_.MatchEvent("event1", 145 yahoo_event_, MSG_ROUTING_NONE); 146 ASSERT_EQ(1u, matches.size()); 147 ASSERT_EQ(1u, matches.count(id)); 148 } 149 { 150 std::set<int> matches = event_filter_.MatchEvent("event1", 151 random_url_event_, MSG_ROUTING_NONE); 152 ASSERT_EQ(0u, matches.size()); 153 } 154} 155 156TEST_F(EventFilterUnittest, TestStillMatchesAfterRemoval) { 157 int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); 158 int id2 = event_filter_.AddEventMatcher("event1", AllURLs()); 159 160 event_filter_.RemoveEventMatcher(id1); 161 { 162 std::set<int> matches = event_filter_.MatchEvent("event1", 163 google_event_, MSG_ROUTING_NONE); 164 ASSERT_EQ(1u, matches.size()); 165 ASSERT_EQ(1u, matches.count(id2)); 166 } 167} 168 169TEST_F(EventFilterUnittest, TestMatchesOnlyAgainstPatternsForCorrectEvent) { 170 int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); 171 event_filter_.AddEventMatcher("event2", AllURLs()); 172 173 { 174 std::set<int> matches = event_filter_.MatchEvent("event1", 175 google_event_, MSG_ROUTING_NONE); 176 ASSERT_EQ(1u, matches.size()); 177 ASSERT_EQ(1u, matches.count(id1)); 178 } 179} 180 181TEST_F(EventFilterUnittest, TestGetMatcherCountForEvent) { 182 ASSERT_EQ(0, event_filter_.GetMatcherCountForEvent("event1")); 183 int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); 184 ASSERT_EQ(1, event_filter_.GetMatcherCountForEvent("event1")); 185 int id2 = event_filter_.AddEventMatcher("event1", AllURLs()); 186 ASSERT_EQ(2, event_filter_.GetMatcherCountForEvent("event1")); 187 event_filter_.RemoveEventMatcher(id1); 188 ASSERT_EQ(1, event_filter_.GetMatcherCountForEvent("event1")); 189 event_filter_.RemoveEventMatcher(id2); 190 ASSERT_EQ(0, event_filter_.GetMatcherCountForEvent("event1")); 191} 192 193TEST_F(EventFilterUnittest, RemoveEventMatcherReturnsEventName) { 194 int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); 195 int id2 = event_filter_.AddEventMatcher("event1", AllURLs()); 196 int id3 = event_filter_.AddEventMatcher("event2", AllURLs()); 197 198 ASSERT_EQ("event1", event_filter_.RemoveEventMatcher(id1)); 199 ASSERT_EQ("event1", event_filter_.RemoveEventMatcher(id2)); 200 ASSERT_EQ("event2", event_filter_.RemoveEventMatcher(id3)); 201} 202 203TEST_F(EventFilterUnittest, InvalidURLFilterCantBeAdded) { 204 scoped_ptr<base::ListValue> filter_list(new base::ListValue()); 205 filter_list->Append(new base::ListValue()); // Should be a dict. 206 scoped_ptr<EventMatcher> matcher(MatcherFromURLFilterList( 207 filter_list.Pass())); 208 int id1 = event_filter_.AddEventMatcher("event1", matcher.Pass()); 209 EXPECT_TRUE(event_filter_.IsURLMatcherEmpty()); 210 ASSERT_EQ(-1, id1); 211} 212 213TEST_F(EventFilterUnittest, EmptyListOfURLFiltersMatchesAllURLs) { 214 scoped_ptr<base::ListValue> filter_list(new base::ListValue()); 215 scoped_ptr<EventMatcher> matcher(MatcherFromURLFilterList( 216 scoped_ptr<ListValue>(new ListValue))); 217 int id = event_filter_.AddEventMatcher("event1", matcher.Pass()); 218 std::set<int> matches = event_filter_.MatchEvent("event1", 219 google_event_, MSG_ROUTING_NONE); 220 ASSERT_EQ(1u, matches.size()); 221 ASSERT_EQ(1u, matches.count(id)); 222} 223 224TEST_F(EventFilterUnittest, 225 InternalURLMatcherShouldBeEmptyWhenThereAreNoEventMatchers) { 226 ASSERT_TRUE(event_filter_.IsURLMatcherEmpty()); 227 int id = event_filter_.AddEventMatcher("event1", 228 HostSuffixMatcher("google.com")); 229 ASSERT_FALSE(event_filter_.IsURLMatcherEmpty()); 230 event_filter_.RemoveEventMatcher(id); 231 ASSERT_TRUE(event_filter_.IsURLMatcherEmpty()); 232} 233 234TEST_F(EventFilterUnittest, EmptyURLsShouldBeMatchedByEmptyURLFilters) { 235 int id = event_filter_.AddEventMatcher("event1", AllURLs()); 236 std::set<int> matches = event_filter_.MatchEvent( 237 "event1", empty_url_event_, MSG_ROUTING_NONE); 238 ASSERT_EQ(1u, matches.size()); 239 ASSERT_EQ(1u, matches.count(id)); 240} 241 242TEST_F(EventFilterUnittest, 243 EmptyURLsShouldBeMatchedByEmptyURLFiltersWithAnEmptyItem) { 244 scoped_ptr<EventMatcher> matcher(MatcherFromURLFilterList(ValueAsList( 245 scoped_ptr<Value>(new DictionaryValue())))); 246 int id = event_filter_.AddEventMatcher("event1", matcher.Pass()); 247 std::set<int> matches = event_filter_.MatchEvent( 248 "event1", empty_url_event_, MSG_ROUTING_NONE); 249 ASSERT_EQ(1u, matches.size()); 250 ASSERT_EQ(1u, matches.count(id)); 251} 252 253} // namespace extensions 254