1 // Copyright (c) 2012 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.
8 #include "base/pickle.h"
9 #include "base/run_loop.h"
10 #include "base/time/time.h"
11 #include "chrome/browser/history/history_backend.h"
12 #include "chrome/browser/history/history_service.h"
13 #include "chrome/browser/history/history_service_factory.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/safe_browsing/malware_details.h"
16 #include "chrome/browser/safe_browsing/malware_details_history.h"
17 #include "chrome/browser/safe_browsing/report.pb.h"
18 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
19 #include "chrome/browser/safe_browsing/ui_manager.h"
20 #include "chrome/common/render_messages.h"
21 #include "chrome/common/safe_browsing/safebrowsing_messages.h"
22 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
23 #include "chrome/test/base/testing_profile.h"
24 #include "content/public/browser/render_process_host.h"
25 #include "content/public/browser/web_contents.h"
26 #include "net/base/io_buffer.h"
27 #include "net/base/net_errors.h"
28 #include "net/base/test_completion_callback.h"
29 #include "net/disk_cache/disk_cache.h"
30 #include "net/http/http_cache.h"
31 #include "net/http/http_response_headers.h"
32 #include "net/http/http_response_info.h"
33 #include "net/http/http_util.h"
34 #include "net/url_request/url_request_context.h"
35 #include "net/url_request/url_request_context_getter.h"
37 static const char* kOriginalLandingURL
= "http://www.originallandingpage.com/";
38 static const char* kHttpsURL
= "https://www.url.com/";
39 static const char* kDOMChildURL
= "http://www.domparent.com/";
40 static const char* kDOMParentURL
= "http://www.domchild.com/";
41 static const char* kFirstRedirectURL
= "http://redirectone.com/";
42 static const char* kSecondRedirectURL
= "http://redirecttwo.com/";
44 static const char* kMalwareURL
= "http://www.malware.com/";
45 static const char* kMalwareHeaders
=
47 "Content-Type: image/jpeg\n";
48 static const char* kMalwareData
= "exploit();";
50 static const char* kLandingURL
= "http://www.landingpage.com/";
51 static const char* kLandingHeaders
=
53 "Content-Type: text/html\n"
54 "Content-Length: 1024\n"
55 "Set-Cookie: tastycookie\n"; // This header is stripped.
56 static const char* kLandingData
= "<iframe src='http://www.malware.com'>";
58 using content::BrowserThread
;
59 using content::WebContents
;
60 using safe_browsing::ClientMalwareReportRequest
;
64 void WriteHeaders(disk_cache::Entry
* entry
, const std::string
& headers
) {
65 net::HttpResponseInfo responseinfo
;
66 std::string raw_headers
= net::HttpUtil::AssembleRawHeaders(
67 headers
.c_str(), headers
.size());
68 responseinfo
.socket_address
= net::HostPortPair("1.2.3.4", 80);
69 responseinfo
.headers
= new net::HttpResponseHeaders(raw_headers
);
72 responseinfo
.Persist(&pickle
, false, false);
74 scoped_refptr
<net::WrappedIOBuffer
> buf(new net::WrappedIOBuffer(
75 reinterpret_cast<const char*>(pickle
.data())));
76 int len
= static_cast<int>(pickle
.size());
78 net::TestCompletionCallback cb
;
79 int rv
= entry
->WriteData(0, 0, buf
.get(), len
, cb
.callback(), true);
80 ASSERT_EQ(len
, cb
.GetResult(rv
));
83 void WriteData(disk_cache::Entry
* entry
, const std::string
& data
) {
87 int len
= data
.length();
88 scoped_refptr
<net::IOBuffer
> buf(new net::IOBuffer(len
));
89 memcpy(buf
->data(), data
.data(), data
.length());
91 net::TestCompletionCallback cb
;
92 int rv
= entry
->WriteData(1, 0, buf
.get(), len
, cb
.callback(), true);
93 ASSERT_EQ(len
, cb
.GetResult(rv
));
96 void WriteToEntry(disk_cache::Backend
* cache
, const std::string
& key
,
97 const std::string
& headers
, const std::string
& data
) {
98 net::TestCompletionCallback cb
;
99 disk_cache::Entry
* entry
;
100 int rv
= cache
->CreateEntry(key
, &entry
, cb
.callback());
101 rv
= cb
.GetResult(rv
);
103 rv
= cache
->OpenEntry(key
, &entry
, cb
.callback());
104 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
107 WriteHeaders(entry
, headers
);
108 WriteData(entry
, data
);
112 void FillCache(net::URLRequestContextGetter
* context_getter
) {
113 net::TestCompletionCallback cb
;
114 disk_cache::Backend
* cache
;
116 context_getter
->GetURLRequestContext()->http_transaction_factory()->
117 GetCache()->GetBackend(&cache
, cb
.callback());
118 ASSERT_EQ(net::OK
, cb
.GetResult(rv
));
120 WriteToEntry(cache
, kMalwareURL
, kMalwareHeaders
, kMalwareData
);
121 WriteToEntry(cache
, kLandingURL
, kLandingHeaders
, kLandingData
);
124 // Lets us provide a MockURLRequestContext with an HTTP Cache we pre-populate.
125 // Also exposes the constructor.
126 class MalwareDetailsWrap
: public MalwareDetails
{
129 SafeBrowsingUIManager
* ui_manager
,
130 WebContents
* web_contents
,
131 const SafeBrowsingUIManager::UnsafeResource
& unsafe_resource
,
132 net::URLRequestContextGetter
* request_context_getter
)
133 : MalwareDetails(ui_manager
, web_contents
, unsafe_resource
) {
135 request_context_getter_
= request_context_getter
;
139 virtual ~MalwareDetailsWrap() {}
142 class MockSafeBrowsingUIManager
: public SafeBrowsingUIManager
{
144 base::RunLoop
* run_loop_
;
145 // The safe browsing UI manager does not need a service for this test.
146 MockSafeBrowsingUIManager()
147 : SafeBrowsingUIManager(NULL
), run_loop_(NULL
) {}
149 // When the MalwareDetails is done, this is called.
150 virtual void SendSerializedMalwareDetails(
151 const std::string
& serialized
) OVERRIDE
{
152 DVLOG(1) << "SendSerializedMalwareDetails";
155 serialized_
= serialized
;
158 // Used to synchronize SendSerializedMalwareDetails() with
159 // WaitForSerializedReport(). RunLoop::RunUntilIdle() is not sufficient
160 // because the MessageLoop task queue completely drains at some point
161 // between the send and the wait.
162 void SetRunLoopToQuit(base::RunLoop
* run_loop
) {
163 DCHECK(run_loop_
== NULL
);
164 run_loop_
= run_loop
;
167 const std::string
& GetSerialized() {
172 virtual ~MockSafeBrowsingUIManager() {}
174 std::string serialized_
;
175 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingUIManager
);
180 class MalwareDetailsTest
: public ChromeRenderViewHostTestHarness
{
182 typedef SafeBrowsingUIManager::UnsafeResource UnsafeResource
;
185 : ui_manager_(new MockSafeBrowsingUIManager()) {
188 virtual void SetUp() OVERRIDE
{
189 ChromeRenderViewHostTestHarness::SetUp();
190 ASSERT_TRUE(profile()->CreateHistoryService(
191 true /* delete_file */, false /* no_db */));
194 virtual void TearDown() OVERRIDE
{
195 profile()->DestroyHistoryService();
196 ChromeRenderViewHostTestHarness::TearDown();
199 static bool ResourceLessThan(
200 const ClientMalwareReportRequest::Resource
* lhs
,
201 const ClientMalwareReportRequest::Resource
* rhs
) {
202 return lhs
->id() < rhs
->id();
205 std::string
WaitForSerializedReport(MalwareDetails
* report
) {
206 BrowserThread::PostTask(
209 base::Bind(&MalwareDetails::FinishCollection
, report
));
210 // Wait for the callback (SendSerializedMalwareDetails).
211 DVLOG(1) << "Waiting for SendSerializedMalwareDetails";
212 base::RunLoop run_loop
;
213 ui_manager_
->SetRunLoopToQuit(&run_loop
);
215 return ui_manager_
->GetSerialized();
218 HistoryService
* history_service() {
219 return HistoryServiceFactory::GetForProfile(profile(),
220 Profile::EXPLICIT_ACCESS
);
224 void InitResource(UnsafeResource
* resource
,
228 resource
->is_subresource
= is_subresource
;
229 resource
->threat_type
= SB_THREAT_TYPE_URL_MALWARE
;
230 resource
->render_process_host_id
=
231 web_contents()->GetRenderProcessHost()->GetID();
232 resource
->render_view_id
=
233 web_contents()->GetRenderViewHost()->GetRoutingID();
236 void VerifyResults(const ClientMalwareReportRequest
& report_pb
,
237 const ClientMalwareReportRequest
& expected_pb
) {
238 EXPECT_EQ(expected_pb
.malware_url(), report_pb
.malware_url());
239 EXPECT_EQ(expected_pb
.page_url(), report_pb
.page_url());
240 EXPECT_EQ(expected_pb
.referrer_url(), report_pb
.referrer_url());
242 ASSERT_EQ(expected_pb
.resources_size(), report_pb
.resources_size());
243 // Sort the resources, to make the test deterministic
244 std::vector
<const ClientMalwareReportRequest::Resource
*> resources
;
245 for (int i
= 0; i
< report_pb
.resources_size(); ++i
) {
246 const ClientMalwareReportRequest::Resource
& resource
=
247 report_pb
.resources(i
);
248 resources
.push_back(&resource
);
250 std::sort(resources
.begin(), resources
.end(),
251 &MalwareDetailsTest::ResourceLessThan
);
253 std::vector
<const ClientMalwareReportRequest::Resource
*> expected
;
254 for (int i
= 0; i
< report_pb
.resources_size(); ++i
) {
255 const ClientMalwareReportRequest::Resource
& resource
=
256 expected_pb
.resources(i
);
257 expected
.push_back(&resource
);
259 std::sort(expected
.begin(), expected
.end(),
260 &MalwareDetailsTest::ResourceLessThan
);
262 for (uint32 i
= 0; i
< expected
.size(); ++i
) {
263 VerifyResource(resources
[i
], expected
[i
]);
266 EXPECT_EQ(expected_pb
.complete(), report_pb
.complete());
269 void VerifyResource(const ClientMalwareReportRequest::Resource
* resource
,
270 const ClientMalwareReportRequest::Resource
* expected
) {
271 EXPECT_EQ(expected
->id(), resource
->id());
272 EXPECT_EQ(expected
->url(), resource
->url());
273 EXPECT_EQ(expected
->parent_id(), resource
->parent_id());
274 ASSERT_EQ(expected
->child_ids_size(), resource
->child_ids_size());
275 for (int i
= 0; i
< expected
->child_ids_size(); i
++) {
276 EXPECT_EQ(expected
->child_ids(i
), resource
->child_ids(i
));
279 // Verify HTTP Responses
280 if (expected
->has_response()) {
281 ASSERT_TRUE(resource
->has_response());
282 EXPECT_EQ(expected
->response().firstline().code(),
283 resource
->response().firstline().code());
285 ASSERT_EQ(expected
->response().headers_size(),
286 resource
->response().headers_size());
287 for (int i
= 0; i
< expected
->response().headers_size(); ++i
) {
288 EXPECT_EQ(expected
->response().headers(i
).name(),
289 resource
->response().headers(i
).name());
290 EXPECT_EQ(expected
->response().headers(i
).value(),
291 resource
->response().headers(i
).value());
294 EXPECT_EQ(expected
->response().body(), resource
->response().body());
295 EXPECT_EQ(expected
->response().bodylength(),
296 resource
->response().bodylength());
297 EXPECT_EQ(expected
->response().bodydigest(),
298 resource
->response().bodydigest());
301 // Verify IP:port pair
302 EXPECT_EQ(expected
->response().remote_ip(),
303 resource
->response().remote_ip());
306 // Adds a page to history.
307 // The redirects is the redirect url chain leading to the url.
308 void AddPageToHistory(const GURL
& url
,
309 history::RedirectList
* redirects
) {
310 // The last item of the redirect chain has to be the final url when adding
311 // to history backend.
312 redirects
->push_back(url
);
313 history_service()->AddPage(
314 url
, base::Time::Now(), reinterpret_cast<history::ContextID
>(1), 0,
315 GURL(), *redirects
, content::PAGE_TRANSITION_TYPED
,
316 history::SOURCE_BROWSED
, false);
319 scoped_refptr
<MockSafeBrowsingUIManager
> ui_manager_
;
322 // Tests creating a simple malware report.
323 TEST_F(MalwareDetailsTest
, MalwareSubResource
) {
325 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
326 content::PAGE_TRANSITION_TYPED
, std::string());
328 UnsafeResource resource
;
329 InitResource(&resource
, true, GURL(kMalwareURL
));
331 scoped_refptr
<MalwareDetailsWrap
> report
=
332 new MalwareDetailsWrap(ui_manager_
.get(), web_contents(), resource
, NULL
);
334 std::string serialized
= WaitForSerializedReport(report
.get());
336 ClientMalwareReportRequest actual
;
337 actual
.ParseFromString(serialized
);
339 ClientMalwareReportRequest expected
;
340 expected
.set_malware_url(kMalwareURL
);
341 expected
.set_page_url(kLandingURL
);
342 expected
.set_referrer_url("");
344 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
345 pb_resource
->set_id(0);
346 pb_resource
->set_url(kLandingURL
);
347 pb_resource
= expected
.add_resources();
348 pb_resource
->set_id(1);
349 pb_resource
->set_url(kMalwareURL
);
351 VerifyResults(actual
, expected
);
354 // Tests creating a simple malware report where the subresource has a
355 // different original_url.
356 TEST_F(MalwareDetailsTest
, MalwareSubResourceWithOriginalUrl
) {
357 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
358 content::PAGE_TRANSITION_TYPED
, std::string());
360 UnsafeResource resource
;
361 InitResource(&resource
, true, GURL(kMalwareURL
));
362 resource
.original_url
= GURL(kOriginalLandingURL
);
364 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
365 ui_manager_
.get(), web_contents(), resource
, NULL
);
367 std::string serialized
= WaitForSerializedReport(report
.get());
369 ClientMalwareReportRequest actual
;
370 actual
.ParseFromString(serialized
);
372 ClientMalwareReportRequest expected
;
373 expected
.set_malware_url(kMalwareURL
);
374 expected
.set_page_url(kLandingURL
);
375 expected
.set_referrer_url("");
377 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
378 pb_resource
->set_id(0);
379 pb_resource
->set_url(kLandingURL
);
381 pb_resource
= expected
.add_resources();
382 pb_resource
->set_id(1);
383 pb_resource
->set_url(kOriginalLandingURL
);
385 pb_resource
= expected
.add_resources();
386 pb_resource
->set_id(2);
387 pb_resource
->set_url(kMalwareURL
);
388 // The Resource for kMmalwareUrl should have the Resource for
389 // kOriginalLandingURL (with id 1) as parent.
390 pb_resource
->set_parent_id(1);
392 VerifyResults(actual
, expected
);
395 // Tests creating a malware report with data from the renderer.
396 TEST_F(MalwareDetailsTest
, MalwareDOMDetails
) {
397 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
398 content::PAGE_TRANSITION_TYPED
, std::string());
400 UnsafeResource resource
;
401 InitResource(&resource
, true, GURL(kMalwareURL
));
403 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
404 ui_manager_
.get(), web_contents(), resource
, NULL
);
406 // Send a message from the DOM, with 2 nodes, a parent and a child.
407 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
408 SafeBrowsingHostMsg_MalwareDOMDetails_Node child_node
;
409 child_node
.url
= GURL(kDOMChildURL
);
410 child_node
.tag_name
= "iframe";
411 child_node
.parent
= GURL(kDOMParentURL
);
412 params
.push_back(child_node
);
413 SafeBrowsingHostMsg_MalwareDOMDetails_Node parent_node
;
414 parent_node
.url
= GURL(kDOMParentURL
);
415 parent_node
.children
.push_back(GURL(kDOMChildURL
));
416 params
.push_back(parent_node
);
417 report
->OnReceivedMalwareDOMDetails(params
);
419 std::string serialized
= WaitForSerializedReport(report
.get());
420 ClientMalwareReportRequest actual
;
421 actual
.ParseFromString(serialized
);
423 ClientMalwareReportRequest expected
;
424 expected
.set_malware_url(kMalwareURL
);
425 expected
.set_page_url(kLandingURL
);
426 expected
.set_referrer_url("");
428 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
429 pb_resource
->set_id(0);
430 pb_resource
->set_url(kLandingURL
);
432 pb_resource
= expected
.add_resources();
433 pb_resource
->set_id(1);
434 pb_resource
->set_url(kMalwareURL
);
436 pb_resource
= expected
.add_resources();
437 pb_resource
->set_id(2);
438 pb_resource
->set_url(kDOMChildURL
);
439 pb_resource
->set_parent_id(3);
441 pb_resource
= expected
.add_resources();
442 pb_resource
->set_id(3);
443 pb_resource
->set_url(kDOMParentURL
);
444 pb_resource
->add_child_ids(2);
445 expected
.set_complete(false); // Since the cache was missing.
447 VerifyResults(actual
, expected
);
450 // Verify that https:// urls are dropped.
451 TEST_F(MalwareDetailsTest
, NotPublicUrl
) {
452 controller().LoadURL(GURL(kHttpsURL
), content::Referrer(),
453 content::PAGE_TRANSITION_TYPED
, std::string());
454 UnsafeResource resource
;
455 InitResource(&resource
, true, GURL(kMalwareURL
));
456 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
457 ui_manager_
.get(), web_contents(), resource
, NULL
);
459 std::string serialized
= WaitForSerializedReport(report
.get());
460 ClientMalwareReportRequest actual
;
461 actual
.ParseFromString(serialized
);
463 ClientMalwareReportRequest expected
;
464 expected
.set_malware_url(kMalwareURL
); // No page_url
465 expected
.set_referrer_url("");
467 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
468 pb_resource
->set_url(kMalwareURL
); // Only one resource
470 VerifyResults(actual
, expected
);
473 // Tests creating a malware report where there are redirect urls to an unsafe
475 TEST_F(MalwareDetailsTest
, MalwareWithRedirectUrl
) {
476 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
477 content::PAGE_TRANSITION_TYPED
, std::string());
479 UnsafeResource resource
;
480 InitResource(&resource
, true, GURL(kMalwareURL
));
481 resource
.original_url
= GURL(kOriginalLandingURL
);
483 // add some redirect urls
484 resource
.redirect_urls
.push_back(GURL(kFirstRedirectURL
));
485 resource
.redirect_urls
.push_back(GURL(kSecondRedirectURL
));
486 resource
.redirect_urls
.push_back(GURL(kMalwareURL
));
488 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
489 ui_manager_
.get(), web_contents(), resource
, NULL
);
491 std::string serialized
= WaitForSerializedReport(report
.get());
492 ClientMalwareReportRequest actual
;
493 actual
.ParseFromString(serialized
);
495 ClientMalwareReportRequest expected
;
496 expected
.set_malware_url(kMalwareURL
);
497 expected
.set_page_url(kLandingURL
);
498 expected
.set_referrer_url("");
500 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
501 pb_resource
->set_id(0);
502 pb_resource
->set_url(kLandingURL
);
504 pb_resource
= expected
.add_resources();
505 pb_resource
->set_id(1);
506 pb_resource
->set_url(kOriginalLandingURL
);
508 pb_resource
= expected
.add_resources();
509 pb_resource
->set_id(2);
510 pb_resource
->set_url(kMalwareURL
);
511 pb_resource
->set_parent_id(4);
513 pb_resource
= expected
.add_resources();
514 pb_resource
->set_id(3);
515 pb_resource
->set_url(kFirstRedirectURL
);
516 pb_resource
->set_parent_id(1);
518 pb_resource
= expected
.add_resources();
519 pb_resource
->set_id(4);
520 pb_resource
->set_url(kSecondRedirectURL
);
521 pb_resource
->set_parent_id(3);
523 VerifyResults(actual
, expected
);
526 // Tests the interaction with the HTTP cache.
527 TEST_F(MalwareDetailsTest
, HTTPCache
) {
528 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
529 content::PAGE_TRANSITION_TYPED
, std::string());
531 UnsafeResource resource
;
532 InitResource(&resource
, true, GURL(kMalwareURL
));
534 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
535 ui_manager_
.get(), web_contents(), resource
,
536 profile()->GetRequestContext());
538 BrowserThread::PostTask(
539 BrowserThread::IO
, FROM_HERE
,
540 base::Bind(&FillCache
,
541 make_scoped_refptr(profile()->GetRequestContext())));
543 // The cache collection starts after the IPC from the DOM is fired.
544 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
545 report
->OnReceivedMalwareDOMDetails(params
);
547 // Let the cache callbacks complete.
548 base::RunLoop().RunUntilIdle();
550 DVLOG(1) << "Getting serialized report";
551 std::string serialized
= WaitForSerializedReport(report
.get());
552 ClientMalwareReportRequest actual
;
553 actual
.ParseFromString(serialized
);
555 ClientMalwareReportRequest expected
;
556 expected
.set_malware_url(kMalwareURL
);
557 expected
.set_page_url(kLandingURL
);
558 expected
.set_referrer_url("");
560 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
561 pb_resource
->set_id(0);
562 pb_resource
->set_url(kLandingURL
);
563 safe_browsing::ClientMalwareReportRequest::HTTPResponse
* pb_response
=
564 pb_resource
->mutable_response();
565 pb_response
->mutable_firstline()->set_code(200);
566 safe_browsing::ClientMalwareReportRequest::HTTPHeader
* pb_header
=
567 pb_response
->add_headers();
568 pb_header
->set_name("Content-Type");
569 pb_header
->set_value("text/html");
570 pb_header
= pb_response
->add_headers();
571 pb_header
->set_name("Content-Length");
572 pb_header
->set_value("1024");
573 pb_header
= pb_response
->add_headers();
574 pb_header
->set_name("Set-Cookie");
575 pb_header
->set_value(""); // The cookie is dropped.
576 pb_response
->set_body(kLandingData
);
577 pb_response
->set_bodylength(37);
578 pb_response
->set_bodydigest("9ca97475598a79bc1e8fc9bd6c72cd35");
579 pb_response
->set_remote_ip("1.2.3.4:80");
581 pb_resource
= expected
.add_resources();
582 pb_resource
->set_id(1);
583 pb_resource
->set_url(kMalwareURL
);
584 pb_response
= pb_resource
->mutable_response();
585 pb_response
->mutable_firstline()->set_code(200);
586 pb_header
= pb_response
->add_headers();
587 pb_header
->set_name("Content-Type");
588 pb_header
->set_value("image/jpeg");
589 pb_response
->set_body(kMalwareData
);
590 pb_response
->set_bodylength(10);
591 pb_response
->set_bodydigest("581373551c43d4cf33bfb3b26838ff95");
592 pb_response
->set_remote_ip("1.2.3.4:80");
593 expected
.set_complete(true);
595 VerifyResults(actual
, expected
);
598 // Tests the interaction with the HTTP cache (where the cache is empty).
599 TEST_F(MalwareDetailsTest
, HTTPCacheNoEntries
) {
600 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
601 content::PAGE_TRANSITION_TYPED
, std::string());
603 UnsafeResource resource
;
604 InitResource(&resource
, true, GURL(kMalwareURL
));
606 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
607 ui_manager_
.get(), web_contents(), resource
,
608 profile()->GetRequestContext());
610 // No call to FillCache
612 // The cache collection starts after the IPC from the DOM is fired.
613 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
614 report
->OnReceivedMalwareDOMDetails(params
);
616 // Let the cache callbacks complete.
617 base::RunLoop().RunUntilIdle();
619 DVLOG(1) << "Getting serialized report";
620 std::string serialized
= WaitForSerializedReport(report
.get());
621 ClientMalwareReportRequest actual
;
622 actual
.ParseFromString(serialized
);
624 ClientMalwareReportRequest expected
;
625 expected
.set_malware_url(kMalwareURL
);
626 expected
.set_page_url(kLandingURL
);
627 expected
.set_referrer_url("");
629 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
630 pb_resource
->set_id(0);
631 pb_resource
->set_url(kLandingURL
);
632 pb_resource
= expected
.add_resources();
633 pb_resource
->set_id(1);
634 pb_resource
->set_url(kMalwareURL
);
635 expected
.set_complete(true);
637 VerifyResults(actual
, expected
);
640 // Test getting redirects from history service.
641 TEST_F(MalwareDetailsTest
, HistoryServiceUrls
) {
642 // Add content to history service.
643 // There are two redirect urls before reacing malware url:
644 // kFirstRedirectURL -> kSecondRedirectURL -> kMalwareURL
645 GURL
baseurl(kMalwareURL
);
646 history::RedirectList redirects
;
647 redirects
.push_back(GURL(kFirstRedirectURL
));
648 redirects
.push_back(GURL(kSecondRedirectURL
));
649 AddPageToHistory(baseurl
, &redirects
);
650 // Wait for history service operation finished.
651 profile()->BlockUntilHistoryProcessesPendingRequests();
653 controller().LoadURL(GURL(kLandingURL
), content::Referrer(),
654 content::PAGE_TRANSITION_TYPED
, std::string());
656 UnsafeResource resource
;
657 InitResource(&resource
, true, GURL(kMalwareURL
));
658 scoped_refptr
<MalwareDetailsWrap
> report
= new MalwareDetailsWrap(
659 ui_manager_
.get(), web_contents(), resource
, NULL
);
661 // The redirects collection starts after the IPC from the DOM is fired.
662 std::vector
<SafeBrowsingHostMsg_MalwareDOMDetails_Node
> params
;
663 report
->OnReceivedMalwareDOMDetails(params
);
665 // Let the redirects callbacks complete.
666 base::RunLoop().RunUntilIdle();
668 std::string serialized
= WaitForSerializedReport(report
.get());
669 ClientMalwareReportRequest actual
;
670 actual
.ParseFromString(serialized
);
672 ClientMalwareReportRequest expected
;
673 expected
.set_malware_url(kMalwareURL
);
674 expected
.set_page_url(kLandingURL
);
675 expected
.set_referrer_url("");
677 ClientMalwareReportRequest::Resource
* pb_resource
= expected
.add_resources();
678 pb_resource
->set_id(0);
679 pb_resource
->set_url(kLandingURL
);
680 pb_resource
= expected
.add_resources();
681 pb_resource
->set_id(1);
682 pb_resource
->set_parent_id(2);
683 pb_resource
->set_url(kMalwareURL
);
684 pb_resource
= expected
.add_resources();
685 pb_resource
->set_id(2);
686 pb_resource
->set_parent_id(3);
687 pb_resource
->set_url(kSecondRedirectURL
);
688 pb_resource
= expected
.add_resources();
689 pb_resource
->set_id(3);
690 pb_resource
->set_url(kFirstRedirectURL
);
692 VerifyResults(actual
, expected
);