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

Unified Diff: components/safe_browsing/request_checker_unittest.cc

Issue 2876473003: [ABANDONED] [WIP] Refactor SafeBrowsingResourceThrottle in preparation for WebSocket (Closed)
Patch Set: Minor fixes Created 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/safe_browsing/request_checker.cc ('k') | components/safe_browsing/resource_throttle.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/safe_browsing/request_checker_unittest.cc
diff --git a/components/safe_browsing/request_checker_unittest.cc b/components/safe_browsing/request_checker_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..486861cd5ebef904ac429edf4adf68b489ee6347
--- /dev/null
+++ b/components/safe_browsing/request_checker_unittest.cc
@@ -0,0 +1,504 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/safe_browsing/request_checker.h"
+
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/location.h"
+#include "base/memory/ref_counted.h"
+#include "base/run_loop.h"
+#include "base/time/time.h"
+#include "components/safe_browsing/base_ui_manager.h"
+#include "components/safe_browsing_db/database_manager.h"
+#include "components/safe_browsing_db/hit_report.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
+#include "components/security_interstitials/content/unsafe_resource.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/resource_type.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/base/load_flags.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace safe_browsing {
+
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::InSequence;
+using ::testing::Return;
+using ::testing::MockFunction;
+using ::testing::NiceMock;
+using ::testing::SaveArg;
+using ::testing::StrictMock;
+using ::testing::_;
+
+constexpr char kTestUrl[] = "test:";
+constexpr char kTestUrl2[] = "test:2";
+constexpr char kTestUrl3[] = "test:3";
+
+// A checkpoint can be used to verify the relative ordering of mocked calls and
+// real calls to the code under test.
+typedef StrictMock<MockFunction<void(int)>> Checkpoint;
+
+class StubUIManager : public BaseUIManager {
+ public:
+ StubUIManager() {}
+
+ // Override all the methods on the base class to eliminate all side-effects.
+ void StopOnIOThread(bool shutdown) override {}
+ void DisplayBlockingPage(const UnsafeResource& resource) override {}
+ void LogPauseDelay(base::TimeDelta time) override {}
+ void SendSerializedThreatDetails(const std::string& serialized) override {}
+ void MaybeReportSafeBrowsingHit(
+ const safe_browsing::HitReport& hit_report) override {}
+ bool IsWhitelisted(const UnsafeResource& resource) override { return false; }
+ bool IsUrlWhitelistedOrPendingForWebContents(
+ const GURL& url,
+ bool is_subresource,
+ content::NavigationEntry* entry,
+ content::WebContents* web_contents,
+ bool whitelist_only,
+ SBThreatType* threat_type) override {
+ return false;
+ }
+ void OnBlockingPageDone(const std::vector<UnsafeResource>& resources,
+ bool proceed,
+ content::WebContents* web_contents,
+ const GURL& main_frame_url) override {}
+ const std::string app_locale() const override { return "C"; }
+ history::HistoryService* history_service(
+ content::WebContents* web_contents) override {
+ return nullptr;
+ }
+ const GURL default_safe_page() const override { return GURL(); }
+
+ protected:
+ ~StubUIManager() override {}
+
+ // These should never be called. Override them anyway to be on the safe side.
+ void ReportSafeBrowsingHitOnIOThread(
+ const safe_browsing::HitReport& hit_report) override {}
+ void CreateAndSendHitReport(const UnsafeResource& resource) override {}
+ void ShowBlockingPageForResource(const UnsafeResource& resource) override {}
+};
+
+// RequestChecker only uses one method from UIManager, LogPauseDelay, so only
+// mock that one.
+class SemiMockUIManager : public StubUIManager {
+ public:
+ MOCK_METHOD1(LogPauseDelay, void(base::TimeDelta));
+
+ protected:
+ ~SemiMockUIManager() {}
+};
+
+class MockDelegate : public RequestChecker::Delegate {
+ public:
+ MOCK_METHOD1(MaybeDestroyPrerenderContents, void(const WebContentsGetter&));
+ MOCK_CONST_METHOD1(GetWebContentsGetterForRequest,
+ WebContentsGetter(const net::URLRequest* request));
+ MOCK_METHOD2(StartDisplayingBlockingPage,
+ void(const security_interstitials::UnsafeResource& resource,
+ scoped_refptr<BaseUIManager> ui_manager));
+ MOCK_METHOD0(CancelResourceLoad, void());
+ MOCK_METHOD0(ResumeResourceRequest, void());
+};
+
+class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
+ public:
+ MOCK_METHOD1(CancelApiCheck, bool(Client* client));
+ MOCK_METHOD1(CancelCheck, void(Client* client));
+ MOCK_CONST_METHOD1(CanCheckResourceType,
+ bool(content::ResourceType resource_type));
+ MOCK_CONST_METHOD1(CanCheckUrl, bool(const GURL& url));
+ MOCK_CONST_METHOD0(ChecksAreAlwaysAsync, bool());
+ MOCK_METHOD2(CheckApiBlacklistUrl, bool(const GURL& url, Client* client));
+ MOCK_METHOD2(CheckBrowseUrl, bool(const GURL& url, Client* client));
+ MOCK_METHOD2(CheckUrlForSubresourceFilter,
+ bool(const GURL& url, Client* client));
+ MOCK_METHOD2(CheckDownloadUrl,
+ bool(const std::vector<GURL>& url_chain, Client* client));
+ MOCK_METHOD2(CheckExtensionIDs,
+ bool(const std::set<std::string>& extension_ids,
+ Client* client));
+ MOCK_METHOD2(CheckResourceUrl, bool(const GURL& url, Client* client));
+ MOCK_METHOD1(MatchCsdWhitelistUrl, bool(const GURL& url));
+ MOCK_METHOD1(MatchDownloadWhitelistString, bool(const std::string& str));
+ MOCK_METHOD1(MatchDownloadWhitelistUrl, bool(const GURL& url));
+ MOCK_METHOD1(MatchMalwareIP, bool(const std::string& ip_address));
+ MOCK_METHOD1(MatchModuleWhitelistString, bool(const std::string& str));
+ MOCK_METHOD0(GetStoresForFullHashRequests, StoresToCheck());
+ MOCK_CONST_METHOD0(GetThreatSource, ThreatSource());
+ MOCK_METHOD0(IsCsdWhitelistKillSwitchOn, bool());
+ MOCK_CONST_METHOD0(IsDownloadProtectionEnabled, bool());
+ MOCK_METHOD0(IsMalwareKillSwitchOn, bool());
+ MOCK_CONST_METHOD0(IsSupported, bool());
+ MOCK_METHOD2(StartOnIOThread,
+ void(net::URLRequestContextGetter* request_context_getter,
+ const V4ProtocolConfig& config));
+ MOCK_METHOD1(StopOnIOThread, void(bool shutdown));
+
+ protected:
+ ~MockSafeBrowsingDatabaseManager() {}
+};
+
+class RequestCheckerTest : public ::testing::Test {
+ protected:
+ RequestCheckerTest()
+ : request_(url_request_context_.CreateRequest(GURL(kTestUrl),
+ net::DEFAULT_PRIORITY,
+ nullptr)),
+ database_manager_(new NiceMock<MockSafeBrowsingDatabaseManager>()),
+ ui_manager_(new NiceMock<SemiMockUIManager>()),
+ delegate_(base::MakeUnique<NiceMock<MockDelegate>>()),
+ checker_(base::MakeUnique<RequestChecker>(
+ request_.get(),
+ content::RESOURCE_TYPE_SUB_RESOURCE,
+ database_manager_,
+ ui_manager_,
+ delegate_.get())) {
+ // CanCheckResourceType() is called by almost all tests so make it pass by
+ // default.
+ ON_CALL(*database_manager_, CanCheckResourceType(_))
+ .WillByDefault(Return(true));
+ }
+ ~RequestCheckerTest() override {
+ // It's possible that something could hold a reference to these objects
+ // after the framework is destroyed, so make sure mock expectations have
+ // been verified.
+ ::testing::Mock::VerifyAndClearExpectations(database_manager_.get());
+ ::testing::Mock::VerifyAndClearExpectations(ui_manager_.get());
+ }
+
+ const content::TestBrowserThreadBundle test_browser_thread_bundle_;
+ net::TestURLRequestContext url_request_context_;
+ const std::unique_ptr<net::URLRequest> request_;
+ const scoped_refptr<NiceMock<MockSafeBrowsingDatabaseManager>>
+ database_manager_;
+ const scoped_refptr<NiceMock<SemiMockUIManager>> ui_manager_;
+ const std::unique_ptr<NiceMock<MockDelegate>> delegate_;
+ std::unique_ptr<RequestChecker> checker_;
+};
+
+TEST_F(RequestCheckerTest, Constructs) {
+ // The framework constructor does all the work.
+}
+
+TEST_F(RequestCheckerTest, UncheckedResourceType) {
+ EXPECT_CALL(*database_manager_,
+ CanCheckResourceType(content::RESOURCE_TYPE_SUB_RESOURCE))
+ .WillOnce(Return(false));
+ EXPECT_EQ(RequestChecker::PROCEED_SKIPPED, checker_->CheckNewRequest());
+}
+
+TEST_F(RequestCheckerTest, SynchronousPass) {
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(true));
+ EXPECT_EQ(RequestChecker::PROCEED_SAFE, checker_->CheckNewRequest());
+}
+
+TEST_F(RequestCheckerTest, CorrectUrlIsPassedToDatabaseManager) {
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(GURL(kTestUrl), _))
+ .WillOnce(Return(true));
+ checker_->CheckNewRequest();
+}
+
+TEST_F(RequestCheckerTest, ZeroDelayIsLogged) {
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(true));
+ EXPECT_CALL(*ui_manager_, LogPauseDelay(base::TimeDelta()));
+ checker_->CheckNewRequest();
+}
+
+TEST_F(RequestCheckerTest, SyncMissAsyncProceed) {
+ Checkpoint checkpoint;
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*database_manager_, ChecksAreAlwaysAsync())
+ .WillOnce(Return(false));
+ {
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*delegate_, ResumeResourceRequest());
+ }
+
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckNewRequest());
+ checkpoint.Call(1);
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_SAFE,
+ ThreatMetadata());
+}
+
+TEST_F(RequestCheckerTest, SyncMissAsyncUnsafe) {
+ security_interstitials::UnsafeResource resource;
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*database_manager_, ChecksAreAlwaysAsync())
+ .WillOnce(Return(false));
+ EXPECT_CALL(*delegate_, StartDisplayingBlockingPage(_, _))
+ .WillOnce(SaveArg<0>(&resource));
+ EXPECT_CALL(*delegate_, GetWebContentsGetterForRequest(request_.get()))
+ .WillOnce(Return(
+ base::Bind([]() -> content::WebContents* { return nullptr; })));
+ EXPECT_CALL(*database_manager_, GetThreatSource())
+ .WillOnce(Return(ThreatSource::LOCAL_PVER4));
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckNewRequest());
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_URL_MALWARE,
+ ThreatMetadata());
+ EXPECT_EQ(GURL(kTestUrl), resource.url);
+ EXPECT_EQ(request_->original_url(), resource.original_url);
+ EXPECT_EQ(0u, resource.redirect_urls.size());
+ EXPECT_TRUE(resource.is_subresource);
+ EXPECT_FALSE(resource.is_subframe);
+ EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, resource.threat_type);
+ EXPECT_EQ(ThreatMetadata(), resource.threat_metadata);
+ EXPECT_FALSE(resource.callback.is_null());
+ EXPECT_TRUE(resource.callback_thread);
+ EXPECT_EQ(nullptr, resource.web_contents_getter.Run());
+ EXPECT_EQ(ThreatSource::LOCAL_PVER4, resource.threat_source);
+}
+
+TEST_F(RequestCheckerTest, SyncMissAsyncUnsafeBlockBypassed) {
+ security_interstitials::UnsafeResource resource;
+ Checkpoint checkpoint;
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*database_manager_, ChecksAreAlwaysAsync())
+ .WillOnce(Return(false));
+ EXPECT_CALL(*delegate_, StartDisplayingBlockingPage(_, _))
+ .WillOnce(SaveArg<0>(&resource));
+ EXPECT_CALL(*delegate_, GetWebContentsGetterForRequest(request_.get()))
+ .WillOnce(Return(
+ base::Bind([]() -> content::WebContents* { return nullptr; })));
+ EXPECT_CALL(*database_manager_, GetThreatSource())
+ .WillOnce(Return(ThreatSource::LOCAL_PVER4));
+ {
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*delegate_, ResumeResourceRequest());
+ }
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckNewRequest());
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_URL_MALWARE,
+ ThreatMetadata());
+ checkpoint.Call(1);
+ resource.callback.Run(true);
+}
+
+TEST_F(RequestCheckerTest, SyncMissAsyncUnsafeBlockRejected) {
+ security_interstitials::UnsafeResource resource;
+ Checkpoint checkpoint;
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*database_manager_, ChecksAreAlwaysAsync())
+ .WillOnce(Return(false));
+ EXPECT_CALL(*delegate_, StartDisplayingBlockingPage(_, _))
+ .WillOnce(SaveArg<0>(&resource));
+ EXPECT_CALL(*delegate_, GetWebContentsGetterForRequest(request_.get()))
+ .WillOnce(Return(
+ base::Bind([]() -> content::WebContents* { return nullptr; })));
+ EXPECT_CALL(*database_manager_, GetThreatSource())
+ .WillOnce(Return(ThreatSource::LOCAL_PVER4));
+ {
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*delegate_, CancelResourceLoad());
+ }
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckNewRequest());
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_URL_MALWARE,
+ ThreatMetadata());
+ checkpoint.Call(1);
+ resource.callback.Run(false);
+}
+
+TEST_F(RequestCheckerTest, AlwaysAsyncSafe) {
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*database_manager_, ChecksAreAlwaysAsync())
+ .WillRepeatedly(Return(true));
+ // ResumeResourceRequest() must not be called.
+ EXPECT_CALL(*delegate_, ResumeResourceRequest()).Times(0);
+ EXPECT_EQ(RequestChecker::PROCEED_ALWAYS_ASYNC, checker_->CheckNewRequest());
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_SAFE,
+ ThreatMetadata());
+ EXPECT_EQ(RequestChecker::PROCEED_SAFE, checker_->ShouldDeferResponse());
+}
+
+TEST_F(RequestCheckerTest, AlwaysAsyncLateSafe) {
+ Checkpoint checkpoint;
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*database_manager_, ChecksAreAlwaysAsync())
+ .WillRepeatedly(Return(true));
+ {
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*delegate_, ResumeResourceRequest());
+ }
+ EXPECT_EQ(RequestChecker::PROCEED_ALWAYS_ASYNC, checker_->CheckNewRequest());
+ EXPECT_EQ(RequestChecker::DEFER, checker_->ShouldDeferResponse());
+ checkpoint.Call(1);
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_SAFE,
+ ThreatMetadata());
+}
+
+TEST_F(RequestCheckerTest, AlwaysAsyncUnsafe) {
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*database_manager_, ChecksAreAlwaysAsync())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*delegate_, StartDisplayingBlockingPage(_, _));
+ EXPECT_CALL(*delegate_, GetWebContentsGetterForRequest(request_.get()))
+ .WillOnce(Return(
+ base::Bind([]() -> content::WebContents* { return nullptr; })));
+ EXPECT_CALL(*database_manager_, GetThreatSource())
+ .WillOnce(Return(ThreatSource::LOCAL_PVER4));
+ // ResumeResourceRequest() must not be called.
+ EXPECT_CALL(*delegate_, ResumeResourceRequest()).Times(0);
+ EXPECT_EQ(RequestChecker::PROCEED_ALWAYS_ASYNC, checker_->CheckNewRequest());
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_URL_MALWARE,
+ ThreatMetadata());
+ EXPECT_EQ(RequestChecker::DEFER, checker_->ShouldDeferResponse());
+}
+
+TEST_F(RequestCheckerTest, RedirectToSafeSync) {
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _))
+ .WillRepeatedly(Return(true));
+ EXPECT_EQ(RequestChecker::PROCEED_SAFE, checker_->CheckNewRequest());
+ EXPECT_EQ(RequestChecker::PROCEED_SAFE,
+ checker_->CheckRedirect(GURL(kTestUrl2)));
+}
+
+TEST_F(RequestCheckerTest, RedirectToSafeAsync) {
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _))
+ .WillOnce(Return(true))
+ .WillOnce(Return(false));
+ EXPECT_CALL(*delegate_, ResumeResourceRequest());
+ EXPECT_EQ(RequestChecker::PROCEED_SAFE, checker_->CheckNewRequest());
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckRedirect(GURL(kTestUrl2)));
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl2), SB_THREAT_TYPE_SAFE,
+ ThreatMetadata());
+}
+
+TEST_F(RequestCheckerTest, RedirectToUnsafe) {
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _))
+ .WillOnce(Return(true))
+ .WillOnce(Return(false));
+ EXPECT_CALL(*delegate_, StartDisplayingBlockingPage(_, _));
+ EXPECT_EQ(RequestChecker::PROCEED_SAFE, checker_->CheckNewRequest());
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckRedirect(GURL(kTestUrl2)));
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl2), SB_THREAT_TYPE_URL_MALWARE,
+ ThreatMetadata());
+}
+
+TEST_F(RequestCheckerTest, RedirectToSafeThenUnsafe) {
+ security_interstitials::UnsafeResource resource;
+ Checkpoint checkpoint;
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _))
+ .WillOnce(Return(true))
+ .WillRepeatedly(Return(false));
+ {
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*delegate_, ResumeResourceRequest());
+ EXPECT_CALL(checkpoint, Call(2));
+ EXPECT_CALL(*delegate_, StartDisplayingBlockingPage(_, _))
+ .WillOnce(SaveArg<0>(&resource));
+ }
+ EXPECT_EQ(RequestChecker::PROCEED_SAFE, checker_->CheckNewRequest());
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckRedirect(GURL(kTestUrl2)));
+ checkpoint.Call(1);
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl2), SB_THREAT_TYPE_SAFE,
+ ThreatMetadata());
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckRedirect(GURL(kTestUrl3)));
+ checkpoint.Call(2);
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl3), SB_THREAT_TYPE_URL_MALWARE,
+ ThreatMetadata());
+ EXPECT_EQ(GURL(kTestUrl3), resource.url);
+ EXPECT_EQ(GURL(kTestUrl), resource.original_url);
+ EXPECT_THAT(resource.redirect_urls,
+ ElementsAre(GURL(kTestUrl2), GURL(kTestUrl3)));
+}
+
+TEST_F(RequestCheckerTest, RedirectToSafeAlwaysAsync) {
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(*database_manager_, ChecksAreAlwaysAsync())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*delegate_, ResumeResourceRequest());
+ EXPECT_EQ(RequestChecker::PROCEED_ALWAYS_ASYNC, checker_->CheckNewRequest());
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckRedirect(GURL(kTestUrl2)));
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_SAFE,
+ ThreatMetadata());
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl2), SB_THREAT_TYPE_SAFE,
+ ThreatMetadata());
+}
+
+TEST_F(RequestCheckerTest, AsyncTimeout) {
+ ScopedTimeoutForTesting scoped_timeout(1);
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*database_manager_, CancelCheck(_));
+ EXPECT_CALL(*delegate_, ResumeResourceRequest());
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckNewRequest());
+ base::RunLoop run_loop;
+ content::BrowserThread::PostDelayedTask(content::BrowserThread::IO, FROM_HERE,
+ run_loop.QuitClosure(),
+ base::TimeDelta::FromMilliseconds(2));
+ run_loop.Run();
+}
+
+TEST_F(RequestCheckerTest, TimeoutIsReallyCancelled) {
+ // The test is not flaky because OnCheckBrowseUrlResult() is called
+ // synchronously, and so will always succeed in cancelling the timer before
+ // OnCheckUrlTimeout can be called asynchronously.
+ ScopedTimeoutForTesting scoped_timeout(1);
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*database_manager_, CancelCheck(_)).Times(0);
+ EXPECT_CALL(*delegate_, ResumeResourceRequest());
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckNewRequest());
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_SAFE,
+ ThreatMetadata());
+ base::RunLoop run_loop;
+ content::BrowserThread::PostDelayedTask(content::BrowserThread::IO, FROM_HERE,
+ run_loop.QuitClosure(),
+ base::TimeDelta::FromMilliseconds(2));
+ run_loop.Run();
+ // If we get here without hitting a DCHECK then the test passed.
+}
+
+TEST_F(RequestCheckerTest, PrefetchCancelledOnAsyncBlock) {
+ request_->SetLoadFlags(request_->load_flags() | net::LOAD_PREFETCH);
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*delegate_, CancelResourceLoad());
+ // Blocking page is not displayed for prefetch / prerender.
+ EXPECT_CALL(*delegate_, StartDisplayingBlockingPage(_, _)).Times(0);
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckNewRequest());
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_URL_MALWARE,
+ ThreatMetadata());
+}
+
+TEST_F(RequestCheckerTest, PrerenderContentsDestroyed) {
+ request_->SetLoadFlags(request_->load_flags() | net::LOAD_PREFETCH);
+ // Change resource type to MAIN_FRAME.
+ checker_.reset(
+ new RequestChecker(request_.get(), content::RESOURCE_TYPE_MAIN_FRAME,
+ database_manager_, ui_manager_, delegate_.get()));
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*delegate_, CancelResourceLoad());
+ EXPECT_CALL(*delegate_, MaybeDestroyPrerenderContents(_));
+ EXPECT_CALL(*delegate_, StartDisplayingBlockingPage(_, _)).Times(0);
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckNewRequest());
+ checker_->OnCheckBrowseUrlResult(GURL(kTestUrl), SB_THREAT_TYPE_URL_MALWARE,
+ ThreatMetadata());
+}
+
+TEST_F(RequestCheckerTest, CheckCancelledOnDestruction) {
+ EXPECT_CALL(*database_manager_, CheckBrowseUrl(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*database_manager_, CancelCheck(_));
+ EXPECT_EQ(RequestChecker::DEFER, checker_->CheckNewRequest());
+ checker_.reset();
+}
+
+} // namespace
+
+} // namespace safe_browsing
« no previous file with comments | « components/safe_browsing/request_checker.cc ('k') | components/safe_browsing/resource_throttle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698