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