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
12static const char* kURL1 = "http://www.google.com/";
13static const char* kURL2 = "http://www.gmail.com/";
14
15namespace {
16
17// An OfflineLoadPage class that does not create windows.
18class TestOfflineLoadPage :  public chromeos::OfflineLoadPage {
19 public:
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.
28  virtual TabContentsView* CreateTabContentsView() {
29    return NULL;
30  }
31};
32
33}  // namespace
34
35namespace chromeos {
36
37class 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
47  OfflineLoadPageTest()
48      : ui_thread_(BrowserThread::UI, MessageLoop::current()),
49        io_thread_(BrowserThread::IO, MessageLoop::current()) {
50  }
51
52  virtual void SetUp() {
53    RenderViewHostTestHarness::SetUp();
54    user_response_ = PENDING;
55  }
56
57  // OfflineLoadPage::Delegate implementation.
58  virtual void OnBlockingPageComplete(bool proceed) {
59    if (proceed)
60      user_response_ = OK;
61    else
62      user_response_ = CANCEL;
63  }
64
65  void Navigate(const char* url, int page_id) {
66    ViewHostMsg_FrameNavigate_Params params;
67    InitNavigateParams(&params, page_id, GURL(url), PageTransition::TYPED);
68    contents()->TestDidNavigate(contents()->render_view_host(), params);
69  }
70
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.
77  InterstitialPage* GetOfflineLoadPage() {
78    return InterstitialPage::GetInterstitialPage(contents());
79  }
80
81  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
90TEST_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.
118TEST_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