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..63bbb76e72b2c9a12017d4bd073f6d11e739e581 |
--- /dev/null |
+++ b/components/data_reduction_proxy/content/browser/data_reduction_proxy_debug_blocking_page_unittest.cc |
@@ -0,0 +1,433 @@ |
+// 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/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_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" |
+ |
+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); |
+ } |
+}; |
+ |
+// TODO(megjablon): Add tests that verify the reception of a bypass message |
+// triggers the interstitial. |
+class DataReductionProxyDebugBlockingPageTest |
+ : public content::RenderViewHostTestHarness { |
+ public: |
+ // The decision the user made. |
+ enum UserResponse { |
+ PENDING, |
+ OK, |
+ CANCEL |
+ }; |
+ |
+ DataReductionProxyDebugBlockingPageTest() : user_response_(PENDING) { |
+ } |
+ |
+ void SetUp() override { |
+ content::RenderViewHostTestHarness::SetUp(); |
+ DataReductionProxyDebugBlockingPage::RegisterFactory(&factory_); |
+ ui_manager_ = new DataReductionProxyDebugUIManager( |
+ base::MessageLoopProxy::current(), |
+ base::MessageLoopProxy::current(), |
+ "en-US"); |
+ 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* render_frame_host = is_cross_site ? |
+ content::WebContentsTester::For( |
+ web_contents())->GetPendingMainFrame() : |
+ web_contents()->GetMainFrame(); |
+ content::WebContentsTester::For(web_contents())->TestDidNavigate( |
+ render_frame_host, |
+ 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 causes |
+// the interstitial to disappear. |
+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); |
+ DataReductionProxyDebugBlockingPage* interstitial = |
+ GetDataReductionProxyDebugBlockingPage(); |
+ ASSERT_TRUE(interstitial); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Simulate the user clicking "proceed" then "don't proceed". |
+ 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 |