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

Side by Side Diff: chrome/browser/safe_browsing/client_side_detection_host_unittest.cc

Issue 6014003: Intergration of the client-side phishing detection. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync Created 9 years, 10 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "base/command_line.h"
6 #include "base/file_path.h"
7 #include "base/ref_counted.h"
8 #include "base/scoped_ptr.h"
9 #include "base/scoped_temp_dir.h"
10 #include "base/task.h"
11 #include "chrome/browser/browser_thread.h"
12 #include "chrome/browser/renderer_host/test/test_render_view_host.h"
13 #include "chrome/browser/safe_browsing/client_side_detection_host.h"
14 #include "chrome/browser/safe_browsing/client_side_detection_service.h"
15 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
16 #include "chrome/browser/tab_contents/test_tab_contents.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/test/ui_test_utils.h"
19 #include "googleurl/src/gurl.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gmock/include/gmock/gmock-spec-builders.h"
22
23 using ::testing::_;
24 using ::testing::DoAll;
25 using ::testing::Mock;
26 using ::testing::SaveArg;
27
28 namespace safe_browsing {
29
30 class MockClientSideDetectionService : public ClientSideDetectionService {
31 public:
32 MockClientSideDetectionService(const FilePath& model_path)
33 : ClientSideDetectionService(model_path, NULL) {}
34 virtual ~MockClientSideDetectionService() {};
35
36 MOCK_METHOD3(SendClientReportPhishingRequest,
37 void(const GURL&, double, ClientReportPhishingRequestCallback*));
38
39 private:
40 DISALLOW_COPY_AND_ASSIGN(MockClientSideDetectionService);
41 };
42
43 class MockSafeBrowsingService : public SafeBrowsingService {
44 public:
45 MockSafeBrowsingService() {}
46 virtual ~MockSafeBrowsingService() {}
47
48 MOCK_METHOD8(DisplayBlockingPage,
49 void(const GURL&, const GURL&, const std::vector<GURL>&,
50 ResourceType::Type, UrlCheckResult, Client*, int, int));
51
52 // Helper function which calls OnBlockingPageComplete for this client
53 // object.
54 void InvokeOnBlockingPageComplete(SafeBrowsingService::Client* client) {
55 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
56 DCHECK(client);
57 // Note: this will delete the client object in the case of the CsdClient
58 // implementation.
59 client->OnBlockingPageComplete(false);
60 }
61
62 private:
63 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingService);
64 };
65
66 // Helper function which quits the UI message loop from the IO message loop.
67 void QuitUIMessageLoop() {
68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
69 BrowserThread::PostTask(BrowserThread::UI,
70 FROM_HERE,
71 new MessageLoop::QuitTask());
72 }
73
74 class ClientSideDetectionHostTest : public RenderViewHostTestHarness {
75 public:
76 virtual void SetUp() {
77 RenderViewHostTestHarness::SetUp();
78 ui_thread_.reset(new BrowserThread(BrowserThread::UI, &message_loop_));
79 // Note: we're starting a real IO thread to make sure our DCHECKs that
80 // verify which thread is running are actually tested.
81 io_thread_.reset(new BrowserThread(BrowserThread::IO));
82 ASSERT_TRUE(io_thread_->Start());
83
84 // Inject service classes.
85 ScopedTempDir tmp_dir;
86 ASSERT_TRUE(tmp_dir.CreateUniqueTempDir());
87 FilePath model_path = tmp_dir.path().AppendASCII("model");
88
89 csd_service_.reset(new MockClientSideDetectionService(model_path));
90 sb_service_ = new MockSafeBrowsingService();
91 csd_host_ = contents()->safebrowsing_detection_host();
92 csd_host_->set_client_side_detection_service(csd_service_.get());
93 csd_host_->set_safe_browsing_service(sb_service_.get());
94 }
95
96 virtual void TearDown() {
97 io_thread_.reset();
98 ui_thread_.reset();
99 RenderViewHostTestHarness::TearDown();
100 }
101
102 void OnDetectedPhishingSite(const GURL& phishing_url, double phishing_score) {
103 csd_host_->OnDetectedPhishingSite(phishing_url, phishing_score);
104 }
105
106 void FlushIOMessageLoop() {
107 // If there was a message posted on the IO thread to display the
108 // interstitial page we know that it would have been posted before
109 // we put the quit message there.
110 BrowserThread::PostTask(BrowserThread::IO,
111 FROM_HERE,
112 NewRunnableFunction(&QuitUIMessageLoop));
113 MessageLoop::current()->Run();
114 }
115
116 protected:
117 ClientSideDetectionHost* csd_host_;
118 scoped_ptr<MockClientSideDetectionService> csd_service_;
119 scoped_refptr<MockSafeBrowsingService> sb_service_;
120
121 private:
122 scoped_ptr<BrowserThread> ui_thread_;
123 scoped_ptr<BrowserThread> io_thread_;
124 };
125
126 TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSiteNotPhishing) {
127 // Case 1: client thinks the page is phishing. The server does not agree.
128 // No interstitial is shown.
129 ClientSideDetectionService::ClientReportPhishingRequestCallback* cb;
130 GURL phishing_url("http://phishingurl.com/");
131
132 EXPECT_CALL(*csd_service_,
133 SendClientReportPhishingRequest(phishing_url, 1.0, _))
134 .WillOnce(SaveArg<2>(&cb));
135 OnDetectedPhishingSite(phishing_url, 1.0);
136 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
137 ASSERT_TRUE(cb != NULL);
138
139 // Make sure DisplayBlockingPage is not going to be called.
140 EXPECT_CALL(*sb_service_,
141 DisplayBlockingPage(_, _, _, _, _, _, _, _)).Times(0);
142 cb->Run(phishing_url, false);
143 delete cb;
144 // If there was a message posted on the IO thread to display the
145 // interstitial page we know that it would have been posted before
146 // we put the quit message there.
147 BrowserThread::PostTask(BrowserThread::IO,
148 FROM_HERE,
149 NewRunnableFunction(&QuitUIMessageLoop));
150 MessageLoop::current()->Run();
151 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get()));
152 }
153
154 TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSiteDisabled) {
155 // Case 2: client thinks the page is phishing and so does the server but
156 // showing the interstitial is disabled => no interstitial is shown.
157 ClientSideDetectionService::ClientReportPhishingRequestCallback* cb;
158 GURL phishing_url("http://phishingurl.com/");
159
160 EXPECT_CALL(*csd_service_,
161 SendClientReportPhishingRequest(phishing_url, 1.0, _))
162 .WillOnce(SaveArg<2>(&cb));
163 OnDetectedPhishingSite(phishing_url, 1.0);
164 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
165 ASSERT_TRUE(cb != NULL);
166
167 // Make sure DisplayBlockingPage is not going to be called.
168 EXPECT_CALL(*sb_service_,
169 DisplayBlockingPage(_, _, _, _, _, _, _, _)).Times(0);
170 cb->Run(phishing_url, false);
171 delete cb;
172
173 FlushIOMessageLoop();
174 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get()));
175 }
176
177 TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSiteShowInterstitial) {
178 // Case 3: client thinks the page is phishing and so does the server.
179 // We show an interstitial.
180 ClientSideDetectionService::ClientReportPhishingRequestCallback* cb;
181 GURL phishing_url("http://phishingurl.com/");
182
183 CommandLine::ForCurrentProcess()->AppendSwitch(
184 switches::kEnableClientSidePhishingInterstitial);
185
186 EXPECT_CALL(*csd_service_,
187 SendClientReportPhishingRequest(phishing_url, 1.0, _))
188 .WillOnce(SaveArg<2>(&cb));
189 OnDetectedPhishingSite(phishing_url, 1.0);
190 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
191 ASSERT_TRUE(cb != NULL);
192
193 SafeBrowsingService::Client* client;
194 EXPECT_CALL(*sb_service_,
195 DisplayBlockingPage(
196 phishing_url,
197 phishing_url,
198 _,
199 ResourceType::MAIN_FRAME,
200 SafeBrowsingService::URL_PHISHING,
201 _ /* a CsdClient object */,
202 contents()->GetRenderProcessHost()->id(),
203 contents()->render_view_host()->routing_id()))
204 .WillOnce(SaveArg<5>(&client));
205
206 cb->Run(phishing_url, true);
207 delete cb;
208
209 FlushIOMessageLoop();
210 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get()));
211
212 // Make sure the client object will be deleted.
213 BrowserThread::PostTask(
214 BrowserThread::IO,
215 FROM_HERE,
216 NewRunnableMethod(
217 sb_service_.get(),
218 &MockSafeBrowsingService::InvokeOnBlockingPageComplete,
219 client));
220 // Since the CsdClient object will be deleted on the UI thread I need
221 // to run the UI message loop. Post a task to stop the UI message loop
222 // after the client object destructor is called.
223 FlushIOMessageLoop();
224 }
225
226 TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSiteMultiplePings) {
227 // Case 4 & 5: client thinks a page is phishing then navigates to
228 // another page which is also considered phishing by the client
229 // before the server responds with a verdict. After a while the
230 // server responds for both requests with a phishing verdict. Only
231 // a single interstitial is shown for the second URL.
232 ClientSideDetectionService::ClientReportPhishingRequestCallback* cb;
233 GURL phishing_url("http://phishingurl.com/");
234
235 CommandLine::ForCurrentProcess()->AppendSwitch(
236 switches::kEnableClientSidePhishingInterstitial);
237
238 EXPECT_CALL(*csd_service_,
239 SendClientReportPhishingRequest(phishing_url, 1.0, _))
240 .WillOnce(SaveArg<2>(&cb));
241 OnDetectedPhishingSite(phishing_url, 1.0);
242 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
243 ASSERT_TRUE(cb != NULL);
244 GURL other_phishing_url("http://other_phishing_url.com/bla");
245 // We navigate away. The callback cb should be revoked.
246 NavigateAndCommit(other_phishing_url);
247
248 ClientSideDetectionService::ClientReportPhishingRequestCallback* cb_other;
249 EXPECT_CALL(*csd_service_,
250 SendClientReportPhishingRequest(other_phishing_url, 0.8, _))
251 .WillOnce(SaveArg<2>(&cb_other));
252 OnDetectedPhishingSite(other_phishing_url, 0.8);
253 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
254 ASSERT_TRUE(cb_other);
255
256 // We expect that the interstitial is shown for the second phishing URL and
257 // not for the first phishing URL.
258 EXPECT_CALL(*sb_service_,
259 DisplayBlockingPage(phishing_url, phishing_url,_, _, _, _, _, _))
260 .Times(0);
261 SafeBrowsingService::Client* client;
262 EXPECT_CALL(*sb_service_,
263 DisplayBlockingPage(
264 other_phishing_url,
265 other_phishing_url,
266 _,
267 ResourceType::MAIN_FRAME,
268 SafeBrowsingService::URL_PHISHING,
269 _ /* a CsdClient object */,
270 contents()->GetRenderProcessHost()->id(),
271 contents()->render_view_host()->routing_id()))
272 .WillOnce(SaveArg<5>(&client));
273
274 cb->Run(phishing_url, true); // Should have no effect.
275 delete cb;
276 cb_other->Run(other_phishing_url, true); // Should show interstitial.
277 delete cb_other;
278
279 FlushIOMessageLoop();
280 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get()));
281
282 // Make sure the client object will be deleted.
283 BrowserThread::PostTask(
284 BrowserThread::IO,
285 FROM_HERE,
286 NewRunnableMethod(
287 sb_service_.get(),
288 &MockSafeBrowsingService::InvokeOnBlockingPageComplete,
289 client));
290 // Since the CsdClient object will be deleted on the UI thread I need
291 // to run the UI message loop. Post a task to stop the UI message loop
292 // after the client object destructor is called.
293 FlushIOMessageLoop();
294 }
295
296 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698