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/chrome_content_rules_registry.h"
10 #include "base/test/values_test_util.h"
11 #include "chrome/browser/extensions/api/declarative_content/content_predicate.h"
12 #include "chrome/browser/extensions/api/declarative_content/content_predicate_evaluator.h"
13 #include "chrome/browser/extensions/test_extension_environment.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "content/public/browser/navigation_details.h"
16 #include "content/public/browser/web_contents.h"
17 #include "content/public/common/frame_navigate_params.h"
18 #include "extensions/common/extension.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace extensions
{
25 class TestPredicateEvaluator
;
27 class TestPredicate
: public ContentPredicate
{
29 explicit TestPredicate(ContentPredicateEvaluator
* evaluator
)
30 : evaluator_(evaluator
) {
33 ContentPredicateEvaluator
* GetEvaluator() const override
{
38 ContentPredicateEvaluator
* evaluator_
;
40 DISALLOW_COPY_AND_ASSIGN(TestPredicate
);
43 class TestPredicateEvaluator
: public ContentPredicateEvaluator
{
45 explicit TestPredicateEvaluator(ContentPredicateEvaluator::Delegate
* delegate
)
46 : delegate_(delegate
),
47 contents_for_next_operation_evaluation_(nullptr),
48 next_evaluation_result_(false) {
51 std::string
GetPredicateApiAttributeName() const override
{
52 return "test_predicate";
55 scoped_ptr
<const ContentPredicate
> CreatePredicate(
56 const Extension
* extension
,
57 const base::Value
& value
,
58 std::string
* error
) override
{
59 RequestEvaluationIfSpecified();
60 return make_scoped_ptr(new TestPredicate(this));
64 const std::map
<const void*,
65 std::vector
<const ContentPredicate
*>>& predicates
) override
{
66 RequestEvaluationIfSpecified();
69 void StopTrackingPredicates(
70 const std::vector
<const void*>& predicate_groups
) override
{
71 RequestEvaluationIfSpecified();
74 void TrackForWebContents(content::WebContents
* contents
) override
{
75 RequestEvaluationIfSpecified();
78 void OnWebContentsNavigation(
79 content::WebContents
* contents
,
80 const content::LoadCommittedDetails
& details
,
81 const content::FrameNavigateParams
& params
) override
{
82 RequestEvaluationIfSpecified();
85 bool EvaluatePredicate(const ContentPredicate
* predicate
,
86 content::WebContents
* tab
) const override
{
87 bool result
= next_evaluation_result_
;
88 next_evaluation_result_
= false;
92 void RequestImmediateEvaluation(content::WebContents
* contents
,
93 bool evaluation_result
) {
94 next_evaluation_result_
= evaluation_result
;
95 delegate_
->RequestEvaluation(contents
);
98 void RequestEvaluationOnNextOperation(content::WebContents
* contents
,
99 bool evaluation_result
) {
100 contents_for_next_operation_evaluation_
= contents
;
101 next_evaluation_result_
= evaluation_result
;
105 void RequestEvaluationIfSpecified() {
106 if (contents_for_next_operation_evaluation_
)
107 delegate_
->RequestEvaluation(contents_for_next_operation_evaluation_
);
108 contents_for_next_operation_evaluation_
= nullptr;
111 ContentPredicateEvaluator::Delegate
* delegate_
;
112 content::WebContents
* contents_for_next_operation_evaluation_
;
113 mutable bool next_evaluation_result_
;
115 DISALLOW_COPY_AND_ASSIGN(TestPredicateEvaluator
);
118 // Create the test evaluator and set |evaluator| to its pointer.
119 ScopedVector
<ContentPredicateEvaluator
> CreateTestEvaluator(
120 TestPredicateEvaluator
** evaluator
,
121 ContentPredicateEvaluator::Delegate
* delegate
) {
122 ScopedVector
<ContentPredicateEvaluator
> evaluators
;
123 *evaluator
= new TestPredicateEvaluator(delegate
);
124 evaluators
.push_back(*evaluator
);
125 return evaluators
.Pass();
130 class DeclarativeChromeContentRulesRegistryTest
: public testing::Test
{
132 DeclarativeChromeContentRulesRegistryTest() {}
135 TestExtensionEnvironment
* env() { return &env_
; }
138 TestExtensionEnvironment env_
;
140 DISALLOW_COPY_AND_ASSIGN(DeclarativeChromeContentRulesRegistryTest
);
143 TEST_F(DeclarativeChromeContentRulesRegistryTest
, ActiveRulesDoesntGrow
) {
144 TestPredicateEvaluator
* evaluator
= nullptr;
145 scoped_refptr
<ChromeContentRulesRegistry
> registry(
146 new ChromeContentRulesRegistry(env()->profile(), nullptr,
147 base::Bind(&CreateTestEvaluator
,
150 EXPECT_EQ(0u, registry
->GetActiveRulesCountForTesting());
152 scoped_ptr
<content::WebContents
> tab
= env()->MakeTab();
153 registry
->MonitorWebContentsForRuleEvaluation(tab
.get());
154 registry
->DidNavigateMainFrame(tab
.get(), content::LoadCommittedDetails(),
155 content::FrameNavigateParams());
156 EXPECT_EQ(0u, registry
->GetActiveRulesCountForTesting());
159 linked_ptr
<api::events::Rule
> rule(new api::events::Rule
);
160 api::events::Rule::Populate(
161 *base::test::ParseJson(
163 " \"id\": \"rule1\",\n"
164 " \"priority\": 100,\n"
165 " \"conditions\": [\n"
167 " \"instanceType\": \"declarativeContent.PageStateMatcher\",\n"
168 " \"test_predicate\": []\n"
171 " { \"instanceType\": \"declarativeContent.ShowPageAction\" }\n"
175 std::vector
<linked_ptr
<api::events::Rule
>> rules
;
176 rules
.push_back(rule
);
178 const Extension
* extension
= env()->MakeExtension(*base::test::ParseJson(
179 "{\"page_action\": {}}"));
180 registry
->AddRulesImpl(extension
->id(), rules
);
182 registry
->DidNavigateMainFrame(tab
.get(), content::LoadCommittedDetails(),
183 content::FrameNavigateParams());
184 EXPECT_EQ(0u, registry
->GetActiveRulesCountForTesting());
186 evaluator
->RequestImmediateEvaluation(tab
.get(), true);
187 EXPECT_EQ(1u, registry
->GetActiveRulesCountForTesting());
189 // Closing the tab should erase its entry from active_rules_.
191 EXPECT_EQ(0u, registry
->GetActiveRulesCountForTesting());
193 tab
= env()->MakeTab();
194 registry
->MonitorWebContentsForRuleEvaluation(tab
.get());
195 evaluator
->RequestImmediateEvaluation(tab
.get(), true);
196 EXPECT_EQ(1u, registry
->GetActiveRulesCountForTesting());
198 evaluator
->RequestEvaluationOnNextOperation(tab
.get(), false);
199 registry
->DidNavigateMainFrame(tab
.get(), content::LoadCommittedDetails(),
200 content::FrameNavigateParams());
201 EXPECT_EQ(0u, registry
->GetActiveRulesCountForTesting());
204 } // namespace extensions