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 12using content::InterstitialPage; 13using content::WebContents; 14using content::WebContentsTester; 15 16static const char* kURL1 = "http://www.google.com/"; 17static const char* kURL2 = "http://www.gmail.com/"; 18 19namespace chromeos { 20 21class OfflineLoadPageTest; 22 23// An OfflineLoadPage class that does not create windows. 24class 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 43class 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()->GetRenderViewHost(), page_id, GURL(url), 67 content::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 88void TestOfflineLoadPage::NotifyBlockingPageComplete(bool proceed) { 89 test_page_->OnBlockingPageComplete(proceed); 90} 91 92TEST_F(OfflineLoadPageTest, OfflinePageProceed) { 93 // Start a load. 94 Navigate(kURL1, 1); 95 // Load next page. 96 controller().LoadURL(GURL(kURL2), content::Referrer(), 97 content::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. 121TEST_F(OfflineLoadPageTest, OfflinePageDontProceed) { 122 // Start a load. 123 Navigate(kURL1, 1); 124 controller().LoadURL(GURL(kURL2), content::Referrer(), 125 content::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