Home | History | Annotate | Download | only in offline
      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.
      4 
      5 #include "chrome/browser/chromeos/offline/offline_load_page.h"
      6 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
      7 #include "content/public/browser/interstitial_page.h"
      8 #include "content/public/browser/navigation_controller.h"
      9 #include "content/public/browser/web_contents.h"
     10 #include "content/public/test/web_contents_tester.h"
     11 
     12 using content::InterstitialPage;
     13 using content::WebContents;
     14 using content::WebContentsTester;
     15 
     16 static const char* kURL1 = "http://www.google.com/";
     17 static const char* kURL2 = "http://www.gmail.com/";
     18 
     19 namespace chromeos {
     20 
     21 class OfflineLoadPageTest;
     22 
     23 // An OfflineLoadPage class that does not create windows.
     24 class TestOfflineLoadPage :  public chromeos::OfflineLoadPage {
     25  public:
     26   TestOfflineLoadPage(WebContents* web_contents,
     27                       const GURL& url,
     28                       OfflineLoadPageTest* test_page)
     29     : chromeos::OfflineLoadPage(web_contents, url, CompletionCallback()),
     30       test_page_(test_page) {
     31     interstitial_page_->DontCreateViewForTesting();
     32   }
     33 
     34   // chromeos::OfflineLoadPage override.
     35   virtual void NotifyBlockingPageComplete(bool proceed) OVERRIDE;
     36 
     37  private:
     38   OfflineLoadPageTest* test_page_;
     39 
     40   DISALLOW_COPY_AND_ASSIGN(TestOfflineLoadPage);
     41 };
     42 
     43 class OfflineLoadPageTest : public ChromeRenderViewHostTestHarness {
     44  public:
     45   // The decision the user made.
     46   enum UserResponse {
     47     PENDING,
     48     OK,
     49     CANCEL
     50   };
     51 
     52   virtual void SetUp() {
     53     ChromeRenderViewHostTestHarness::SetUp();
     54     user_response_ = PENDING;
     55   }
     56 
     57   void OnBlockingPageComplete(bool proceed) {
     58     if (proceed)
     59       user_response_ = OK;
     60     else
     61       user_response_ = CANCEL;
     62   }
     63 
     64   void Navigate(const char* url, int page_id) {
     65     WebContentsTester::For(web_contents())->TestDidNavigate(
     66         web_contents()->GetMainFrame(), page_id, GURL(url),
     67         ui::PAGE_TRANSITION_TYPED);
     68   }
     69 
     70   void ShowInterstitial(const char* url) {
     71     (new TestOfflineLoadPage(web_contents(), GURL(url), this))->Show();
     72   }
     73 
     74   // Returns the OfflineLoadPage currently showing or NULL if none is
     75   // showing.
     76   InterstitialPage* GetOfflineLoadPage() {
     77     return InterstitialPage::GetInterstitialPage(web_contents());
     78   }
     79 
     80   UserResponse user_response() const { return user_response_; }
     81 
     82  private:
     83   friend class TestOfflineLoadPage;
     84 
     85   UserResponse user_response_;
     86 };
     87 
     88 void TestOfflineLoadPage::NotifyBlockingPageComplete(bool proceed) {
     89   test_page_->OnBlockingPageComplete(proceed);
     90 }
     91 
     92 TEST_F(OfflineLoadPageTest, OfflinePageProceed) {
     93   // Start a load.
     94   Navigate(kURL1, 1);
     95   // Load next page.
     96   controller().LoadURL(GURL(kURL2), content::Referrer(),
     97                        ui::PAGE_TRANSITION_TYPED, std::string());
     98 
     99   // Simulate the load causing an offline browsing interstitial page
    100   // to be shown.
    101   ShowInterstitial(kURL2);
    102   InterstitialPage* interstitial = GetOfflineLoadPage();
    103   ASSERT_TRUE(interstitial);
    104   base::MessageLoop::current()->RunUntilIdle();
    105 
    106   // Simulate the user clicking "proceed".
    107   interstitial->Proceed();
    108   base::MessageLoop::current()->RunUntilIdle();
    109 
    110   EXPECT_EQ(OK, user_response());
    111 
    112   // The URL remains to be URL2.
    113   EXPECT_EQ(kURL2, web_contents()->GetVisibleURL().spec());
    114 
    115   // Commit navigation and the interstitial page is gone.
    116   Navigate(kURL2, 2);
    117   EXPECT_FALSE(GetOfflineLoadPage());
    118 }
    119 
    120 // Tests showing an offline page and not proceeding.
    121 TEST_F(OfflineLoadPageTest, OfflinePageDontProceed) {
    122   // Start a load.
    123   Navigate(kURL1, 1);
    124   controller().LoadURL(GURL(kURL2), content::Referrer(),
    125                        ui::PAGE_TRANSITION_TYPED, std::string());
    126 
    127   // Simulate the load causing an offline interstitial page to be shown.
    128   ShowInterstitial(kURL2);
    129   InterstitialPage* interstitial = GetOfflineLoadPage();
    130   ASSERT_TRUE(interstitial);
    131   base::MessageLoop::current()->RunUntilIdle();
    132 
    133   // Simulate the user clicking "don't proceed".
    134   interstitial->DontProceed();
    135 
    136   // The interstitial should be gone.
    137   EXPECT_EQ(CANCEL, user_response());
    138   EXPECT_FALSE(GetOfflineLoadPage());
    139   // We did not proceed, the pending entry should be gone.
    140   EXPECT_FALSE(controller().GetPendingEntry());
    141   // the URL is set back to kURL1.
    142   EXPECT_EQ(kURL1, web_contents()->GetLastCommittedURL().spec());
    143 }
    144 
    145 }  // namespace chromeos
    146