Chromium Code Reviews| Index: components/data_reduction_proxy/content/browser/data_reduction_proxy_debug_blocking_page_unittest.cc |
| diff --git a/components/data_reduction_proxy/content/browser/data_reduction_proxy_debug_blocking_page_unittest.cc b/components/data_reduction_proxy/content/browser/data_reduction_proxy_debug_blocking_page_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8be7d86afe2fbeb3f3d547044cdc2beb18e5fa28 |
| --- /dev/null |
| +++ b/components/data_reduction_proxy/content/browser/data_reduction_proxy_debug_blocking_page_unittest.cc |
| @@ -0,0 +1,443 @@ |
| +// Copyright 2015 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/data_reduction_proxy/content/browser/data_reduction_proxy_debug_blocking_page.h" |
| + |
| +#include <string> |
| + |
| +#include "base/files/file_path.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/message_loop/message_loop_proxy.h" |
| +#include "base/path_service.h" |
| +#include "base/run_loop.h" |
| +#include "base/single_thread_task_runner.h" |
| +#include "components/data_reduction_proxy/content/browser/data_reduction_proxy_debug_ui_manager.h" |
| +#include "content/public/browser/interstitial_page.h" |
| +#include "content/public/browser/navigation_entry.h" |
| +#include "content/public/browser/render_frame_host.h" |
| +#include "content/public/browser/render_process_host.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "content/public/test/test_renderer_host.h" |
| +#include "content/public/test/web_contents_tester.h" |
| +#include "ui/base/layout.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| +#include "ui/base/ui_base_paths.h" |
| + |
| +static const char* kBypassURL = "http://www.bypass.com/"; |
| +static const char* kBypassURL2 = "http://www.bypass2.com/"; |
| +static const char* kBypassURL3 = "http://www.bypass3.com/"; |
| +static const char* kGoogleURL = "http://www.google.com/"; |
| +static const char* kOtherURL = "http://www.other.com/"; |
| + |
| +namespace data_reduction_proxy { |
| + |
| +// A DataReductionProxyDebugBlockingPage class that does not create windows. |
| +class TestDataReductionProxyDebugBlockingPage |
| + : public DataReductionProxyDebugBlockingPage { |
| + public: |
| + TestDataReductionProxyDebugBlockingPage( |
| + DataReductionProxyDebugUIManager* ui_manager, |
| + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, |
| + content::WebContents* web_contents, |
| + const BypassResourceList& bypass_resources, |
| + const std::string& app_locale) |
| + : DataReductionProxyDebugBlockingPage( |
| + ui_manager, io_task_runner, web_contents, |
| + bypass_resources, app_locale) { |
| + DontCreateViewForTesting(); |
| + } |
| +}; |
| + |
| +class TestDataReductionProxyDebugBlockingPageFactory |
| + : public DataReductionProxyDebugBlockingPageFactory { |
| + public: |
| + TestDataReductionProxyDebugBlockingPageFactory() { |
| + } |
| + |
| + ~TestDataReductionProxyDebugBlockingPageFactory() override { |
| + } |
| + |
| + DataReductionProxyDebugBlockingPage* CreateDataReductionProxyPage( |
| + DataReductionProxyDebugUIManager* ui_manager, |
| + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, |
| + content::WebContents* web_contents, |
| + const DataReductionProxyDebugBlockingPage::BypassResourceList& |
| + resource_list, |
| + const std::string& app_locale) override { |
| + return new TestDataReductionProxyDebugBlockingPage( |
| + ui_manager, io_task_runner, web_contents, resource_list, app_locale); |
| + } |
| +}; |
| + |
| +class DataReductionProxyDebugBlockingPageTest |
| + : public content::RenderViewHostTestHarness { |
| + public: |
| + // The decision the user made. |
| + enum UserResponse { |
| + PENDING, |
| + OK, |
| + CANCEL |
| + }; |
| + |
| + DataReductionProxyDebugBlockingPageTest() : user_response_(PENDING) { |
| + } |
| + |
| + void SetUp() override { |
| + base::FilePath resources_pack_path; |
| + PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &resources_pack_path); |
| + ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath( |
| + resources_pack_path.AppendASCII("resources.pak"), |
| + ui::SCALE_FACTOR_NONE); |
| + |
| + content::RenderViewHostTestHarness::SetUp(); |
| + DataReductionProxyDebugBlockingPage::RegisterFactory(&factory_); |
| + ui_manager_ = new DataReductionProxyDebugUIManager( |
| + base::MessageLoopProxy::current(), |
| + base::MessageLoopProxy::current(), |
| + std::string()); |
| + ResetUserResponse(); |
| + } |
| + |
| + void TearDown() override { |
| + // Release the UI manager before the BrowserThreads are destroyed. |
| + ui_manager_ = NULL; |
| + DataReductionProxyDebugBlockingPage::RegisterFactory(NULL); |
| + content::RenderViewHostTestHarness::TearDown(); |
| + } |
| + |
| + void OnBlockingPageComplete(bool proceed) { |
| + if (proceed) |
| + user_response_ = OK; |
| + else |
| + user_response_ = CANCEL; |
| + } |
| + |
| + void Navigate(const char* url, int page_id) { |
| + content::WebContentsTester::For(web_contents())->TestDidNavigate( |
| + web_contents()->GetMainFrame(), page_id, GURL(url), |
| + ui::PAGE_TRANSITION_TYPED); |
| + } |
| + |
| + void GoBack(bool is_cross_site) { |
| + content::NavigationEntry* entry = |
| + web_contents()->GetController().GetEntryAtOffset(-1); |
| + ASSERT_TRUE(entry); |
| + web_contents()->GetController().GoBack(); |
| + |
| + // The pending RVH should commit for cross-site navigations. |
| + content::RenderFrameHost* rfh = is_cross_site ? |
|
bengr
2015/02/05 01:30:09
render_frame_host, not rfh
megjablon
2015/02/13 01:48:08
Done.
|
| + content::WebContentsTester::For( |
| + web_contents())->GetPendingMainFrame() : |
| + web_contents()->GetMainFrame(); |
| + content::WebContentsTester::For(web_contents())->TestDidNavigate( |
| + rfh, |
| + entry->GetPageID(), |
| + GURL(entry->GetURL()), |
| + ui::PAGE_TRANSITION_TYPED); |
| + } |
| + |
| + void ShowInterstitial(bool is_subresource, const char* url) { |
| + DataReductionProxyDebugUIManager::BypassResource resource; |
| + InitResource(&resource, is_subresource, GURL(url)); |
| + DataReductionProxyDebugBlockingPage::ShowBlockingPage( |
| + ui_manager_.get(), base::MessageLoopProxy::current(), |
| + resource, std::string()); |
| + } |
| + |
| + // Returns the DataReductionProxyDebugBlockingPage currently showing or NULL |
| + // if none is showing. |
| + DataReductionProxyDebugBlockingPage* |
| + GetDataReductionProxyDebugBlockingPage() { |
| + content::InterstitialPage* interstitial = |
| + content::InterstitialPage::GetInterstitialPage(web_contents()); |
| + if (!interstitial) |
| + return NULL; |
| + return static_cast<DataReductionProxyDebugBlockingPage*>( |
| + interstitial->GetDelegateForTesting()); |
| + } |
| + |
| + UserResponse user_response() const { |
| + return user_response_; |
| + } |
| + |
| + void ResetUserResponse() { |
| + user_response_ = PENDING; |
| + } |
| + |
| + static void ProceedThroughInterstitial( |
| + DataReductionProxyDebugBlockingPage* interstitial) { |
| + interstitial->interstitial_page()->Proceed(); |
| + base::RunLoop().RunUntilIdle(); |
| + } |
| + |
| + static void DontProceedThroughInterstitial( |
| + DataReductionProxyDebugBlockingPage* interstitial) { |
| + interstitial->interstitial_page()->DontProceed(); |
| + base::RunLoop().RunUntilIdle(); |
| + } |
| + |
| + void DontProceedThroughSubresourceInterstitial( |
| + DataReductionProxyDebugBlockingPage* sb_interstitial) { |
| + // CommandReceived(kTakeMeBackCommand) does a back navigation for |
| + // subresource interstitials. |
| + GoBack(false); |
| + base::RunLoop().RunUntilIdle(); |
| + } |
| + |
| + private: |
| + void InitResource(DataReductionProxyDebugUIManager::BypassResource* resource, |
| + bool is_subresource, |
| + const GURL& url) { |
| + resource->callback = |
| + base::Bind(&DataReductionProxyDebugBlockingPageTest:: |
| + OnBlockingPageComplete, |
| + base::Unretained(this)); |
| + resource->url = url; |
| + resource->is_subresource = is_subresource; |
| + resource->render_process_host_id = |
| + web_contents()->GetRenderProcessHost()->GetID(); |
| + resource->render_view_id = |
| + web_contents()->GetRenderViewHost()->GetRoutingID(); |
| + } |
| + |
| + scoped_refptr<DataReductionProxyDebugUIManager> ui_manager_; |
| + UserResponse user_response_; |
| + TestDataReductionProxyDebugBlockingPageFactory factory_; |
| +}; |
| + |
| +// Tests showing a blocking page for a bypassed request and not proceeding. |
| +TEST_F(DataReductionProxyDebugBlockingPageTest, BypassPageDontProceed) { |
| + // Start a load. |
| + controller().LoadURL(GURL(kBypassURL), content::Referrer(), |
| + ui::PAGE_TRANSITION_TYPED, std::string()); |
| + |
| + // Simulate the load causing an interstitial to be shown. |
| + ShowInterstitial(false, kBypassURL); |
| + DataReductionProxyDebugBlockingPage* interstitial = |
| + GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_TRUE(interstitial); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // Simulate the user clicking "don't proceed". |
| + DontProceedThroughInterstitial(interstitial); |
| + |
| + // The interstitial should be gone. |
| + EXPECT_EQ(CANCEL, user_response()); |
| + EXPECT_FALSE(GetDataReductionProxyDebugBlockingPage()); |
| + |
| + // The user did not proceed, the pending entry should be gone. |
| + EXPECT_FALSE(controller().GetPendingEntry()); |
| +} |
| + |
| +// Tests showing a blocking page for a bypassed request and proceeding. |
| +TEST_F(DataReductionProxyDebugBlockingPageTest, BypassPageProceed) { |
| + // Start a load. |
| + controller().LoadURL(GURL(kBypassURL), content::Referrer(), |
| + ui::PAGE_TRANSITION_TYPED, std::string()); |
| + |
| + // Simulate the load causing an interstitial to be shown. |
| + ShowInterstitial(false, kBypassURL); |
| + DataReductionProxyDebugBlockingPage* interstitial = |
| + GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_TRUE(interstitial); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // Simulate the user clicking "proceed". |
| + ProceedThroughInterstitial(interstitial); |
| + |
| + // The interstitial is shown until the navigation commits. |
| + ASSERT_TRUE(GetDataReductionProxyDebugBlockingPage()); |
| + // Commit the navigation. |
| + Navigate(kBypassURL, 1); |
| + // The interstitial should be gone now. |
| + EXPECT_EQ(OK, user_response()); |
| + ASSERT_FALSE(GetDataReductionProxyDebugBlockingPage()); |
| +} |
| + |
| +// Tests showing a blocking page for a page that contains bypassed subresources |
| +// and not proceeding. |
| +TEST_F(DataReductionProxyDebugBlockingPageTest, BypassSubresourceDontProceed) { |
| + // Navigate somewhere. |
| + Navigate(kGoogleURL, 1); |
| + |
| + // Navigate somewhere else. |
| + Navigate(kOtherURL, 2); |
| + |
| + // Simulate that page loading a bypass-resource triggering an interstitial. |
| + ShowInterstitial(true, kBypassURL); |
| + |
| + DataReductionProxyDebugBlockingPage* interstitial = |
| + GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_TRUE(interstitial); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // Simulate the user clicking "don't proceed". |
| + DontProceedThroughSubresourceInterstitial(interstitial); |
| + EXPECT_EQ(CANCEL, user_response()); |
| + EXPECT_FALSE(GetDataReductionProxyDebugBlockingPage()); |
| + |
| + // The user did not proceed, the controler should be back to the first page, |
| + // the 2nd one should have been removed from the navigation controller. |
| + ASSERT_EQ(1, controller().GetEntryCount()); |
| + EXPECT_EQ(kGoogleURL, controller().GetActiveEntry()->GetURL().spec()); |
| +} |
| + |
| +// Tests showing a blocking page for a page that contains bypassed subresources |
| +// and proceeding. |
| +TEST_F(DataReductionProxyDebugBlockingPageTest, BypassSubresourceProceed) { |
| + // Navigate somewhere. |
| + Navigate(kGoogleURL, 1); |
| + |
| + // Simulate that page loading a bypass-resource triggering an interstitial. |
| + ShowInterstitial(true, kBypassURL); |
| + |
| + DataReductionProxyDebugBlockingPage* interstitial = |
| + GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_TRUE(interstitial); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // Simulate the user clicking "proceed". |
| + ProceedThroughInterstitial(interstitial); |
| + EXPECT_EQ(OK, user_response()); |
| + EXPECT_FALSE(GetDataReductionProxyDebugBlockingPage()); |
| + |
| + // The user did proceed, the controller should be back to showing the page. |
| + ASSERT_EQ(1, controller().GetEntryCount()); |
| + EXPECT_EQ(kGoogleURL, controller().GetActiveEntry()->GetURL().spec()); |
| +} |
| + |
| +// Tests showing a blocking page for a page that contains multiple bypassed |
| +// subresources and not proceeding. This just tests that the extra bypassed |
| +// subresources (which trigger queued interstitial pages) do not break anything. |
| +TEST_F(DataReductionProxyDebugBlockingPageTest, |
| + BypassMultipleSubresourcesDontProceed) { |
| + // Navigate somewhere. |
| + Navigate(kGoogleURL, 1); |
| + |
| + // Navigate somewhere else. |
| + Navigate(kOtherURL, 2); |
| + |
| + // Simulate that page loading a bypass-resource triggering an interstitial. |
| + ShowInterstitial(true, kBypassURL); |
| + |
| + // More bypassedd resources loading causing more interstitials. The new |
| + // interstitials should be queued. |
| + ShowInterstitial(true, kBypassURL2); |
| + ShowInterstitial(true, kBypassURL3); |
| + |
| + DataReductionProxyDebugBlockingPage* interstitial = |
| + GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_TRUE(interstitial); |
| + |
| + // Simulate the user clicking "don't proceed". |
| + DontProceedThroughSubresourceInterstitial(interstitial); |
| + EXPECT_EQ(CANCEL, user_response()); |
| + EXPECT_FALSE(GetDataReductionProxyDebugBlockingPage()); |
| + |
| + // The user did not proceed, the controler should be back to the first page, |
| + // the 2nd one should have been removed from the navigation controller. |
| + ASSERT_EQ(1, controller().GetEntryCount()); |
| + EXPECT_EQ(kGoogleURL, controller().GetActiveEntry()->GetURL().spec()); |
| +} |
| + |
| +// Tests showing a blocking page for a page that contains multiple bypassed |
| +// subresources. Proceeding through the first interstitial should proceed |
| +// through all interstitials. |
| +TEST_F(DataReductionProxyDebugBlockingPageTest, |
| + BypassMultipleSubresourcesProceed) { |
| + // Navigate somewhere. |
| + Navigate(kGoogleURL, 1); |
| + |
| + // Simulate that page loading a bypass-resource triggering an interstitial. |
| + ShowInterstitial(true, kBypassURL); |
| + |
| + // More bypassed resources loading causing more interstitials. The new |
| + // interstitials should be queued. |
| + ShowInterstitial(true, kBypassURL2); |
| + ShowInterstitial(true, kBypassURL3); |
| + |
| + DataReductionProxyDebugBlockingPage* interstitial = |
| + GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_TRUE(interstitial); |
| + |
| + // Proceed through the 1st interstitial. |
| + ProceedThroughInterstitial(interstitial); |
| + EXPECT_EQ(OK, user_response()); |
| + |
| + // The user did proceed, the controller should be back to showing the page. |
| + ASSERT_EQ(1, controller().GetEntryCount()); |
| + EXPECT_EQ(kGoogleURL, controller().GetActiveEntry()->GetURL().spec()); |
| +} |
| + |
| +// Tests showing a blocking page then navigating back and forth to make sure the |
| +// controller entries are OK. |
| +TEST_F(DataReductionProxyDebugBlockingPageTest, NavigatingBackAndForth) { |
| + // Navigate somewhere. |
| + Navigate(kGoogleURL, 1); |
| + |
| + // Now navigate to a bypassed page triggerring an interstitial. |
| + controller().LoadURL(GURL(kBypassURL), content::Referrer(), |
| + ui::PAGE_TRANSITION_TYPED, std::string()); |
| + ShowInterstitial(false, kBypassURL); |
| + DataReductionProxyDebugBlockingPage* interstitial = |
| + GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_TRUE(interstitial); |
| + |
| + // Proceed through the 1st interstitial. |
| + ProceedThroughInterstitial(interstitial); |
| + Navigate(kBypassURL, 2); // Commit the navigation. |
| + GoBack(true); |
| + |
| + // We are back on the first page. |
| + interstitial = GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_FALSE(interstitial); |
| + ASSERT_EQ(2, controller().GetEntryCount()); |
| + EXPECT_EQ(kGoogleURL, controller().GetActiveEntry()->GetURL().spec()); |
| + |
| + // Navigate forward to the bypassed URL. |
| + web_contents()->GetController().GoForward(); |
| + ShowInterstitial(false, kBypassURL); |
| + interstitial = GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_TRUE(interstitial); |
| + |
| + // Let's proceed and make sure everything is OK. |
| + ProceedThroughInterstitial(interstitial); |
| + Navigate(kBypassURL, 2); // Commit the navigation. |
| + interstitial = GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_FALSE(interstitial); |
| + ASSERT_EQ(2, controller().GetEntryCount()); |
| + EXPECT_EQ(kBypassURL, controller().GetActiveEntry()->GetURL().spec()); |
| +} |
| + |
| +// Tests that calling "don't proceed" after "proceed" has been called doesn't |
| +// cause problems. |
|
bengr
2015/02/05 01:30:09
What kinds of problems?
megjablon
2015/02/13 01:48:08
Done.
|
| +TEST_F(DataReductionProxyDebugBlockingPageTest, ProceedThenDontProceed) { |
| + // Start a load. |
| + controller().LoadURL(GURL(kBypassURL), content::Referrer(), |
| + ui::PAGE_TRANSITION_TYPED, std::string()); |
| + |
| + // Simulate the load causing an interstitial to be shown. |
| + ShowInterstitial(false, kBypassURL); |
|
bengr
2015/02/05 01:30:09
These tests don't test that the (actual or simulat
megjablon
2015/02/13 01:48:08
Done.
|
| + DataReductionProxyDebugBlockingPage* interstitial = |
| + GetDataReductionProxyDebugBlockingPage(); |
| + ASSERT_TRUE(interstitial); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // Simulate the user clicking "proceed" then "don't proceed" (before the |
| + // interstitial is shown). |
| + interstitial->interstitial_page()->Proceed(); |
| + interstitial->interstitial_page()->DontProceed(); |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // The interstitial should be gone. |
| + EXPECT_EQ(OK, user_response()); |
| + EXPECT_FALSE(GetDataReductionProxyDebugBlockingPage()); |
| +} |
| + |
| +} // namespace data_reduction_proxy |