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