| OLD | NEW | 
|    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |    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 |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include <algorithm> |    5 #include <algorithm> | 
|    6  |    6  | 
|    7 #include "base/bind.h" |    7 #include "base/bind.h" | 
|    8 #include "base/pickle.h" |    8 #include "base/pickle.h" | 
 |    9 #include "base/run_loop.h" | 
|    9 #include "base/time.h" |   10 #include "base/time.h" | 
|   10 #include "chrome/browser/history/history_backend.h" |   11 #include "chrome/browser/history/history_backend.h" | 
|   11 #include "chrome/browser/history/history_service.h" |   12 #include "chrome/browser/history/history_service.h" | 
|   12 #include "chrome/browser/history/history_service_factory.h" |   13 #include "chrome/browser/history/history_service_factory.h" | 
|   13 #include "chrome/browser/profiles/profile.h" |   14 #include "chrome/browser/profiles/profile.h" | 
|   14 #include "chrome/browser/safe_browsing/malware_details.h" |   15 #include "chrome/browser/safe_browsing/malware_details.h" | 
|   15 #include "chrome/browser/safe_browsing/malware_details_history.h" |   16 #include "chrome/browser/safe_browsing/malware_details_history.h" | 
|   16 #include "chrome/browser/safe_browsing/report.pb.h" |   17 #include "chrome/browser/safe_browsing/report.pb.h" | 
|   17 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |   18 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 
|   18 #include "chrome/browser/safe_browsing/ui_manager.h" |   19 #include "chrome/browser/safe_browsing/ui_manager.h" | 
|   19 #include "chrome/common/render_messages.h" |   20 #include "chrome/common/render_messages.h" | 
|   20 #include "chrome/common/safe_browsing/safebrowsing_messages.h" |   21 #include "chrome/common/safe_browsing/safebrowsing_messages.h" | 
|   21 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |   22 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 
|   22 #include "chrome/test/base/testing_profile.h" |   23 #include "chrome/test/base/testing_profile.h" | 
|   23 #include "content/public/browser/render_process_host.h" |   24 #include "content/public/browser/render_process_host.h" | 
|   24 #include "content/public/browser/web_contents.h" |   25 #include "content/public/browser/web_contents.h" | 
|   25 #include "content/public/test/test_browser_thread.h" |  | 
|   26 #include "net/base/io_buffer.h" |   26 #include "net/base/io_buffer.h" | 
|   27 #include "net/base/net_errors.h" |   27 #include "net/base/net_errors.h" | 
|   28 #include "net/base/test_completion_callback.h" |   28 #include "net/base/test_completion_callback.h" | 
|   29 #include "net/disk_cache/disk_cache.h" |   29 #include "net/disk_cache/disk_cache.h" | 
|   30 #include "net/http/http_cache.h" |   30 #include "net/http/http_cache.h" | 
|   31 #include "net/http/http_response_headers.h" |   31 #include "net/http/http_response_headers.h" | 
|   32 #include "net/http/http_response_info.h" |   32 #include "net/http/http_response_info.h" | 
|   33 #include "net/http/http_util.h" |   33 #include "net/http/http_util.h" | 
|   34 #include "net/url_request/url_request_context.h" |   34 #include "net/url_request/url_request_context.h" | 
|   35 #include "net/url_request/url_request_context_getter.h" |   35 #include "net/url_request/url_request_context_getter.h" | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  115   int rv = |  115   int rv = | 
|  116       context_getter->GetURLRequestContext()->http_transaction_factory()-> |  116       context_getter->GetURLRequestContext()->http_transaction_factory()-> | 
|  117       GetCache()->GetBackend(&cache, cb.callback()); |  117       GetCache()->GetBackend(&cache, cb.callback()); | 
|  118   ASSERT_EQ(net::OK, cb.GetResult(rv)); |  118   ASSERT_EQ(net::OK, cb.GetResult(rv)); | 
|  119  |  119  | 
|  120   std::string empty; |  120   std::string empty; | 
|  121   WriteToEntry(cache, kMalwareURL, kMalwareHeaders, kMalwareData); |  121   WriteToEntry(cache, kMalwareURL, kMalwareHeaders, kMalwareData); | 
|  122   WriteToEntry(cache, kLandingURL, kLandingHeaders, kLandingData); |  122   WriteToEntry(cache, kLandingURL, kLandingHeaders, kLandingData); | 
|  123 } |  123 } | 
|  124  |  124  | 
|  125 void QuitUIMessageLoop() { |  | 
|  126   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |  | 
|  127   BrowserThread::PostTask(BrowserThread::UI, |  | 
|  128                           FROM_HERE, |  | 
|  129                           base::MessageLoop::QuitClosure()); |  | 
|  130 } |  | 
|  131  |  | 
|  132 // Lets us provide a MockURLRequestContext with an HTTP Cache we pre-populate. |  125 // Lets us provide a MockURLRequestContext with an HTTP Cache we pre-populate. | 
|  133 // Also exposes the constructor. |  126 // Also exposes the constructor. | 
|  134 class MalwareDetailsWrap : public MalwareDetails { |  127 class MalwareDetailsWrap : public MalwareDetails { | 
|  135  public: |  128  public: | 
|  136   MalwareDetailsWrap( |  129   MalwareDetailsWrap( | 
|  137       SafeBrowsingUIManager* ui_manager, |  130       SafeBrowsingUIManager* ui_manager, | 
|  138       WebContents* web_contents, |  131       WebContents* web_contents, | 
|  139       const SafeBrowsingUIManager::UnsafeResource& unsafe_resource, |  132       const SafeBrowsingUIManager::UnsafeResource& unsafe_resource, | 
|  140       net::URLRequestContextGetter* request_context_getter) |  133       net::URLRequestContextGetter* request_context_getter) | 
|  141       : MalwareDetails(ui_manager, web_contents, unsafe_resource) { |  134       : MalwareDetails(ui_manager, web_contents, unsafe_resource) { | 
|  142  |  135  | 
|  143     request_context_getter_ = request_context_getter; |  136     request_context_getter_ = request_context_getter; | 
|  144   } |  137   } | 
|  145  |  138  | 
|  146  private: |  139  private: | 
|  147   virtual ~MalwareDetailsWrap() {} |  140   virtual ~MalwareDetailsWrap() {} | 
|  148 }; |  141 }; | 
|  149  |  142  | 
|  150 class MockSafeBrowsingUIManager : public SafeBrowsingUIManager { |  143 class MockSafeBrowsingUIManager : public SafeBrowsingUIManager { | 
|  151  public: |  144  public: | 
 |  145   base::RunLoop* run_loop_; | 
|  152   // The safe browsing UI manager does not need a service for this test. |  146   // The safe browsing UI manager does not need a service for this test. | 
|  153   MockSafeBrowsingUIManager() |  147   MockSafeBrowsingUIManager() | 
|  154       : SafeBrowsingUIManager(NULL) {} |  148       : SafeBrowsingUIManager(NULL), run_loop_(NULL) {} | 
|  155  |  149  | 
|  156   // When the MalwareDetails is done, this is called. |  150   // When the MalwareDetails is done, this is called. | 
|  157   virtual void SendSerializedMalwareDetails( |  151   virtual void SendSerializedMalwareDetails( | 
|  158       const std::string& serialized) OVERRIDE { |  152       const std::string& serialized) OVERRIDE { | 
|  159     DVLOG(1) << "SendSerializedMalwareDetails"; |  153     DVLOG(1) << "SendSerializedMalwareDetails"; | 
|  160     // Notify WaitForSerializedReport. |  154     run_loop_->Quit(); | 
|  161     BrowserThread::PostTask(BrowserThread::IO, |  155     run_loop_ = NULL; | 
|  162                             FROM_HERE, |  | 
|  163                             base::Bind(&QuitUIMessageLoop)); |  | 
|  164     serialized_ = serialized; |  156     serialized_ = serialized; | 
|  165   } |  157   } | 
|  166  |  158  | 
 |  159   // Used to synchronize SendSerializedMalwareDetails() with | 
 |  160   // WaitForSerializedReport(). RunLoop::RunUntilIdle() is not sufficient | 
 |  161   // because the MessageLoop task queue completely drains at some point | 
 |  162   // between the send and the wait. | 
 |  163   void SetRunLoopToQuit(base::RunLoop* run_loop) { | 
 |  164     DCHECK(run_loop_ == NULL); | 
 |  165     run_loop_ = run_loop; | 
 |  166   } | 
 |  167  | 
|  167   const std::string& GetSerialized() { |  168   const std::string& GetSerialized() { | 
|  168     return serialized_; |  169     return serialized_; | 
|  169   } |  170   } | 
|  170  |  171  | 
|  171  private: |  172  private: | 
|  172   virtual ~MockSafeBrowsingUIManager() {} |  173   virtual ~MockSafeBrowsingUIManager() {} | 
|  173  |  174  | 
|  174   std::string serialized_; |  175   std::string serialized_; | 
|  175   DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingUIManager); |  176   DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingUIManager); | 
|  176 }; |  177 }; | 
|  177  |  178  | 
|  178 }  // namespace. |  179 }  // namespace. | 
|  179  |  180  | 
|  180 class MalwareDetailsTest : public ChromeRenderViewHostTestHarness { |  181 class MalwareDetailsTest : public ChromeRenderViewHostTestHarness { | 
|  181  public: |  182  public: | 
|  182   typedef SafeBrowsingUIManager::UnsafeResource UnsafeResource; |  183   typedef SafeBrowsingUIManager::UnsafeResource UnsafeResource; | 
|  183  |  184  | 
|  184   MalwareDetailsTest() |  185   MalwareDetailsTest() | 
|  185       : ui_thread_(BrowserThread::UI, &message_loop_), |  186       : ui_manager_(new MockSafeBrowsingUIManager()) { | 
|  186         io_thread_(BrowserThread::IO), |  | 
|  187         ui_manager_(new MockSafeBrowsingUIManager()) { |  | 
|  188   } |  187   } | 
|  189  |  188  | 
|  190   virtual void SetUp() { |  189   virtual void SetUp() OVERRIDE { | 
|  191     ChromeRenderViewHostTestHarness::SetUp(); |  190     ChromeRenderViewHostTestHarness::SetUp(); | 
|  192     // The URLFetcher checks that the messageloop type is IO. |  | 
|  193     ASSERT_TRUE(io_thread_.StartIOThread()); |  | 
|  194  |  | 
|  195     profile()->CreateHistoryService(true /* delete_file */, false /* no_db */); |  191     profile()->CreateHistoryService(true /* delete_file */, false /* no_db */); | 
|  196   } |  192   } | 
|  197  |  193  | 
|  198   virtual void TearDown() { |  194   virtual void TearDown() OVERRIDE { | 
|  199     profile()->DestroyHistoryService(); |  195     profile()->DestroyHistoryService(); | 
|  200     ChromeRenderViewHostTestHarness::TearDown(); |  196     ChromeRenderViewHostTestHarness::TearDown(); | 
|  201     io_thread_.Stop(); |  | 
|  202   } |  197   } | 
|  203  |  198  | 
|  204   static bool ResourceLessThan( |  199   static bool ResourceLessThan( | 
|  205       const ClientMalwareReportRequest::Resource* lhs, |  200       const ClientMalwareReportRequest::Resource* lhs, | 
|  206       const ClientMalwareReportRequest::Resource* rhs) { |  201       const ClientMalwareReportRequest::Resource* rhs) { | 
|  207     return lhs->id() < rhs->id(); |  202     return lhs->id() < rhs->id(); | 
|  208   } |  203   } | 
|  209  |  204  | 
|  210   std::string WaitForSerializedReport(MalwareDetails* report) { |  205   std::string WaitForSerializedReport(MalwareDetails* report) { | 
|  211     BrowserThread::PostTask( |  206     BrowserThread::PostTask( | 
|  212         BrowserThread::IO, |  207         BrowserThread::IO, | 
|  213         FROM_HERE, |  208         FROM_HERE, | 
|  214         base::Bind(&MalwareDetails::FinishCollection, report)); |  209         base::Bind(&MalwareDetails::FinishCollection, report)); | 
|  215     // Wait for the callback (SendSerializedMalwareDetails). |  210     // Wait for the callback (SendSerializedMalwareDetails). | 
|  216     DVLOG(1) << "Waiting for SendSerializedMalwareDetails"; |  211     DVLOG(1) << "Waiting for SendSerializedMalwareDetails"; | 
|  217     base::MessageLoop::current()->Run(); |  212     base::RunLoop run_loop; | 
 |  213     ui_manager_->SetRunLoopToQuit(&run_loop); | 
 |  214     run_loop.Run(); | 
|  218     return ui_manager_->GetSerialized(); |  215     return ui_manager_->GetSerialized(); | 
|  219   } |  216   } | 
|  220  |  217  | 
|  221   HistoryService* history_service() { |  218   HistoryService* history_service() { | 
|  222     return HistoryServiceFactory::GetForProfile(profile(), |  219     return HistoryServiceFactory::GetForProfile(profile(), | 
|  223                                                 Profile::EXPLICIT_ACCESS); |  220                                                 Profile::EXPLICIT_ACCESS); | 
|  224   } |  221   } | 
|  225  |  222  | 
|  226  protected: |  223  protected: | 
|  227   void InitResource(UnsafeResource* resource, |  224   void InitResource(UnsafeResource* resource, | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  312                         history::RedirectList* redirects) { |  309                         history::RedirectList* redirects) { | 
|  313     // The last item of the redirect chain has to be the final url when adding |  310     // The last item of the redirect chain has to be the final url when adding | 
|  314     // to history backend. |  311     // to history backend. | 
|  315     redirects->push_back(url); |  312     redirects->push_back(url); | 
|  316     history_service()->AddPage( |  313     history_service()->AddPage( | 
|  317         url, base::Time::Now(), static_cast<void*>(this), 0, GURL(), |  314         url, base::Time::Now(), static_cast<void*>(this), 0, GURL(), | 
|  318         *redirects, content::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, |  315         *redirects, content::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, | 
|  319         false); |  316         false); | 
|  320   } |  317   } | 
|  321  |  318  | 
|  322   content::TestBrowserThread ui_thread_; |  | 
|  323   content::TestBrowserThread io_thread_; |  | 
|  324   scoped_refptr<MockSafeBrowsingUIManager> ui_manager_; |  319   scoped_refptr<MockSafeBrowsingUIManager> ui_manager_; | 
|  325 }; |  320 }; | 
|  326  |  321  | 
|  327 // Tests creating a simple malware report. |  322 // Tests creating a simple malware report. | 
|  328 TEST_F(MalwareDetailsTest, MalwareSubResource) { |  323 TEST_F(MalwareDetailsTest, MalwareSubResource) { | 
|  329   // Start a load. |  324   // Start a load. | 
|  330   controller().LoadURL(GURL(kLandingURL), content::Referrer(), |  325   controller().LoadURL(GURL(kLandingURL), content::Referrer(), | 
|  331                        content::PAGE_TRANSITION_TYPED, std::string()); |  326                        content::PAGE_TRANSITION_TYPED, std::string()); | 
|  332  |  327  | 
|  333   UnsafeResource resource; |  328   UnsafeResource resource; | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  414   child_node.url = GURL(kDOMChildURL); |  409   child_node.url = GURL(kDOMChildURL); | 
|  415   child_node.tag_name = "iframe"; |  410   child_node.tag_name = "iframe"; | 
|  416   child_node.parent = GURL(kDOMParentURL); |  411   child_node.parent = GURL(kDOMParentURL); | 
|  417   params.push_back(child_node); |  412   params.push_back(child_node); | 
|  418   SafeBrowsingHostMsg_MalwareDOMDetails_Node parent_node; |  413   SafeBrowsingHostMsg_MalwareDOMDetails_Node parent_node; | 
|  419   parent_node.url = GURL(kDOMParentURL); |  414   parent_node.url = GURL(kDOMParentURL); | 
|  420   parent_node.children.push_back(GURL(kDOMChildURL)); |  415   parent_node.children.push_back(GURL(kDOMChildURL)); | 
|  421   params.push_back(parent_node); |  416   params.push_back(parent_node); | 
|  422   report->OnReceivedMalwareDOMDetails(params); |  417   report->OnReceivedMalwareDOMDetails(params); | 
|  423  |  418  | 
|  424   base::MessageLoop::current()->RunUntilIdle(); |  | 
|  425  |  | 
|  426   std::string serialized = WaitForSerializedReport(report.get()); |  419   std::string serialized = WaitForSerializedReport(report.get()); | 
|  427   ClientMalwareReportRequest actual; |  420   ClientMalwareReportRequest actual; | 
|  428   actual.ParseFromString(serialized); |  421   actual.ParseFromString(serialized); | 
|  429  |  422  | 
|  430   ClientMalwareReportRequest expected; |  423   ClientMalwareReportRequest expected; | 
|  431   expected.set_malware_url(kMalwareURL); |  424   expected.set_malware_url(kMalwareURL); | 
|  432   expected.set_page_url(kLandingURL); |  425   expected.set_page_url(kLandingURL); | 
|  433   expected.set_referrer_url(""); |  426   expected.set_referrer_url(""); | 
|  434  |  427  | 
|  435   ClientMalwareReportRequest::Resource* pb_resource = expected.add_resources(); |  428   ClientMalwareReportRequest::Resource* pb_resource = expected.add_resources(); | 
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  545  |  538  | 
|  546   BrowserThread::PostTask( |  539   BrowserThread::PostTask( | 
|  547       BrowserThread::IO, FROM_HERE, |  540       BrowserThread::IO, FROM_HERE, | 
|  548       base::Bind(&FillCache, |  541       base::Bind(&FillCache, | 
|  549                  make_scoped_refptr(profile()->GetRequestContext()))); |  542                  make_scoped_refptr(profile()->GetRequestContext()))); | 
|  550  |  543  | 
|  551   // The cache collection starts after the IPC from the DOM is fired. |  544   // The cache collection starts after the IPC from the DOM is fired. | 
|  552   std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node> params; |  545   std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node> params; | 
|  553   report->OnReceivedMalwareDOMDetails(params); |  546   report->OnReceivedMalwareDOMDetails(params); | 
|  554  |  547  | 
|  555   // Let the cache callbacks complete |  548   // Let the cache callbacks complete. | 
|  556   base::MessageLoop::current()->RunUntilIdle(); |  549   base::RunLoop().RunUntilIdle(); | 
|  557  |  550  | 
|  558   DVLOG(1) << "Getting serialized report"; |  551   DVLOG(1) << "Getting serialized report"; | 
|  559   std::string serialized = WaitForSerializedReport(report.get()); |  552   std::string serialized = WaitForSerializedReport(report.get()); | 
|  560   ClientMalwareReportRequest actual; |  553   ClientMalwareReportRequest actual; | 
|  561   actual.ParseFromString(serialized); |  554   actual.ParseFromString(serialized); | 
|  562  |  555  | 
|  563   ClientMalwareReportRequest expected; |  556   ClientMalwareReportRequest expected; | 
|  564   expected.set_malware_url(kMalwareURL); |  557   expected.set_malware_url(kMalwareURL); | 
|  565   expected.set_page_url(kLandingURL); |  558   expected.set_page_url(kLandingURL); | 
|  566   expected.set_referrer_url(""); |  559   expected.set_referrer_url(""); | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  616   scoped_refptr<MalwareDetailsWrap> report = new MalwareDetailsWrap( |  609   scoped_refptr<MalwareDetailsWrap> report = new MalwareDetailsWrap( | 
|  617       ui_manager_.get(), web_contents(), resource, |  610       ui_manager_.get(), web_contents(), resource, | 
|  618       profile()->GetRequestContext()); |  611       profile()->GetRequestContext()); | 
|  619  |  612  | 
|  620   // No call to FillCache |  613   // No call to FillCache | 
|  621  |  614  | 
|  622   // The cache collection starts after the IPC from the DOM is fired. |  615   // The cache collection starts after the IPC from the DOM is fired. | 
|  623   std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node> params; |  616   std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node> params; | 
|  624   report->OnReceivedMalwareDOMDetails(params); |  617   report->OnReceivedMalwareDOMDetails(params); | 
|  625  |  618  | 
|  626   // Let the cache callbacks complete |  619   // Let the cache callbacks complete. | 
|  627   base::MessageLoop::current()->RunUntilIdle(); |  620   base::RunLoop().RunUntilIdle(); | 
|  628  |  621  | 
|  629   DVLOG(1) << "Getting serialized report"; |  622   DVLOG(1) << "Getting serialized report"; | 
|  630   std::string serialized = WaitForSerializedReport(report.get()); |  623   std::string serialized = WaitForSerializedReport(report.get()); | 
|  631   ClientMalwareReportRequest actual; |  624   ClientMalwareReportRequest actual; | 
|  632   actual.ParseFromString(serialized); |  625   actual.ParseFromString(serialized); | 
|  633  |  626  | 
|  634   ClientMalwareReportRequest expected; |  627   ClientMalwareReportRequest expected; | 
|  635   expected.set_malware_url(kMalwareURL); |  628   expected.set_malware_url(kMalwareURL); | 
|  636   expected.set_page_url(kLandingURL); |  629   expected.set_page_url(kLandingURL); | 
|  637   expected.set_referrer_url(""); |  630   expected.set_referrer_url(""); | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|  666   UnsafeResource resource; |  659   UnsafeResource resource; | 
|  667   InitResource(&resource, true, GURL(kMalwareURL)); |  660   InitResource(&resource, true, GURL(kMalwareURL)); | 
|  668   scoped_refptr<MalwareDetailsWrap> report = new MalwareDetailsWrap( |  661   scoped_refptr<MalwareDetailsWrap> report = new MalwareDetailsWrap( | 
|  669       ui_manager_.get(), web_contents(), resource, NULL); |  662       ui_manager_.get(), web_contents(), resource, NULL); | 
|  670  |  663  | 
|  671   // The redirects collection starts after the IPC from the DOM is fired. |  664   // The redirects collection starts after the IPC from the DOM is fired. | 
|  672   std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node> params; |  665   std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node> params; | 
|  673   report->OnReceivedMalwareDOMDetails(params); |  666   report->OnReceivedMalwareDOMDetails(params); | 
|  674  |  667  | 
|  675   // Let the redirects callbacks complete. |  668   // Let the redirects callbacks complete. | 
|  676   base::MessageLoop::current()->RunUntilIdle(); |  669   base::RunLoop().RunUntilIdle(); | 
|  677  |  670  | 
|  678   std::string serialized = WaitForSerializedReport(report.get()); |  671   std::string serialized = WaitForSerializedReport(report.get()); | 
|  679   ClientMalwareReportRequest actual; |  672   ClientMalwareReportRequest actual; | 
|  680   actual.ParseFromString(serialized); |  673   actual.ParseFromString(serialized); | 
|  681  |  674  | 
|  682   ClientMalwareReportRequest expected; |  675   ClientMalwareReportRequest expected; | 
|  683   expected.set_malware_url(kMalwareURL); |  676   expected.set_malware_url(kMalwareURL); | 
|  684   expected.set_page_url(kLandingURL); |  677   expected.set_page_url(kLandingURL); | 
|  685   expected.set_referrer_url(""); |  678   expected.set_referrer_url(""); | 
|  686  |  679  | 
|  687   ClientMalwareReportRequest::Resource* pb_resource = expected.add_resources(); |  680   ClientMalwareReportRequest::Resource* pb_resource = expected.add_resources(); | 
|  688   pb_resource->set_id(0); |  681   pb_resource->set_id(0); | 
|  689   pb_resource->set_url(kLandingURL); |  682   pb_resource->set_url(kLandingURL); | 
|  690   pb_resource = expected.add_resources(); |  683   pb_resource = expected.add_resources(); | 
|  691   pb_resource->set_id(1); |  684   pb_resource->set_id(1); | 
|  692   pb_resource->set_parent_id(2); |  685   pb_resource->set_parent_id(2); | 
|  693   pb_resource->set_url(kMalwareURL); |  686   pb_resource->set_url(kMalwareURL); | 
|  694   pb_resource = expected.add_resources(); |  687   pb_resource = expected.add_resources(); | 
|  695   pb_resource->set_id(2); |  688   pb_resource->set_id(2); | 
|  696   pb_resource->set_parent_id(3); |  689   pb_resource->set_parent_id(3); | 
|  697   pb_resource->set_url(kSecondRedirectURL); |  690   pb_resource->set_url(kSecondRedirectURL); | 
|  698   pb_resource = expected.add_resources(); |  691   pb_resource = expected.add_resources(); | 
|  699   pb_resource->set_id(3); |  692   pb_resource->set_id(3); | 
|  700   pb_resource->set_url(kFirstRedirectURL); |  693   pb_resource->set_url(kFirstRedirectURL); | 
|  701  |  694  | 
|  702   VerifyResults(actual, expected); |  695   VerifyResults(actual, expected); | 
|  703 } |  696 } | 
| OLD | NEW |