| Index: components/data_reduction_proxy/content/browser/data_reduction_proxy_blocking_page_unittest.cc
|
| diff --git a/components/data_reduction_proxy/content/browser/data_reduction_proxy_blocking_page_unittest.cc b/components/data_reduction_proxy/content/browser/data_reduction_proxy_blocking_page_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..98850edece2b960053bd67d699d03cb1139b79f7
|
| --- /dev/null
|
| +++ b/components/data_reduction_proxy/content/browser/data_reduction_proxy_blocking_page_unittest.cc
|
| @@ -0,0 +1,422 @@
|
| +// 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_blocking_page.h"
|
| +
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/message_loop/message_loop_proxy.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/single_thread_task_runner.h"
|
| +#include "components/data_reduction_proxy/content/browser/data_reduction_proxy_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"
|
| +
|
| +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 DataReductionProxyBlockingPage class that does not create windows.
|
| +class TestDataReductionProxyBlockingPage
|
| + : public DataReductionProxyBlockingPage {
|
| + public:
|
| + TestDataReductionProxyBlockingPage(
|
| + DataReductionProxyUIManager* ui_manager,
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
|
| + content::WebContents* web_contents,
|
| + const BypassResourceList& bypass_resources)
|
| + : DataReductionProxyBlockingPage(ui_manager, io_task_runner, web_contents,
|
| + bypass_resources) {
|
| + DontCreateViewForTesting();
|
| + }
|
| +};
|
| +
|
| +class TestDataReductionProxyBlockingPageFactory
|
| + : public DataReductionProxyBlockingPageFactory {
|
| + public:
|
| + TestDataReductionProxyBlockingPageFactory() {
|
| + }
|
| +
|
| + ~TestDataReductionProxyBlockingPageFactory() override {
|
| + }
|
| +
|
| + DataReductionProxyBlockingPage* CreateDataReductionProxyPage(
|
| + DataReductionProxyUIManager* ui_manager,
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
|
| + content::WebContents* web_contents,
|
| + const DataReductionProxyBlockingPage::BypassResourceList&
|
| + resource_list) override {
|
| + return new TestDataReductionProxyBlockingPage(
|
| + ui_manager, io_task_runner, web_contents, resource_list);
|
| + }
|
| +};
|
| +
|
| +class DataReductionProxyBlockingPageTest
|
| + : public content::RenderViewHostTestHarness {
|
| + public:
|
| + // The decision the user made.
|
| + enum UserResponse {
|
| + PENDING,
|
| + OK,
|
| + CANCEL
|
| + };
|
| +
|
| + DataReductionProxyBlockingPageTest() : user_response_(PENDING) {
|
| + }
|
| +
|
| + void SetUp() override {
|
| + content::RenderViewHostTestHarness::SetUp();
|
| + DataReductionProxyBlockingPage::RegisterFactory(&factory_);
|
| + ui_manager_ = new DataReductionProxyUIManager(
|
| + base::MessageLoopProxy::current(),
|
| + base::MessageLoopProxy::current());
|
| + ResetUserResponse();
|
| + }
|
| +
|
| + void TearDown() override {
|
| + // Release the UI manager before the BrowserThreads are destroyed.
|
| + ui_manager_ = NULL;
|
| + DataReductionProxyBlockingPage::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 ?
|
| + 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) {
|
| + DataReductionProxyUIManager::BypassResource resource;
|
| + InitResource(&resource, is_subresource, GURL(url));
|
| + DataReductionProxyBlockingPage::ShowBlockingPage(
|
| + ui_manager_.get(), base::MessageLoopProxy::current(), resource);
|
| + }
|
| +
|
| + // Returns the DataReductionProxyBlockingPage currently showing or NULL if
|
| + // none is showing.
|
| + DataReductionProxyBlockingPage* GetDataReductionProxyBlockingPage() {
|
| + content::InterstitialPage* interstitial =
|
| + content::InterstitialPage::GetInterstitialPage(web_contents());
|
| + if (!interstitial)
|
| + return NULL;
|
| + return static_cast<DataReductionProxyBlockingPage*>(
|
| + interstitial->GetDelegateForTesting());
|
| + }
|
| +
|
| + UserResponse user_response() const {
|
| + return user_response_;
|
| + }
|
| +
|
| + void ResetUserResponse() {
|
| + user_response_ = PENDING;
|
| + }
|
| +
|
| + static void ProceedThroughInterstitial(
|
| + DataReductionProxyBlockingPage* interstitial) {
|
| + interstitial->interstitial_page()->Proceed();
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| + static void DontProceedThroughInterstitial(
|
| + DataReductionProxyBlockingPage* interstitial) {
|
| + interstitial->interstitial_page()->DontProceed();
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| + void DontProceedThroughSubresourceInterstitial(
|
| + DataReductionProxyBlockingPage* sb_interstitial) {
|
| + // CommandReceived(kTakeMeBackCommand) does a back navigation for
|
| + // subresource interstitials.
|
| + GoBack(false);
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| + private:
|
| + void InitResource(DataReductionProxyUIManager::BypassResource* resource,
|
| + bool is_subresource,
|
| + const GURL& url) {
|
| + resource->callback =
|
| + base::Bind(&DataReductionProxyBlockingPageTest::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<DataReductionProxyUIManager> ui_manager_;
|
| + UserResponse user_response_;
|
| + TestDataReductionProxyBlockingPageFactory factory_;
|
| +};
|
| +
|
| +// Tests showing a blocking page for a bypassed request and not proceeding.
|
| +TEST_F(DataReductionProxyBlockingPageTest, 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);
|
| + DataReductionProxyBlockingPage* interstitial =
|
| + GetDataReductionProxyBlockingPage();
|
| + 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(GetDataReductionProxyBlockingPage());
|
| +
|
| + // 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(DataReductionProxyBlockingPageTest, 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);
|
| + DataReductionProxyBlockingPage* interstitial =
|
| + GetDataReductionProxyBlockingPage();
|
| + ASSERT_TRUE(interstitial);
|
| +
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // Simulate the user clicking "proceed".
|
| + ProceedThroughInterstitial(interstitial);
|
| +
|
| + // The interstitial is shown until the navigation commits.
|
| + ASSERT_TRUE(GetDataReductionProxyBlockingPage());
|
| + // Commit the navigation.
|
| + Navigate(kBypassURL, 1);
|
| + // The interstitial should be gone now.
|
| + EXPECT_EQ(OK, user_response());
|
| + ASSERT_FALSE(GetDataReductionProxyBlockingPage());
|
| +}
|
| +
|
| +// Tests showing a blocking page for a page that contains bypassed subresources
|
| +// and not proceeding.
|
| +TEST_F(DataReductionProxyBlockingPageTest, 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);
|
| +
|
| + DataReductionProxyBlockingPage* interstitial =
|
| + GetDataReductionProxyBlockingPage();
|
| + ASSERT_TRUE(interstitial);
|
| +
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // Simulate the user clicking "don't proceed".
|
| + DontProceedThroughSubresourceInterstitial(interstitial);
|
| + EXPECT_EQ(CANCEL, user_response());
|
| + EXPECT_FALSE(GetDataReductionProxyBlockingPage());
|
| +
|
| + // 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(DataReductionProxyBlockingPageTest, BypassSubresourceProceed) {
|
| + // Navigate somewhere.
|
| + Navigate(kGoogleURL, 1);
|
| +
|
| + // Simulate that page loading a bypass-resource triggering an interstitial.
|
| + ShowInterstitial(true, kBypassURL);
|
| +
|
| + DataReductionProxyBlockingPage* interstitial =
|
| + GetDataReductionProxyBlockingPage();
|
| + ASSERT_TRUE(interstitial);
|
| +
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // Simulate the user clicking "proceed".
|
| + ProceedThroughInterstitial(interstitial);
|
| + EXPECT_EQ(OK, user_response());
|
| + EXPECT_FALSE(GetDataReductionProxyBlockingPage());
|
| +
|
| + // 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(DataReductionProxyBlockingPageTest,
|
| + 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);
|
| +
|
| + DataReductionProxyBlockingPage* interstitial =
|
| + GetDataReductionProxyBlockingPage();
|
| + ASSERT_TRUE(interstitial);
|
| +
|
| + // Simulate the user clicking "don't proceed".
|
| + DontProceedThroughSubresourceInterstitial(interstitial);
|
| + EXPECT_EQ(CANCEL, user_response());
|
| + EXPECT_FALSE(GetDataReductionProxyBlockingPage());
|
| +
|
| + // 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(DataReductionProxyBlockingPageTest, 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);
|
| +
|
| + DataReductionProxyBlockingPage* interstitial =
|
| + GetDataReductionProxyBlockingPage();
|
| + 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(DataReductionProxyBlockingPageTest, 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);
|
| + DataReductionProxyBlockingPage* interstitial =
|
| + GetDataReductionProxyBlockingPage();
|
| + 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 = GetDataReductionProxyBlockingPage();
|
| + 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 = GetDataReductionProxyBlockingPage();
|
| + ASSERT_TRUE(interstitial);
|
| +
|
| + // Let's proceed and make sure everything is OK.
|
| + ProceedThroughInterstitial(interstitial);
|
| + Navigate(kBypassURL, 2); // Commit the navigation.
|
| + interstitial = GetDataReductionProxyBlockingPage();
|
| + 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.
|
| +TEST_F(DataReductionProxyBlockingPageTest, 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);
|
| + DataReductionProxyBlockingPage* interstitial =
|
| + GetDataReductionProxyBlockingPage();
|
| + 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(GetDataReductionProxyBlockingPage());
|
| +}
|
| +
|
| +} // namespace data_reduction_proxy
|
|
|