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.
5 #include "chrome/browser/extensions/api/declarative_content/content_condition.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/test/values_test_util.h"
11 #include "base/values.h"
12 #include "chrome/browser/extensions/api/declarative_content/content_constants.h"
13 #include "components/url_matcher/url_matcher.h"
14 #include "extensions/common/extension.h"
15 #include "extensions/common/extension_builder.h"
16 #include "extensions/common/value_builder.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
21 using testing::ElementsAre
;
22 using testing::HasSubstr
;
23 using url_matcher::URLMatcher
;
24 using url_matcher::URLMatcherConditionSet
;
26 namespace extensions
{
30 scoped_refptr
<Extension
> CreateExtensionWithBookmarksPermission(
31 bool include_bookmarks
) {
32 ListBuilder permissions
;
33 permissions
.Append("declarativeContent");
34 if (include_bookmarks
)
35 permissions
.Append("bookmarks");
36 return ExtensionBuilder()
37 .SetManifest(DictionaryBuilder()
38 .Set("name", "Test extension")
39 .Set("version", "1.0")
40 .Set("manifest_version", 2)
41 .Set("permissions", permissions
))
47 TEST(DeclarativeContentConditionTest
, UnknownConditionName
) {
50 scoped_ptr
<ContentCondition
> result
= ContentCondition::Create(
52 matcher
.condition_factory(),
53 *base::test::ParseJson(
55 " \"invalid\": \"foobar\",\n"
56 " \"instanceType\": \"declarativeContent.PageStateMatcher\",\n"
59 EXPECT_THAT(error
, HasSubstr("Unknown condition attribute"));
62 EXPECT_TRUE(matcher
.IsEmpty()) << "Errors shouldn't add URL conditions";
65 TEST(DeclarativeContentConditionTest
, WrongPageUrlDatatype
) {
68 scoped_ptr
<ContentCondition
> result
= ContentCondition::Create(
70 matcher
.condition_factory(),
71 *base::test::ParseJson(
74 " \"instanceType\": \"declarativeContent.PageStateMatcher\",\n"
77 EXPECT_THAT(error
, HasSubstr("invalid type"));
80 EXPECT_TRUE(matcher
.IsEmpty()) << "Errors shouldn't add URL conditions";
83 TEST(DeclarativeContentConditionTest
, WrongCssDatatype
) {
86 scoped_ptr
<ContentCondition
> result
= ContentCondition::Create(
88 matcher
.condition_factory(),
89 *base::test::ParseJson(
91 " \"css\": \"selector\",\n"
92 " \"instanceType\": \"declarativeContent.PageStateMatcher\",\n"
95 EXPECT_THAT(error
, HasSubstr("invalid type"));
98 EXPECT_TRUE(matcher
.IsEmpty()) << "Errors shouldn't add URL conditions";
101 TEST(DeclarativeContentConditionTest
, ConditionWithUrlAndCss
) {
103 scoped_refptr
<Extension
> extension
=
104 CreateExtensionWithBookmarksPermission(false);
107 scoped_ptr
<ContentCondition
> result
= ContentCondition::Create(
109 matcher
.condition_factory(),
110 *base::test::ParseJson(
112 " \"instanceType\": \"declarativeContent.PageStateMatcher\",\n"
113 " \"pageUrl\": {\"hostSuffix\": \"example.com\"},\n"
114 " \"css\": [\"input\"],\n"
117 EXPECT_EQ("", error
);
120 URLMatcherConditionSet::Vector all_new_condition_sets
;
121 all_new_condition_sets
.push_back(result
->url_matcher_condition_set());
122 matcher
.AddConditionSets(all_new_condition_sets
);
123 EXPECT_FALSE(matcher
.IsEmpty());
125 RendererContentMatchData match_data
;
126 match_data
.css_selectors
.insert("input");
128 EXPECT_THAT(matcher
.MatchURL(GURL("http://google.com/")),
129 ElementsAre(/*empty*/));
130 match_data
.page_url_matches
= matcher
.MatchURL(
131 GURL("http://www.example.com/foobar"));
132 EXPECT_THAT(match_data
.page_url_matches
,
133 ElementsAre(result
->url_matcher_condition_set()->id()));
135 EXPECT_TRUE(result
->IsFulfilled(match_data
));
137 match_data
.css_selectors
.clear();
138 match_data
.css_selectors
.insert("body");
139 EXPECT_FALSE(result
->IsFulfilled(match_data
));
142 // Tests that condition with isBookmarked requires "bookmarks" permission.
143 TEST(DeclarativeContentConditionTest
, IsBookmarkedRequiresBookmarkPermission
) {
145 scoped_refptr
<Extension
> extension
=
146 CreateExtensionWithBookmarksPermission(false);
149 scoped_ptr
<ContentCondition
> result
= ContentCondition::Create(
151 matcher
.condition_factory(),
152 *base::test::ParseJson(
154 " \"isBookmarked\": true,\n"
155 " \"instanceType\": \"declarativeContent.PageStateMatcher\",\n"
158 EXPECT_THAT(error
, HasSubstr("requires 'bookmarks' permission"));
159 ASSERT_FALSE(result
);
162 // Tests an invalid isBookmarked value type.
163 TEST(DeclarativeContentConditionTest
, WrongIsBookmarkedDatatype
) {
165 scoped_refptr
<Extension
> extension
=
166 CreateExtensionWithBookmarksPermission(true);
169 scoped_ptr
<ContentCondition
> result
= ContentCondition::Create(
171 matcher
.condition_factory(),
172 *base::test::ParseJson(
174 " \"isBookmarked\": [],\n"
175 " \"instanceType\": \"declarativeContent.PageStateMatcher\",\n"
178 EXPECT_THAT(error
, HasSubstr("invalid type"));
179 EXPECT_FALSE(result
);
182 // Tests isBookmark: true.
183 TEST(DeclarativeContentConditionTest
, IsBookmarkedTrue
) {
185 scoped_refptr
<Extension
> extension
=
186 CreateExtensionWithBookmarksPermission(true);
189 scoped_ptr
<ContentCondition
> result
= ContentCondition::Create(
191 matcher
.condition_factory(),
192 *base::test::ParseJson(
194 " \"isBookmarked\": true,\n"
195 " \"instanceType\": \"declarativeContent.PageStateMatcher\",\n"
198 EXPECT_EQ("", error
);
201 // TODO(wittman): Getting/adding URL matcher condition sets should not be
202 // necessary when we haven't specified any pageUrl conditions. Remove this and
203 // the MatchURL call below, and refactor ContentCondition and
204 // ChromeContentRulesRegistry to not depend on a ContentCondition always
205 // having a URL matcher condition.
206 URLMatcherConditionSet::Vector all_new_condition_sets
;
207 all_new_condition_sets
.push_back(result
->url_matcher_condition_set());
208 matcher
.AddConditionSets(all_new_condition_sets
);
210 RendererContentMatchData data
;
211 data
.page_url_matches
= matcher
.MatchURL(GURL("http://test/"));
212 data
.is_bookmarked
= true;
213 EXPECT_TRUE(result
->IsFulfilled(data
));
214 data
.is_bookmarked
= false;
215 EXPECT_FALSE(result
->IsFulfilled(data
));
218 // Tests isBookmark: false.
219 TEST(DeclarativeContentConditionTest
, IsBookmarkedFalse
) {
221 scoped_refptr
<Extension
> extension
=
222 CreateExtensionWithBookmarksPermission(true);
225 scoped_ptr
<ContentCondition
> result
= ContentCondition::Create(
227 matcher
.condition_factory(),
228 *base::test::ParseJson(
230 " \"isBookmarked\": false,\n"
231 " \"instanceType\": \"declarativeContent.PageStateMatcher\",\n"
234 EXPECT_EQ("", error
);
237 // TODO(wittman): Getting/adding URL matcher condition sets should not be
238 // necessary when we haven't specified any pageUrl conditions. Remove this and
239 // the MatchURL call below, and refactor ContentCondition and
240 // ChromeContentRulesRegistry to not depend on a ContentCondition always
241 // having a URL matcher condition.
242 URLMatcherConditionSet::Vector all_new_condition_sets
;
243 all_new_condition_sets
.push_back(result
->url_matcher_condition_set());
244 matcher
.AddConditionSets(all_new_condition_sets
);
246 RendererContentMatchData data
;
247 data
.page_url_matches
= matcher
.MatchURL(GURL("http://test/"));
248 data
.is_bookmarked
= true;
249 EXPECT_FALSE(result
->IsFulfilled(data
));
250 data
.is_bookmarked
= false;
251 EXPECT_TRUE(result
->IsFulfilled(data
));
254 } // namespace extensions