Chromium Code Reviews| Index: chrome/browser/safe_browsing/client_side_detection_host_unittest.cc |
| diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ebd78852624269decf2530ee9f7c4d64af301127 |
| --- /dev/null |
| +++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc |
| @@ -0,0 +1,191 @@ |
| +// Copyright (c) 2011 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 "base/command_line.h" |
| +#include "base/ref_counted.h" |
| +#include "base/scoped_ptr.h" |
| +#include "chrome/browser/browser_thread.h" |
| +#include "chrome/browser/renderer_host/test/test_render_view_host.h" |
| +#include "chrome/browser/safe_browsing/client_side_detection_host.h" |
| +#include "chrome/browser/safe_browsing/client_side_detection_service.h" |
| +#include "chrome/browser/safe_browsing/safe_browsing_service.h" |
| +#include "chrome/browser/tab_contents/test_tab_contents.h" |
| +#include "chrome/common/chrome_switches.h" |
| +#include "chrome/test/ui_test_utils.h" |
| +#include "googleurl/src/gurl.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gmock/include/gmock/gmock-spec-builders.h" |
| + |
| +using ::testing::_; |
| +using ::testing::DoAll; |
| +using ::testing::Mock; |
| +using ::testing::SaveArg; |
| + |
| +namespace safe_browsing { |
| + |
| +class MockClientSideDetectionService : public ClientSideDetectionService { |
| + public: |
| + MockClientSideDetectionService() {} |
| + virtual ~MockClientSideDetectionService() {}; |
| + |
| + MOCK_METHOD3(SendClientReportPhishingRequest, |
| + void(const GURL& phishing_url, |
|
Brian Ryner
2011/02/11 01:30:39
Hm, I usually see these written without the parame
noelutz
2011/02/15 23:00:55
Done.
|
| + double score, |
| + ClientReportPhishingRequestCallback* callback)); |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(MockClientSideDetectionService); |
| +}; |
| + |
| +class MockSafeBrowsingService : public SafeBrowsingService { |
| + public: |
| + MockSafeBrowsingService() {} |
| + virtual ~MockSafeBrowsingService() {} |
| + |
| + MOCK_METHOD7(DisplayBlockingPage, |
| + void(const GURL& url, |
| + const GURL& original_url, |
| + ResourceType::Type resource_type, |
| + UrlCheckResult result, |
| + Client* client, |
| + int render_process_host_id, |
| + int render_view_id)); |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingService); |
| +}; |
| + |
| +ACTION_P(QuitMessageLoop, msg_loop) { |
| + msg_loop->Quit(); |
| +} |
| + |
| +class ClientSideDetectionHostTest : public RenderViewHostTestHarness { |
| + public: |
| + virtual void SetUp() { |
| + RenderViewHostTestHarness::SetUp(); |
| + ui_thread_.reset(new BrowserThread(BrowserThread::UI, &message_loop_)); |
| + io_thread_.reset(new BrowserThread(BrowserThread::IO, &message_loop_)); |
|
Brian Ryner
2011/02/11 01:30:39
Unless there's a reason not to, you may want to ac
noelutz
2011/02/15 23:00:55
Done. This was much harder than I thought but it
|
| + |
| + // Inject service classes. |
| + csd_service_.reset(new MockClientSideDetectionService()); |
| + sb_service_ = new MockSafeBrowsingService(); |
| + csd_host_ = contents()->safebrowsing_detection_host(); |
| + csd_host_->set_client_side_detection_service(csd_service_.get()); |
| + csd_host_->set_safe_browsing_service(sb_service_.get()); |
|
lzheng
2011/02/11 19:39:42
You can get rid of these two set_xx by using SafeB
noelutz
2011/02/15 23:00:55
I don't think that would work. Another reason I i
lzheng
2011/02/16 19:09:32
Hm, let's stay with what you have for now. It is n
|
| + } |
| + |
| + virtual void TearDown() { |
| + io_thread_.reset(); |
| + ui_thread_.reset(); |
| + RenderViewHostTestHarness::TearDown(); |
| + } |
| + |
| + virtual void ExpectNotShowInterstitial() { |
| + // Make sure DisplayBlockingPage is not called. |
| + EXPECT_CALL(*sb_service_, |
| + DisplayBlockingPage(_, _, _, _, _, _, _)).Times(0); |
| + MessageLoop::current()->RunAllPending(); |
| + EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); |
| + } |
| + |
| + virtual void ExpectShowInterstital(const GURL& phishing_url) { |
| + |
|
Brian Ryner
2011/02/11 01:30:39
Extra blank line?
noelutz
2011/02/15 23:00:55
Done.
|
| + SafeBrowsingService::Client* client; |
| + EXPECT_CALL(*sb_service_, |
| + DisplayBlockingPage( |
| + phishing_url, |
| + phishing_url, |
| + ResourceType::MAIN_FRAME, |
| + SafeBrowsingService::URL_PHISHING, |
| + _ /* a CsdClient object */, |
| + contents()->GetRenderProcessHost()->id(), |
| + contents()->render_view_host()->routing_id())) |
| + .WillOnce(DoAll(SaveArg<4>(&client), |
| + QuitMessageLoop(MessageLoop::current()))); |
| + MessageLoop::current()->Run(); |
|
Brian Ryner
2011/02/11 01:30:39
This is kind of a nit, but you're using different
noelutz
2011/02/15 23:00:55
Agreed. It makes more sense to use the same logic
|
| + EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); |
| + ASSERT_TRUE(client != NULL); |
| + client->OnBlockingPageComplete(false); |
| + } |
| + |
| + protected: |
| + ClientSideDetectionHost* csd_host_; |
| + scoped_ptr<MockClientSideDetectionService> csd_service_; |
| + scoped_refptr<MockSafeBrowsingService> sb_service_; |
| + scoped_ptr<BrowserThread> ui_thread_; |
| + scoped_ptr<BrowserThread> io_thread_; |
| +}; |
| + |
| +TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSite) { |
| + ClientSideDetectionService::ClientReportPhishingRequestCallback* cb; |
| + GURL phishing_url("http://phishingurl.com/"); |
| + |
| + // Case 1: client thinks the page is phishing. The server does not agree. |
| + // No interstitial is shown. |
| + EXPECT_CALL(*csd_service_, |
| + SendClientReportPhishingRequest(phishing_url, 1.0, _)) |
| + .WillOnce(SaveArg<2>(&cb)); |
| + csd_host_->OnDetectedPhishingSite(phishing_url, 1.0); |
| + EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
| + ASSERT_TRUE(cb != NULL); |
| + cb->Run(phishing_url, false); |
| + delete cb; |
| + ExpectNotShowInterstitial(); |
| + |
| + // Case 2: client thinks the page is phishing and so does the server but |
| + // showing the interstitial is disabled => no interstitial is shown. |
| + EXPECT_CALL(*csd_service_, |
| + SendClientReportPhishingRequest(phishing_url, 1.0, _)) |
| + .WillOnce(SaveArg<2>(&cb)); |
| + csd_host_->OnDetectedPhishingSite(phishing_url, 1.0); |
| + EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
| + ASSERT_TRUE(cb != NULL); |
| + cb->Run(phishing_url, true); |
| + delete cb; |
| + ExpectNotShowInterstitial(); |
| + |
| + // Case 3: client thinks the page is phishing and so does the server. |
| + // We show an interstitial. |
| + EXPECT_CALL(*csd_service_, |
| + SendClientReportPhishingRequest(phishing_url, 1.0, _)) |
| + .WillOnce(SaveArg<2>(&cb)); |
| + csd_host_->OnDetectedPhishingSite(phishing_url, 1.0); |
| + CommandLine::ForCurrentProcess()->AppendSwitch( |
| + switches::kEnableClientSidePhishingInterstitial); |
| + EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
| + ASSERT_TRUE(cb != NULL); |
| + cb->Run(phishing_url, true); |
| + delete cb; |
| + // Verify that we would show an interstitial in this case. |
| + ExpectShowInterstital(phishing_url); |
| + |
| + // Case 4 & 5: client thinks a page is phishing then navigates to |
| + // another page which is also considered phishing by the client |
| + // before the server responds with a verdict. After a while the |
| + // server responds for both requests with a phishing verdict. Only |
| + // a single interstitial is shown for the second URL. |
| + EXPECT_CALL(*csd_service_, |
| + SendClientReportPhishingRequest(phishing_url, 1.0, _)) |
| + .WillOnce(SaveArg<2>(&cb)); |
| + csd_host_->OnDetectedPhishingSite(phishing_url, 1.0); |
| + EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
| + ASSERT_TRUE(cb != NULL); |
| + GURL other_phishing_url("http://other_phishing_url.com/bla"); |
| + // We navigate away. The callback cb should be revoked. |
| + NavigateAndCommit(other_phishing_url); |
| + ClientSideDetectionService::ClientReportPhishingRequestCallback* cb_other; |
| + EXPECT_CALL(*csd_service_, |
| + SendClientReportPhishingRequest(other_phishing_url, 0.8, _)) |
| + .WillOnce(SaveArg<2>(&cb_other)); |
| + csd_host_->OnDetectedPhishingSite(other_phishing_url, 0.8); |
| + EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
| + cb->Run(phishing_url, true); // Should have no effect. |
| + delete cb; |
| + cb_other->Run(other_phishing_url, true); // Should show interstitial. |
| + delete cb_other; |
| + // Check that only the interstitial for the other URL is shown. |
| + ExpectShowInterstital(other_phishing_url); |
| +} |
| + |
| +} // namespace safe_browsing |