blob: df62feb9b72e331ad4d1b4ccf38a2f9ba4e1fdc4 [file] [log] [blame]
feltbc2eda2d2015-06-23 02:06:031// 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
dcheng7bacc0e2016-04-11 20:10:545#include "chrome/browser/safe_browsing/ui_manager.h"
6
clamy4edbf0e2015-12-02 13:35:417#include "base/run_loop.h"
dalecurtis6c58ed02016-10-28 23:02:378#include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
feltbc2eda2d2015-06-23 02:06:039#include "chrome/browser/safe_browsing/safe_browsing_service.h"
scottmg22e4f25a2016-08-15 21:09:0310#include "chrome/browser/safe_browsing/ui_manager.h"
feltfb118572015-08-18 05:22:0111#include "chrome/test/base/chrome_render_view_host_test_harness.h"
12#include "chrome/test/base/testing_profile.h"
timvolodine89cf11712017-05-15 18:05:0713#include "components/safe_browsing/common/safe_browsing_prefs.h"
vakhfa183fa2016-03-29 17:33:3714#include "components/safe_browsing_db/util.h"
edwardjungd7395fb02017-05-12 23:13:2915#include "components/security_interstitials/core/base_safe_browsing_error_ui.h"
estark1ca09ca2016-11-01 04:04:1216#include "content/public/browser/navigation_entry.h"
feltfb118572015-08-18 05:22:0117#include "content/public/browser/render_process_host.h"
18#include "content/public/browser/render_view_host.h"
19#include "content/public/browser/web_contents.h"
dalecurtis6c58ed02016-10-28 23:02:3720#include "content/public/browser/web_contents_delegate.h"
feltbc2eda2d2015-06-23 02:06:0321#include "content/public/test/test_browser_thread_bundle.h"
feltfb118572015-08-18 05:22:0122#include "content/public/test/web_contents_tester.h"
feltbc2eda2d2015-06-23 02:06:0323#include "testing/gtest/include/gtest/gtest.h"
24#include "url/gurl.h"
25
clamy4edbf0e2015-12-02 13:35:4126using content::BrowserThread;
27
feltfb118572015-08-18 05:22:0128static const char* kGoodURL = "https://www.good.com";
29static const char* kBadURL = "https://www.malware.com";
30static const char* kBadURLWithPath = "https://www.malware.com/index.html";
mattmbfc4060d2015-12-18 23:11:3831static const char* kAnotherBadURL = "https://www.badware.com";
32static const char* kLandingURL = "https://www.landing.com";
feltfb118572015-08-18 05:22:0133
vakh9a474d832015-11-13 01:43:0934namespace safe_browsing {
35
clamy4edbf0e2015-12-02 13:35:4136class SafeBrowsingCallbackWaiter {
37 public:
38 SafeBrowsingCallbackWaiter() {}
39
40 bool callback_called() const { return callback_called_; }
41 bool proceed() const { return proceed_; }
42
43 void OnBlockingPageDone(bool proceed) {
44 DCHECK_CURRENTLY_ON(BrowserThread::UI);
45 callback_called_ = true;
46 proceed_ = proceed;
47 loop_.Quit();
48 }
49
50 void OnBlockingPageDoneOnIO(bool proceed) {
51 DCHECK_CURRENTLY_ON(BrowserThread::IO);
52 BrowserThread::PostTask(
53 BrowserThread::UI, FROM_HERE,
tzikb5f84b82017-04-20 00:55:2854 base::BindOnce(&SafeBrowsingCallbackWaiter::OnBlockingPageDone,
55 base::Unretained(this), proceed));
clamy4edbf0e2015-12-02 13:35:4156 }
57
58 void WaitForCallback() {
59 DCHECK_CURRENTLY_ON(BrowserThread::UI);
60 loop_.Run();
61 }
62
63 private:
64 bool callback_called_ = false;
65 bool proceed_ = false;
66 base::RunLoop loop_;
67};
68
feltfb118572015-08-18 05:22:0169class SafeBrowsingUIManagerTest : public ChromeRenderViewHostTestHarness {
feltbc2eda2d2015-06-23 02:06:0370 public:
71 SafeBrowsingUIManagerTest() : ui_manager_(new SafeBrowsingUIManager(NULL)) {}
feltfb118572015-08-18 05:22:0172
juncai1ee189bd2017-06-09 04:25:4373 ~SafeBrowsingUIManagerTest() override {}
feltbc2eda2d2015-06-23 02:06:0374
clamy4edbf0e2015-12-02 13:35:4175 void SetUp() override {
76 SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD);
77 ChromeRenderViewHostTestHarness::SetUp();
estark1ca09ca2016-11-01 04:04:1278 SafeBrowsingUIManager::CreateWhitelistForTesting(web_contents());
clamy4edbf0e2015-12-02 13:35:4179 }
feltfb118572015-08-18 05:22:0180
81 void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); }
82
jialiul792a6662016-12-03 01:44:1083 bool IsWhitelisted(security_interstitials::UnsafeResource resource) {
feltbc2eda2d2015-06-23 02:06:0384 return ui_manager_->IsWhitelisted(resource);
85 }
86
jialiul792a6662016-12-03 01:44:1087 void AddToWhitelist(security_interstitials::UnsafeResource resource) {
estark1ca09ca2016-11-01 04:04:1288 ui_manager_->AddToWhitelistUrlSet(
89 SafeBrowsingUIManager::GetMainFrameWhitelistUrlForResourceForTesting(
90 resource),
estark7ffa8c62016-11-11 23:21:5591 web_contents(), false, resource.threat_type);
feltfb118572015-08-18 05:22:0192 }
93
jialiul792a6662016-12-03 01:44:1094 security_interstitials::UnsafeResource MakeUnsafeResource(
mattmbfc4060d2015-12-18 23:11:3895 const char* url,
96 bool is_subresource) {
jialiul792a6662016-12-03 01:44:1097 security_interstitials::UnsafeResource resource;
feltfb118572015-08-18 05:22:0198 resource.url = GURL(url);
mattmbfc4060d2015-12-18 23:11:3899 resource.is_subresource = is_subresource;
scottmg22e4f25a2016-08-15 21:09:03100 resource.web_contents_getter =
jialiul792a6662016-12-03 01:44:10101 security_interstitials::UnsafeResource::GetWebContentsGetter(
scottmg22e4f25a2016-08-15 21:09:03102 web_contents()->GetRenderProcessHost()->GetID(),
103 web_contents()->GetMainFrame()->GetRoutingID());
feltfb118572015-08-18 05:22:01104 resource.threat_type = SB_THREAT_TYPE_URL_MALWARE;
105 return resource;
106 }
107
jialiul792a6662016-12-03 01:44:10108 security_interstitials::UnsafeResource MakeUnsafeResourceAndStartNavigation(
feltfb118572015-08-18 05:22:01109 const char* url) {
jialiul792a6662016-12-03 01:44:10110 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38111 MakeUnsafeResource(url, false /* is_subresource */);
feltfb118572015-08-18 05:22:01112
mattmbfc4060d2015-12-18 23:11:38113 // The WC doesn't have a URL without a navigation. A main-frame malware
114 // unsafe resource must be a pending navigation.
115 content::WebContentsTester::For(web_contents())->StartNavigation(GURL(url));
feltfb118572015-08-18 05:22:01116 return resource;
feltbc2eda2d2015-06-23 02:06:03117 }
118
clamy4edbf0e2015-12-02 13:35:41119 void SimulateBlockingPageDone(
jialiul792a6662016-12-03 01:44:10120 const std::vector<security_interstitials::UnsafeResource>& resources,
clamy4edbf0e2015-12-02 13:35:41121 bool proceed) {
estark1ca09ca2016-11-01 04:04:12122 GURL main_frame_url;
123 content::NavigationEntry* entry =
124 web_contents()->GetController().GetVisibleEntry();
125 if (entry)
126 main_frame_url = entry->GetURL();
127
128 ui_manager_->OnBlockingPageDone(resources, proceed, web_contents(),
129 main_frame_url);
clamy4edbf0e2015-12-02 13:35:41130 }
131
dalecurtis6c58ed02016-10-28 23:02:37132 protected:
133 SafeBrowsingUIManager* ui_manager() { return ui_manager_.get(); }
134
feltbc2eda2d2015-06-23 02:06:03135 private:
136 scoped_refptr<SafeBrowsingUIManager> ui_manager_;
feltbc2eda2d2015-06-23 02:06:03137};
138
139TEST_F(SafeBrowsingUIManagerTest, Whitelist) {
jialiul792a6662016-12-03 01:44:10140 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38141 MakeUnsafeResourceAndStartNavigation(kBadURL);
feltbc2eda2d2015-06-23 02:06:03142 AddToWhitelist(resource);
143 EXPECT_TRUE(IsWhitelisted(resource));
144}
145
feltfb118572015-08-18 05:22:01146TEST_F(SafeBrowsingUIManagerTest, WhitelistIgnoresSitesNotAdded) {
jialiul792a6662016-12-03 01:44:10147 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38148 MakeUnsafeResourceAndStartNavigation(kGoodURL);
feltbc2eda2d2015-06-23 02:06:03149 EXPECT_FALSE(IsWhitelisted(resource));
feltfb118572015-08-18 05:22:01150}
151
estark7ffa8c62016-11-11 23:21:55152TEST_F(SafeBrowsingUIManagerTest, WhitelistRemembersThreatType) {
jialiul792a6662016-12-03 01:44:10153 security_interstitials::UnsafeResource resource =
estark7ffa8c62016-11-11 23:21:55154 MakeUnsafeResourceAndStartNavigation(kBadURL);
155 AddToWhitelist(resource);
156 EXPECT_TRUE(IsWhitelisted(resource));
157 SBThreatType threat_type;
158 content::NavigationEntry* entry =
159 web_contents()->GetController().GetVisibleEntry();
160 ASSERT_TRUE(entry);
161 EXPECT_TRUE(ui_manager()->IsUrlWhitelistedOrPendingForWebContents(
162 resource.url, resource.is_subresource, entry,
163 resource.web_contents_getter.Run(), true, &threat_type));
164 EXPECT_EQ(resource.threat_type, threat_type);
165}
166
feltfb118572015-08-18 05:22:01167TEST_F(SafeBrowsingUIManagerTest, WhitelistIgnoresPath) {
jialiul792a6662016-12-03 01:44:10168 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38169 MakeUnsafeResourceAndStartNavigation(kBadURL);
feltbc2eda2d2015-06-23 02:06:03170 AddToWhitelist(resource);
171 EXPECT_TRUE(IsWhitelisted(resource));
feltfb118572015-08-18 05:22:01172
mattmbfc4060d2015-12-18 23:11:38173 content::WebContentsTester::For(web_contents())->CommitPendingNavigation();
174
jialiul792a6662016-12-03 01:44:10175 security_interstitials::UnsafeResource resource_path =
mattmbfc4060d2015-12-18 23:11:38176 MakeUnsafeResourceAndStartNavigation(kBadURLWithPath);
feltfb118572015-08-18 05:22:01177 EXPECT_TRUE(IsWhitelisted(resource_path));
feltbc2eda2d2015-06-23 02:06:03178}
179
feltfb118572015-08-18 05:22:01180TEST_F(SafeBrowsingUIManagerTest, WhitelistIgnoresThreatType) {
jialiul792a6662016-12-03 01:44:10181 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38182 MakeUnsafeResourceAndStartNavigation(kBadURL);
feltfb118572015-08-18 05:22:01183 AddToWhitelist(resource);
184 EXPECT_TRUE(IsWhitelisted(resource));
feltbc2eda2d2015-06-23 02:06:03185
jialiul792a6662016-12-03 01:44:10186 security_interstitials::UnsafeResource resource_phishing =
mattmbfc4060d2015-12-18 23:11:38187 MakeUnsafeResource(kBadURL, false /* is_subresource */);
feltfb118572015-08-18 05:22:01188 resource_phishing.threat_type = SB_THREAT_TYPE_URL_PHISHING;
189 EXPECT_TRUE(IsWhitelisted(resource_phishing));
feltbc2eda2d2015-06-23 02:06:03190}
191
mattmbfc4060d2015-12-18 23:11:38192TEST_F(SafeBrowsingUIManagerTest, WhitelistWithUnrelatedPendingLoad) {
193 // Commit load of landing page.
194 NavigateAndCommit(GURL(kLandingURL));
195 {
196 // Simulate subresource malware hit on the landing page.
jialiul792a6662016-12-03 01:44:10197 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38198 MakeUnsafeResource(kBadURL, true /* is_subresource */);
199
200 // Start pending load to unrelated site.
201 content::WebContentsTester::For(web_contents())
202 ->StartNavigation(GURL(kGoodURL));
203
204 // Whitelist the resource on the landing page.
205 AddToWhitelist(resource);
206 EXPECT_TRUE(IsWhitelisted(resource));
207 }
208
209 // Commit the pending load of unrelated site.
210 content::WebContentsTester::For(web_contents())->CommitPendingNavigation();
211 {
212 // The unrelated site is not on the whitelist, even if the same subresource
213 // was on it.
jialiul792a6662016-12-03 01:44:10214 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38215 MakeUnsafeResource(kBadURL, true /* is_subresource */);
216 EXPECT_FALSE(IsWhitelisted(resource));
217 }
218
219 // Navigate back to the original landing url.
220 NavigateAndCommit(GURL(kLandingURL));
221 {
jialiul792a6662016-12-03 01:44:10222 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38223 MakeUnsafeResource(kBadURL, true /* is_subresource */);
224 // Original resource url is whitelisted.
225 EXPECT_TRUE(IsWhitelisted(resource));
226 }
227 {
228 // A different malware subresource on the same page is also whitelisted.
229 // (The whitelist is by the page url, not the resource url.)
jialiul792a6662016-12-03 01:44:10230 security_interstitials::UnsafeResource resource2 =
mattmbfc4060d2015-12-18 23:11:38231 MakeUnsafeResource(kAnotherBadURL, true /* is_subresource */);
232 EXPECT_TRUE(IsWhitelisted(resource2));
233 }
234}
235
clamy4edbf0e2015-12-02 13:35:41236TEST_F(SafeBrowsingUIManagerTest, UICallbackProceed) {
jialiul792a6662016-12-03 01:44:10237 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38238 MakeUnsafeResourceAndStartNavigation(kBadURL);
clamy4edbf0e2015-12-02 13:35:41239 SafeBrowsingCallbackWaiter waiter;
240 resource.callback =
241 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDone,
242 base::Unretained(&waiter));
243 resource.callback_thread =
thestig529ad8a2016-07-08 20:30:12244 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
jialiul792a6662016-12-03 01:44:10245 std::vector<security_interstitials::UnsafeResource> resources;
clamy4edbf0e2015-12-02 13:35:41246 resources.push_back(resource);
247 SimulateBlockingPageDone(resources, true);
248 EXPECT_TRUE(IsWhitelisted(resource));
249 waiter.WaitForCallback();
250 EXPECT_TRUE(waiter.callback_called());
251 EXPECT_TRUE(waiter.proceed());
252}
253
254TEST_F(SafeBrowsingUIManagerTest, UICallbackDontProceed) {
jialiul792a6662016-12-03 01:44:10255 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38256 MakeUnsafeResourceAndStartNavigation(kBadURL);
clamy4edbf0e2015-12-02 13:35:41257 SafeBrowsingCallbackWaiter waiter;
258 resource.callback =
259 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDone,
260 base::Unretained(&waiter));
261 resource.callback_thread =
thestig529ad8a2016-07-08 20:30:12262 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
jialiul792a6662016-12-03 01:44:10263 std::vector<security_interstitials::UnsafeResource> resources;
clamy4edbf0e2015-12-02 13:35:41264 resources.push_back(resource);
265 SimulateBlockingPageDone(resources, false);
266 EXPECT_FALSE(IsWhitelisted(resource));
267 waiter.WaitForCallback();
268 EXPECT_TRUE(waiter.callback_called());
269 EXPECT_FALSE(waiter.proceed());
270}
271
272TEST_F(SafeBrowsingUIManagerTest, IOCallbackProceed) {
jialiul792a6662016-12-03 01:44:10273 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38274 MakeUnsafeResourceAndStartNavigation(kBadURL);
clamy4edbf0e2015-12-02 13:35:41275 SafeBrowsingCallbackWaiter waiter;
276 resource.callback =
277 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDoneOnIO,
278 base::Unretained(&waiter));
279 resource.callback_thread =
thestig529ad8a2016-07-08 20:30:12280 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
jialiul792a6662016-12-03 01:44:10281 std::vector<security_interstitials::UnsafeResource> resources;
clamy4edbf0e2015-12-02 13:35:41282 resources.push_back(resource);
283 SimulateBlockingPageDone(resources, true);
284 EXPECT_TRUE(IsWhitelisted(resource));
285 waiter.WaitForCallback();
286 EXPECT_TRUE(waiter.callback_called());
287 EXPECT_TRUE(waiter.proceed());
288}
289
290TEST_F(SafeBrowsingUIManagerTest, IOCallbackDontProceed) {
jialiul792a6662016-12-03 01:44:10291 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38292 MakeUnsafeResourceAndStartNavigation(kBadURL);
clamy4edbf0e2015-12-02 13:35:41293 SafeBrowsingCallbackWaiter waiter;
294 resource.callback =
295 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDoneOnIO,
296 base::Unretained(&waiter));
297 resource.callback_thread =
thestig529ad8a2016-07-08 20:30:12298 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
jialiul792a6662016-12-03 01:44:10299 std::vector<security_interstitials::UnsafeResource> resources;
clamy4edbf0e2015-12-02 13:35:41300 resources.push_back(resource);
301 SimulateBlockingPageDone(resources, false);
302 EXPECT_FALSE(IsWhitelisted(resource));
303 waiter.WaitForCallback();
304 EXPECT_TRUE(waiter.callback_called());
305 EXPECT_FALSE(waiter.proceed());
306}
307
dalecurtis6c58ed02016-10-28 23:02:37308namespace {
309
310// A WebContentsDelegate that records whether
311// VisibleSecurityStateChanged() was called.
312class SecurityStateWebContentsDelegate : public content::WebContentsDelegate {
313 public:
314 SecurityStateWebContentsDelegate() {}
315 ~SecurityStateWebContentsDelegate() override {}
316
317 bool visible_security_state_changed() const {
318 return visible_security_state_changed_;
319 }
320
321 void ClearVisibleSecurityStateChanged() {
322 visible_security_state_changed_ = false;
323 }
324
325 // WebContentsDelegate:
326 void VisibleSecurityStateChanged(content::WebContents* source) override {
327 visible_security_state_changed_ = true;
328 }
329
330 private:
331 bool visible_security_state_changed_ = false;
332 DISALLOW_COPY_AND_ASSIGN(SecurityStateWebContentsDelegate);
333};
334
335// A test blocking page that does not create windows.
336class TestSafeBrowsingBlockingPage : public SafeBrowsingBlockingPage {
337 public:
jialiul3d6032e2017-01-12 00:41:31338 TestSafeBrowsingBlockingPage(BaseUIManager* manager,
dalecurtis6c58ed02016-10-28 23:02:37339 content::WebContents* web_contents,
340 const GURL& main_frame_url,
341 const UnsafeResourceList& unsafe_resources)
jialiul3d6032e2017-01-12 00:41:31342 : SafeBrowsingBlockingPage(
343 manager,
344 web_contents,
345 main_frame_url,
346 unsafe_resources,
edwardjungd7395fb02017-05-12 23:13:29347 BaseSafeBrowsingErrorUI::SBErrorDisplayOptions(
ntfschra5448fa2017-02-02 01:01:31348 BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources),
ntfschre952a3e2017-05-19 19:15:30349 false, // is_extended_reporting_opt_in_allowed
350 false, // is_off_the_record
351 false, // is_extended_reporting_enabled
352 false, // is_scout_reporting_enabled
353 false, // is_proceed_anyway_disabled
ntfschre952a3e2017-05-19 19:15:30354 "cpn_safe_browsing")) { // help_center_article_link
dalecurtis6c58ed02016-10-28 23:02:37355 // Don't delay details at all for the unittest.
ntfschrfef42f92017-02-24 02:15:47356 SetThreatDetailsProceedDelayForTesting(0);
dalecurtis6c58ed02016-10-28 23:02:37357 DontCreateViewForTesting();
358 }
359};
360
361// A factory that creates TestSafeBrowsingBlockingPages.
362class TestSafeBrowsingBlockingPageFactory
363 : public SafeBrowsingBlockingPageFactory {
364 public:
365 TestSafeBrowsingBlockingPageFactory() {}
366 ~TestSafeBrowsingBlockingPageFactory() override {}
367
368 SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
jialiul3d6032e2017-01-12 00:41:31369 BaseUIManager* delegate,
dalecurtis6c58ed02016-10-28 23:02:37370 content::WebContents* web_contents,
371 const GURL& main_frame_url,
372 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
373 override {
374 return new TestSafeBrowsingBlockingPage(delegate, web_contents,
375 main_frame_url, unsafe_resources);
376 }
377};
378
379} // namespace
380
381// Tests that the WebContentsDelegate is notified of a visible security
382// state change when a blocking page is shown for a subresource.
383TEST_F(SafeBrowsingUIManagerTest,
384 VisibleSecurityStateChangedForUnsafeSubresource) {
385 TestSafeBrowsingBlockingPageFactory factory;
386 SafeBrowsingBlockingPage::RegisterFactory(&factory);
387 SecurityStateWebContentsDelegate delegate;
388 web_contents()->SetDelegate(&delegate);
389
390 // Simulate a blocking page showing for an unsafe subresource.
jialiul792a6662016-12-03 01:44:10391 security_interstitials::UnsafeResource resource =
dalecurtis6c58ed02016-10-28 23:02:37392 MakeUnsafeResource(kBadURL, true /* is_subresource */);
393 // Needed for showing the blocking page.
394 resource.threat_source = safe_browsing::ThreatSource::REMOTE;
395 NavigateAndCommit(GURL("http://example.test"));
396
397 delegate.ClearVisibleSecurityStateChanged();
398 EXPECT_FALSE(delegate.visible_security_state_changed());
399 ui_manager()->DisplayBlockingPage(resource);
400 EXPECT_TRUE(delegate.visible_security_state_changed());
401
402 // Simulate proceeding through the blocking page.
403 SafeBrowsingCallbackWaiter waiter;
404 resource.callback =
405 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDoneOnIO,
406 base::Unretained(&waiter));
407 resource.callback_thread =
408 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
jialiul792a6662016-12-03 01:44:10409 std::vector<security_interstitials::UnsafeResource> resources;
dalecurtis6c58ed02016-10-28 23:02:37410 resources.push_back(resource);
411
412 delegate.ClearVisibleSecurityStateChanged();
413 EXPECT_FALSE(delegate.visible_security_state_changed());
414 SimulateBlockingPageDone(resources, true);
415 EXPECT_TRUE(delegate.visible_security_state_changed());
416
417 waiter.WaitForCallback();
418 EXPECT_TRUE(waiter.callback_called());
419 EXPECT_TRUE(waiter.proceed());
420 EXPECT_TRUE(IsWhitelisted(resource));
421}
422
vakh9a474d832015-11-13 01:43:09423} // namespace safe_browsing