1 // Copyright (c) 2011 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 "content/browser/browser_thread.h"
7 #include "content/browser/renderer_host/test_render_view_host.h"
8 #include "content/browser/tab_contents/navigation_entry.h"
9 #include "content/browser/tab_contents/test_tab_contents.h"
10 #include "content/common/view_messages.h"
11
12 static const char* kURL1 = "http://www.google.com/";
13 static const char* kURL2 = "http://www.gmail.com/";
14
15 namespace {
16
17 // An OfflineLoadPage class that does not create windows.
18 class TestOfflineLoadPage : public chromeos::OfflineLoadPage {
19 public:
TestOfflineLoadPage(TabContents * tab_contents,const GURL & url,Delegate * delegate)20 TestOfflineLoadPage(TabContents* tab_contents,
21 const GURL& url,
22 Delegate* delegate)
23 : chromeos::OfflineLoadPage(tab_contents, url, delegate) {
24 EnableTest();
25 }
26
27 // Overriden from InterstitialPage. Don't create a view.
CreateTabContentsView()28 virtual TabContentsView* CreateTabContentsView() {
29 return NULL;
30 }
31 };
32
33 } // namespace
34
35 namespace chromeos {
36
37 class OfflineLoadPageTest : public RenderViewHostTestHarness,
38 public OfflineLoadPage::Delegate {
39 public:
40 // The decision the user made.
41 enum UserResponse {
42 PENDING,
43 OK,
44 CANCEL
45 };
46
OfflineLoadPageTest()47 OfflineLoadPageTest()
48 : ui_thread_(BrowserThread::UI, MessageLoop::current()),
49 io_thread_(BrowserThread::IO, MessageLoop::current()) {
50 }
51
SetUp()52 virtual void SetUp() {
53 RenderViewHostTestHarness::SetUp();
54 user_response_ = PENDING;
55 }
56
57 // OfflineLoadPage::Delegate implementation.
OnBlockingPageComplete(bool proceed)58 virtual void OnBlockingPageComplete(bool proceed) {
59 if (proceed)
60 user_response_ = OK;
61 else
62 user_response_ = CANCEL;
63 }
64
Navigate(const char * url,int page_id)65 void Navigate(const char* url, int page_id) {
66 ViewHostMsg_FrameNavigate_Params params;
67 InitNavigateParams(¶ms, page_id, GURL(url), PageTransition::TYPED);
68 contents()->TestDidNavigate(contents()->render_view_host(), params);
69 }
70
ShowInterstitial(const char * url)71 void ShowInterstitial(const char* url) {
72 (new TestOfflineLoadPage(contents(), GURL(url), this))->Show();
73 }
74
75 // Returns the OfflineLoadPage currently showing or NULL if none is
76 // showing.
GetOfflineLoadPage()77 InterstitialPage* GetOfflineLoadPage() {
78 return InterstitialPage::GetInterstitialPage(contents());
79 }
80
user_response() const81 UserResponse user_response() const { return user_response_; }
82
83 private:
84 UserResponse user_response_;
85 BrowserThread ui_thread_;
86 BrowserThread io_thread_;
87 };
88
89
TEST_F(OfflineLoadPageTest,OfflinePaeProceed)90 TEST_F(OfflineLoadPageTest, OfflinePaeProceed) {
91 // Start a load.
92 Navigate(kURL1, 1);
93 // Load next page.
94 controller().LoadURL(GURL(kURL2), GURL(), PageTransition::TYPED);
95
96 // Simulate the load causing an offline browsing interstitial page
97 // to be shown.
98 ShowInterstitial(kURL2);
99 InterstitialPage* interstitial = GetOfflineLoadPage();
100 ASSERT_TRUE(interstitial);
101 MessageLoop::current()->RunAllPending();
102
103 // Simulate the user clicking "proceed".
104 interstitial->Proceed();
105 MessageLoop::current()->RunAllPending();
106
107 EXPECT_EQ(OK, user_response());
108
109 // The URL remains to be URL2.
110 EXPECT_EQ(kURL2, contents()->GetURL().spec());
111
112 // Commit navigation and the interstitial page is gone.
113 Navigate(kURL2, 2);
114 EXPECT_FALSE(GetOfflineLoadPage());
115 }
116
117 // Tests showing an offline page and not proceeding.
TEST_F(OfflineLoadPageTest,OfflinePageDontProceed)118 TEST_F(OfflineLoadPageTest, OfflinePageDontProceed) {
119 // Start a load.
120 Navigate(kURL1, 1);
121 controller().LoadURL(GURL(kURL2), GURL(), PageTransition::TYPED);
122
123 // Simulate the load causing an offline interstitial page to be shown.
124 ShowInterstitial(kURL2);
125 InterstitialPage* interstitial = GetOfflineLoadPage();
126 ASSERT_TRUE(interstitial);
127 MessageLoop::current()->RunAllPending();
128
129 // Simulate the user clicking "don't proceed".
130 interstitial->DontProceed();
131
132 // The interstitial should be gone.
133 EXPECT_EQ(CANCEL, user_response());
134 EXPECT_FALSE(GetOfflineLoadPage());
135 // We did not proceed, the pending entry should be gone.
136 EXPECT_FALSE(controller().pending_entry());
137 // the URL is set back to kURL1.
138 EXPECT_EQ(kURL1, contents()->GetURL().spec());
139 }
140
141 } // namespace chromeos
142