Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker_unittest.cc

Issue 1166393002: Reland "Encapsulate CSS selector declarative content condition tracking" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkcr
Patch Set: address comments Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "chrome/browser/extensions/api/declarative_content/declarative_content_ css_condition_tracker.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/run_loop.h"
9 #include "chrome/test/base/testing_profile.h"
10 #include "content/public/browser/navigation_details.h"
11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/web_contents.h"
13 #include "content/public/test/browser_test_utils.h"
14 #include "content/public/test/mock_render_process_host.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "content/public/test/test_renderer_host.h"
17 #include "content/public/test/web_contents_tester.h"
18 #include "extensions/common/extension_messages.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace extensions {
23
24 using testing::UnorderedElementsAreArray;
25
26 class DeclarativeContentCssConditionTrackerTest : public testing::Test {
27 public:
28 DeclarativeContentCssConditionTrackerTest() : profile_(new TestingProfile) {}
29
30 ~DeclarativeContentCssConditionTrackerTest() override {
31 // MockRenderProcessHosts are deleted from the message loop, and their
32 // deletion must complete before RenderViewHostTestEnabler's destructor is
33 // run.
34 base::RunLoop().RunUntilIdle();
35 }
36
37 protected:
38 class Delegate : public DeclarativeContentCssConditionTrackerDelegate {
39 public:
40 Delegate() : evaluation_requests_(0) {}
41
42 int evaluation_requests() { return evaluation_requests_; }
43
44 // DeclarativeContentCssConditionTrackerDelegate:
45 void RequestEvaluation(content::WebContents* contents) override {
46 ++evaluation_requests_;
47 }
48
49 bool ShouldManageConditionsForBrowserContext(
50 content::BrowserContext* context) override {
51 return true;
52 }
53
54 private:
55 int evaluation_requests_;
56
57 DISALLOW_COPY_AND_ASSIGN(Delegate);
58 };
59
60 // Creates a new WebContents and retains ownership.
61 scoped_ptr<content::WebContents> MakeTab() {
62 return make_scoped_ptr(content::WebContentsTester::CreateTestWebContents(
63 profile_.get(),
64 nullptr));
65 }
66
67 // Expect an ExtensionMsg_WatchPages message in |sink| with |selectors| as the
68 // param, after invoking |func|.
69 template <class Func>
70 void ExpectWatchPagesMessage(IPC::TestSink& sink,
71 const std::set<std::string>& selectors,
72 const Func& func) {
73 sink.ClearMessages();
74 func();
75 EXPECT_EQ(1u, sink.message_count());
76 const IPC::Message* message =
77 sink.GetUniqueMessageMatching(ExtensionMsg_WatchPages::ID);
78 ASSERT_TRUE(message);
79 ExtensionMsg_WatchPages::Param params;
80 ExtensionMsg_WatchPages::Read(message, &params);
81 EXPECT_THAT(base::get<0>(params), UnorderedElementsAreArray(selectors));
82 }
83
84 // Sends an OnWatchedPageChange message to the tab.
85 void SendOnWatchedPageChangeMessage(
86 content::WebContents* tab,
87 const std::vector<std::string>& selectors) {
88 ExtensionHostMsg_OnWatchedPageChange page_change(tab->GetRoutingID(),
89 selectors);
90 content::MockRenderProcessHost* process =
91 static_cast<content::MockRenderProcessHost*>(
92 tab->GetRenderViewHost()->GetProcess());
93
94 EXPECT_TRUE(process->OnMessageReceived(page_change));
95 }
96
97 Profile* profile() { return profile_.get(); }
98 Delegate* delegate() { return &delegate_; }
99
100 private:
101 content::TestBrowserThreadBundle thread_bundle_;
102
103 // Enables MockRenderProcessHosts.
104 content::RenderViewHostTestEnabler render_view_host_test_enabler_;
105
106 const scoped_ptr<TestingProfile> profile_;
107 Delegate delegate_;
108
109 DISALLOW_COPY_AND_ASSIGN(DeclarativeContentCssConditionTrackerTest);
110 };
111
112 // Tests the basic flow of operations on the
113 // DeclarativeContentCssConditionTracker.
114 TEST_F(DeclarativeContentCssConditionTrackerTest, Basic) {
115 DeclarativeContentCssConditionTracker tracker(profile(), delegate());
116 int expected_evaluation_requests = 0;
117
118 const scoped_ptr<content::WebContents> tab = MakeTab();
119 tracker.TrackForWebContents(tab.get());
120 EXPECT_EQ(expected_evaluation_requests, delegate()->evaluation_requests());
121
122 content::MockRenderProcessHost* process =
123 static_cast<content::MockRenderProcessHost*>(
124 tab->GetRenderViewHost()->GetProcess());
125
126 // Check that calling SetWatchedCssSelectors sends a WatchPages message with
127 // the selectors to the tab's RenderProcessHost.
128 std::set<std::string> watched_selectors;
129 watched_selectors.insert("a");
130 watched_selectors.insert("div");
131 ExpectWatchPagesMessage(process->sink(), watched_selectors,
132 [&tracker, &watched_selectors]() {
133 tracker.SetWatchedCssSelectors(watched_selectors);
134 });
135 EXPECT_EQ(expected_evaluation_requests, delegate()->evaluation_requests());
136
137 // Check that receiving an OnWatchedPageChange message from the tab results in
138 // a request for condition evaluation.
139 const std::vector<std::string> matched_selectors(1, "div");
140 SendOnWatchedPageChangeMessage(tab.get(), matched_selectors);
141 EXPECT_EQ(++expected_evaluation_requests, delegate()->evaluation_requests());
142
143 // Check that GetMatchingCssSelectors produces the same matched selectors as
144 // were sent by the OnWatchedPageChange message.
145 base::hash_set<std::string> matching_selectors;
146 tracker.GetMatchingCssSelectors(tab.get(), &matching_selectors);
147 EXPECT_THAT(matching_selectors,
148 UnorderedElementsAreArray(matched_selectors));
149 EXPECT_EQ(expected_evaluation_requests, delegate()->evaluation_requests());
150
151 // Check that an in-page navigation has no effect on the matching selectors.
152 {
153 content::LoadCommittedDetails details;
154 details.is_in_page = true;
155 content::FrameNavigateParams params;
156 tracker.OnWebContentsNavigation(tab.get(), details, params);
157 matching_selectors.clear();
158 tracker.GetMatchingCssSelectors(tab.get(), &matching_selectors);
159 EXPECT_THAT(matching_selectors,
160 UnorderedElementsAreArray(matched_selectors));
161 EXPECT_EQ(expected_evaluation_requests, delegate()->evaluation_requests());
162 }
163
164 // Check that a non in-page navigation clears the matching selectors and
165 // requests condition evaluation.
166 {
167 content::LoadCommittedDetails details;
168 details.is_in_page = false;
169 content::FrameNavigateParams params;
170 tracker.OnWebContentsNavigation(tab.get(), details, params);
171 matching_selectors.clear();
172 tracker.GetMatchingCssSelectors(tab.get(), &matching_selectors);
173 EXPECT_TRUE(matching_selectors.empty());
174 EXPECT_EQ(++expected_evaluation_requests,
175 delegate()->evaluation_requests());
176 }
177 }
178
179 // https://crbug.com/497586
180 TEST_F(DeclarativeContentCssConditionTrackerTest, WebContentsOutlivesTracker) {
181 const scoped_ptr<content::WebContents> tab = MakeTab();
182
183 {
184 DeclarativeContentCssConditionTracker tracker(profile(), delegate());
185 tracker.TrackForWebContents(tab.get());
186 }
187 }
188
189 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698