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

Side by Side Diff: components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc

Issue 2770153004: Unittests for the Safe Browsing Subresource filter navigation throttle (Closed)
Patch Set: comments Created 3 years, 8 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 2017 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 "components/subresource_filter/content/browser/subresource_filter_safe_ browsing_activation_throttle.h"
6
7 #include <memory>
8
9 #include "base/memory/ptr_util.h"
10 #include "base/metrics/field_trial.h"
11 #include "base/test/histogram_tester.h"
12 #include "components/safe_browsing_db/test_database_manager.h"
13 #include "components/subresource_filter/content/browser/content_subresource_filt er_driver_factory.h"
14 #include "components/subresource_filter/content/browser/subresource_filter_clien t.h"
15 #include "components/subresource_filter/core/browser/subresource_filter_features .h"
engedy 2017/04/06 13:50:38 nit: Do we use this?
melandory 2017/04/07 09:09:44 Yes, for feature setup
16 #include "components/subresource_filter/core/browser/subresource_filter_features _test_support.h"
17 #include "components/subresource_filter/core/common/activation_level.h"
engedy 2017/04/06 13:50:38 nit: I think 17--20 are not used.
melandory 2017/04/07 09:09:44 Done.
18 #include "components/subresource_filter/core/common/activation_list.h"
19 #include "components/subresource_filter/core/common/activation_state.h"
20 #include "components/subresource_filter/core/common/test_ruleset_creator.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/navigation_handle.h"
23 #include "content/public/browser/web_contents_observer.h"
24 #include "content/public/test/navigation_simulator.h"
25 #include "content/public/test/test_renderer_host.h"
26 #include "testing/gmock/include/gmock/gmock-generated-matchers.h"
engedy 2017/04/06 13:50:38 nit: I think this is included by the one below.
melandory 2017/04/07 09:09:44 Done.
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29
30 namespace subresource_filter {
31
32 namespace {
33
34 char kURL[] = "http://example.test/";
35 char kRedirectURL[] = "http://foo.test/";
36
37 // Names of navigation chain patterns histogram.
38 const char kMatchesPatternHistogramNameSubresourceFilterSuffix[] =
39 "SubresourceFilter.PageLoad.RedirectChainMatchPattern."
40 "SubresourceFilterOnly";
41 const char kNavigationChainSizeSubresourceFilterSuffix[] =
42 "SubresourceFilter.PageLoad.RedirectChainLength.SubresourceFilterOnly";
43
44 // Human readable representation of expected redirect chain match patterns.
45 // The explanations for the buckets given for the following redirect chain:
46 // A->B->C->D, where A is initial URL and D is a final URL.
47 enum RedirectChainMatchPattern {
48 EMPTY, // No histograms were recorded.
49 F0M0L1, // D is a Safe Browsing match.
50 F0M1L0, // B or C, or both are Safe Browsing matches.
51 F0M1L1, // B or C, or both and D are Safe Browsing matches.
52 F1M0L0, // A is Safe Browsing match
53 F1M0L1, // A and D are Safe Browsing matches.
54 F1M1L0, // B and/or C and A are Safe Browsing matches.
55 F1M1L1, // B and/or C and A and D are Safe Browsing matches.
56 NO_REDIRECTS_HIT, // Redirect chain consists of single URL, aka no redirects
57 // has happened, and this URL was a Safe Browsing hit.
58 NUM_HIT_PATTERNS,
59 };
60
61 // Database manager that allows any URL to be configured as blacklisted for
62 // testing.
63 class FakeSafeBrowsingDatabaseManager
64 : public safe_browsing::TestSafeBrowsingDatabaseManager {
65 public:
66 FakeSafeBrowsingDatabaseManager() : simulate_timeout_(false) {}
67
68 void AddBlacklistedUrl(const GURL& url,
69 safe_browsing::SBThreatType threat_type) {
70 url_to_threat_type_[url] = threat_type;
71 }
72
73 void SimulateTimeout() { simulate_timeout_ = true; }
74
75 protected:
76 ~FakeSafeBrowsingDatabaseManager() override {}
77
78 bool CheckUrlForSubresourceFilter(const GURL& url, Client* client) override {
79 if (simulate_timeout_)
80 return false;
81 if (!url_to_threat_type_.count(url))
82 return true;
83
84 content::BrowserThread::PostTask(
85 content::BrowserThread::IO, FROM_HERE,
86 base::Bind(&Client::OnCheckBrowseUrlResult, base::Unretained(client),
87 url, url_to_threat_type_[url],
88 safe_browsing::ThreatMetadata()));
89 return false;
90 }
91
92 bool CheckResourceUrl(const GURL& url, Client* client) override {
93 return true;
94 }
95
96 bool IsSupported() const override { return true; }
97 bool ChecksAreAlwaysAsync() const override { return false; }
98 bool CanCheckResourceType(
99 content::ResourceType /* resource_type */) const override {
100 return true;
101 }
102
103 safe_browsing::ThreatSource GetThreatSource() const override {
104 return safe_browsing::ThreatSource::LOCAL_PVER4;
105 }
106
107 bool CheckExtensionIDs(const std::set<std::string>& extension_ids,
108 Client* client) override {
109 return true;
110 }
111
112 private:
113 std::map<GURL, safe_browsing::SBThreatType> url_to_threat_type_;
114 bool simulate_timeout_;
115
116 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
117 };
118
119 class MockSubresourceFilterClient
120 : public subresource_filter::SubresourceFilterClient {
121 public:
122 MockSubresourceFilterClient() {}
123
124 ~MockSubresourceFilterClient() override = default;
125
126 MOCK_METHOD1(ToggleNotificationVisibility, void(bool));
127 MOCK_METHOD1(IsWhitelistedByContentSettings, bool(const GURL&));
128 MOCK_METHOD1(WhitelistByContentSettings, void(const GURL&));
129 MOCK_METHOD0(GetRulesetDealer, VerifiedRulesetDealer::Handle*());
130
131 private:
132 DISALLOW_COPY_AND_ASSIGN(MockSubresourceFilterClient);
133 };
134
135 // Used to simulate WillProcessResonse for the factory.
engedy 2017/04/06 13:50:38 phrasing nit: // Throttle to call WillProcessResp
melandory 2017/04/07 09:09:44 Done.
136 class ForwardingNavigationThrottle : public content::NavigationThrottle {
engedy 2017/04/06 13:50:38 naming nit: TestForwardingNavigationThrottle
melandory 2017/04/07 09:09:44 Done.
137 public:
138 ForwardingNavigationThrottle(content::NavigationHandle* handle)
139 : content::NavigationThrottle(handle) {}
140 ~ForwardingNavigationThrottle() override {}
141
142 // content::NavigationThrottle:
143 content::NavigationThrottle::ThrottleCheckResult WillProcessResponse()
144 override {
145 content::WebContents* web_contents = navigation_handle()->GetWebContents();
146 ContentSubresourceFilterDriverFactory* factory =
147 ContentSubresourceFilterDriverFactory::FromWebContents(web_contents);
148 factory->WillProcessResponse(navigation_handle());
149 return content::NavigationThrottle::PROCEED;
150 }
151
152 private:
153 DISALLOW_COPY_AND_ASSIGN(ForwardingNavigationThrottle);
154 };
155
156 } // namespace
157
158 class SubresourceFilterSafeBrowsingActivationThrottleTest
159 : public content::RenderViewHostTestHarness,
160 public content::WebContentsObserver {
161 public:
162 SubresourceFilterSafeBrowsingActivationThrottleTest()
163 : field_trial_list_(nullptr) {}
164 ~SubresourceFilterSafeBrowsingActivationThrottleTest() override {}
165
166 void SetUp() override {
167 content::RenderViewHostTestHarness::SetUp();
168 scoped_feature_toggle_.reset(
169 new testing::ScopedSubresourceFilterFeatureToggle(
170 base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
171 kActivationScopeActivationList, kActivationListSubresourceFilter));
172 auto client = base::MakeUnique<MockSubresourceFilterClient>();
173 ContentSubresourceFilterDriverFactory::CreateForWebContents(
174 RenderViewHostTestHarness::web_contents(), std::move(client));
175 fake_safe_browsing_database_ = new FakeSafeBrowsingDatabaseManager();
176 NavigateAndCommit(GURL(kURL));
engedy 2017/04/06 13:50:38 Let's navigate to some other URL here, it's unclea
melandory 2017/04/07 09:09:44 Done.
177 Observe(RenderViewHostTestHarness::web_contents());
178 }
179
180 ContentSubresourceFilterDriverFactory* factory() {
181 return ContentSubresourceFilterDriverFactory::FromWebContents(
182 RenderViewHostTestHarness::web_contents());
183 }
184
185 // content::WebContentsObserver:
186 void DidStartNavigation(
187 content::NavigationHandle* navigation_handle) override {
188 ASSERT_TRUE(navigation_handle->IsInMainFrame());
189 navigation_handle->RegisterThrottleForTesting(
190 base::MakeUnique<SubresourceFilterSafeBrowsingActivationThrottle>(
191 navigation_handle, fake_safe_browsing_database_));
192 navigation_handle->RegisterThrottleForTesting(
193 base::MakeUnique<ForwardingNavigationThrottle>(navigation_handle));
194 }
195
196 void SimulateStartAndExpectProceed() {
197 navigation_simulator_->Start();
198 EXPECT_EQ(content::NavigationThrottle::PROCEED,
199 navigation_simulator_->GetLastThrottleCheckResult());
200 }
201
202 void SimulateRedirectAndExpectProceed(const GURL& new_url) {
203 navigation_simulator_->Redirect(new_url);
204 EXPECT_EQ(content::NavigationThrottle::PROCEED,
205 navigation_simulator_->GetLastThrottleCheckResult());
206 }
207
208 void SimulateCommitAndExpectProceed() {
209 navigation_simulator_->Commit();
210 EXPECT_EQ(content::NavigationThrottle::PROCEED,
211 navigation_simulator_->GetLastThrottleCheckResult());
212 }
213
214 void CreateTestNavigationForMainFrame(const GURL& first_url) {
215 navigation_simulator_ =
216 content::NavigationSimulator::CreateRendererInitiated(first_url,
217 main_rfh());
218 }
219
220 void ConfigureAsSubresourceFilterOnlyURL(const GURL& url) {
221 fake_safe_browsing_database_->AddBlacklistedUrl(
222 url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER);
223 }
224
225 void SimulateTimeout() { fake_safe_browsing_database_->SimulateTimeout(); }
226
227 const base::HistogramTester& tester() const { return tester_; }
228
229 private:
230 base::FieldTrialList field_trial_list_;
231 std::unique_ptr<content::NavigationSimulator> navigation_simulator_;
232 scoped_refptr<FakeSafeBrowsingDatabaseManager> fake_safe_browsing_database_;
233 std::unique_ptr<testing::ScopedSubresourceFilterFeatureToggle>
engedy 2017/04/06 13:50:38 nit: Could you please move this next to |field_tri
melandory 2017/04/07 09:09:44 Done.
234 scoped_feature_toggle_;
235 base::HistogramTester tester_;
236
237 DISALLOW_COPY_AND_ASSIGN(SubresourceFilterSafeBrowsingActivationThrottleTest);
238 };
239
240 TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, NoHitNavigation) {
engedy 2017/04/06 13:50:38 nit: Could we name these test cases using the patt
melandory 2017/04/07 09:09:44 Done.
241 const GURL url(kURL);
242 CreateTestNavigationForMainFrame(url);
243 SimulateStartAndExpectProceed();
244 SimulateCommitAndExpectProceed();
245 EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision::
246 ACTIVATION_LIST_NOT_MATCHED,
247 factory()->GetActivationDecisionForLastCommittedPageLoad());
248 tester().ExpectTotalCount(kMatchesPatternHistogramNameSubresourceFilterSuffix,
249 0);
250 tester().ExpectTotalCount(kNavigationChainSizeSubresourceFilterSuffix, 0);
251 }
252
253 TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, HitNavigation) {
254 const GURL url(kURL);
255 ConfigureAsSubresourceFilterOnlyURL(url);
256 CreateTestNavigationForMainFrame(url);
257 SimulateStartAndExpectProceed();
258 SimulateCommitAndExpectProceed();
259 EXPECT_EQ(
260 ContentSubresourceFilterDriverFactory::ActivationDecision::ACTIVATED,
261 factory()->GetActivationDecisionForLastCommittedPageLoad());
262 tester().ExpectUniqueSample(
263 kMatchesPatternHistogramNameSubresourceFilterSuffix, NO_REDIRECTS_HIT, 1);
264 tester().ExpectUniqueSample(kNavigationChainSizeSubresourceFilterSuffix, 1,
265 1);
266 }
267
268 TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
269 CheckRedirectsNoHit) {
270 const GURL url(kURL);
271 CreateTestNavigationForMainFrame(url);
272 SimulateStartAndExpectProceed();
273 SimulateRedirectAndExpectProceed(GURL(kRedirectURL));
274 SimulateCommitAndExpectProceed();
275 EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision::
276 ACTIVATION_LIST_NOT_MATCHED,
277 factory()->GetActivationDecisionForLastCommittedPageLoad());
278 tester().ExpectTotalCount(kMatchesPatternHistogramNameSubresourceFilterSuffix,
279 0);
280 tester().ExpectTotalCount(kNavigationChainSizeSubresourceFilterSuffix, 0);
281 }
282
283 TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, CheckRedirectsHit) {
284 const GURL url(kURL);
285 ConfigureAsSubresourceFilterOnlyURL(GURL(kRedirectURL));
286 CreateTestNavigationForMainFrame(url);
287 SimulateStartAndExpectProceed();
288 SimulateRedirectAndExpectProceed(GURL(kRedirectURL));
289 SimulateCommitAndExpectProceed();
290 EXPECT_EQ(
291 ContentSubresourceFilterDriverFactory::ActivationDecision::ACTIVATED,
292 factory()->GetActivationDecisionForLastCommittedPageLoad());
293 tester().ExpectUniqueSample(
294 kMatchesPatternHistogramNameSubresourceFilterSuffix, F0M0L1, 1);
295 tester().ExpectUniqueSample(kNavigationChainSizeSubresourceFilterSuffix, 2,
296 1);
297 }
298
299 TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, SimulateTimeout) {
300 const GURL url(kURL);
301 SimulateTimeout();
302 CreateTestNavigationForMainFrame(url);
303 SimulateStartAndExpectProceed();
304 SimulateCommitAndExpectProceed();
305 EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision::
306 ACTIVATION_LIST_NOT_MATCHED,
307 factory()->GetActivationDecisionForLastCommittedPageLoad());
308 tester().ExpectTotalCount(kMatchesPatternHistogramNameSubresourceFilterSuffix,
309 0);
310 tester().ExpectTotalCount(kNavigationChainSizeSubresourceFilterSuffix, 0);
311 }
312
313 } // namespace subresource_filter
engedy 2017/04/06 13:50:38 Could you please add one more test that destroys t
melandory 2017/04/07 09:09:44 As per offline discussion, it's tricky to implemen
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698