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 "content/test/test_web_contents.h"
6
7#include <utility>
8
9#include "content/browser/browser_url_handler_impl.h"
10#include "content/browser/frame_host/cross_process_frame_connector.h"
11#include "content/browser/frame_host/navigation_entry_impl.h"
12#include "content/browser/frame_host/navigator.h"
13#include "content/browser/renderer_host/render_view_host_impl.h"
14#include "content/browser/site_instance_impl.h"
15#include "content/common/frame_messages.h"
16#include "content/common/view_messages.h"
17#include "content/public/browser/notification_registrar.h"
18#include "content/public/browser/notification_source.h"
19#include "content/public/browser/notification_types.h"
20#include "content/public/common/page_state.h"
21#include "content/public/test/mock_render_process_host.h"
22#include "content/test/test_render_view_host.h"
23#include "ui/base/page_transition_types.h"
24
25namespace content {
26
27TestWebContents::TestWebContents(BrowserContext* browser_context)
28    : WebContentsImpl(browser_context, NULL),
29      delegate_view_override_(NULL),
30      expect_set_history_length_and_prune_(false),
31      expect_set_history_length_and_prune_site_instance_(NULL),
32      expect_set_history_length_and_prune_history_length_(0),
33      expect_set_history_length_and_prune_min_page_id_(-1) {
34}
35
36TestWebContents* TestWebContents::Create(BrowserContext* browser_context,
37                                         SiteInstance* instance) {
38  TestWebContents* test_web_contents = new TestWebContents(browser_context);
39  test_web_contents->Init(WebContents::CreateParams(browser_context, instance));
40  return test_web_contents;
41}
42
43TestWebContents::~TestWebContents() {
44  EXPECT_FALSE(expect_set_history_length_and_prune_);
45}
46
47TestRenderFrameHost* TestWebContents::GetMainFrame() {
48  return static_cast<TestRenderFrameHost*>(WebContentsImpl::GetMainFrame());
49}
50
51TestRenderViewHost* TestWebContents::GetRenderViewHost() const {
52    return static_cast<TestRenderViewHost*>(
53        WebContentsImpl::GetRenderViewHost());
54}
55
56TestRenderFrameHost* TestWebContents::GetPendingMainFrame() const {
57  return static_cast<TestRenderFrameHost*>(
58      GetRenderManager()->pending_frame_host());
59}
60
61void TestWebContents::TestDidNavigate(RenderFrameHost* render_frame_host,
62                                      int page_id,
63                                      const GURL& url,
64                                      ui::PageTransition transition) {
65  TestDidNavigateWithReferrer(render_frame_host,
66                              page_id,
67                              url,
68                              Referrer(),
69                              transition);
70}
71
72void TestWebContents::TestDidNavigateWithReferrer(
73    RenderFrameHost* render_frame_host,
74    int page_id,
75    const GURL& url,
76    const Referrer& referrer,
77    ui::PageTransition transition) {
78  FrameHostMsg_DidCommitProvisionalLoad_Params params;
79
80  params.page_id = page_id;
81  params.url = url;
82  params.referrer = referrer;
83  params.transition = transition;
84  params.redirects = std::vector<GURL>();
85  params.should_update_history = false;
86  params.searchable_form_url = GURL();
87  params.searchable_form_encoding = std::string();
88  params.security_info = std::string();
89  params.gesture = NavigationGestureUser;
90  params.was_within_same_page = false;
91  params.is_post = false;
92  params.page_state = PageState::CreateFromURL(url);
93
94  RenderFrameHostImpl* rfhi =
95      static_cast<RenderFrameHostImpl*>(render_frame_host);
96  rfhi->frame_tree_node()->navigator()->DidNavigate(rfhi, params);
97}
98
99WebPreferences TestWebContents::TestComputeWebkitPrefs() {
100  return ComputeWebkitPrefs();
101}
102
103bool TestWebContents::CreateRenderViewForRenderManager(
104    RenderViewHost* render_view_host,
105    int opener_route_id,
106    int proxy_routing_id,
107    bool for_main_frame) {
108  UpdateMaxPageIDIfNecessary(render_view_host);
109  // This will go to a TestRenderViewHost.
110  static_cast<RenderViewHostImpl*>(
111      render_view_host)->CreateRenderView(base::string16(),
112                                          opener_route_id,
113                                          proxy_routing_id,
114                                          -1, false);
115  return true;
116}
117
118WebContents* TestWebContents::Clone() {
119  WebContentsImpl* contents =
120      Create(GetBrowserContext(), SiteInstance::Create(GetBrowserContext()));
121  contents->GetController().CopyStateFrom(controller_);
122  return contents;
123}
124
125void TestWebContents::NavigateAndCommit(const GURL& url) {
126  GetController().LoadURL(
127      url, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
128  GURL loaded_url(url);
129  bool reverse_on_redirect = false;
130  BrowserURLHandlerImpl::GetInstance()->RewriteURLIfNecessary(
131      &loaded_url, GetBrowserContext(), &reverse_on_redirect);
132
133  // LoadURL created a navigation entry, now simulate the RenderView sending
134  // a notification that it actually navigated.
135  CommitPendingNavigation();
136}
137
138void TestWebContents::TestSetIsLoading(bool value) {
139  SetIsLoading(GetRenderViewHost(), value, true, NULL);
140}
141
142void TestWebContents::CommitPendingNavigation() {
143  // If we are doing a cross-site navigation, this simulates the current RVH
144  // notifying that it has unloaded so the pending RVH is resumed and can
145  // navigate.
146  ProceedWithCrossSiteNavigation();
147  TestRenderFrameHost* old_rfh = GetMainFrame();
148  TestRenderFrameHost* rfh = GetPendingMainFrame();
149  if (!rfh)
150    rfh = old_rfh;
151
152  const NavigationEntry* entry = GetController().GetPendingEntry();
153  DCHECK(entry);
154  int page_id = entry->GetPageID();
155  if (page_id == -1) {
156    // It's a new navigation, assign a never-seen page id to it.
157    page_id = GetMaxPageIDForSiteInstance(rfh->GetSiteInstance()) + 1;
158  }
159
160  rfh->SendNavigate(page_id, entry->GetURL());
161  // Simulate the SwapOut_ACK. This is needed when cross-site navigation happens
162  // (old_rfh != rfh).
163  if (old_rfh != rfh)
164    old_rfh->OnSwappedOut(false);
165}
166
167void TestWebContents::ProceedWithCrossSiteNavigation() {
168  if (!GetPendingMainFrame())
169    return;
170  GetMainFrame()->GetRenderViewHost()->SendBeforeUnloadACK(true);
171}
172
173RenderViewHostDelegateView* TestWebContents::GetDelegateView() {
174  if (delegate_view_override_)
175    return delegate_view_override_;
176  return WebContentsImpl::GetDelegateView();
177}
178
179void TestWebContents::SetOpener(TestWebContents* opener) {
180  // This is normally only set in the WebContents constructor, which also
181  // registers an observer for when the opener gets closed.
182  opener_ = opener;
183  AddDestructionObserver(opener_);
184}
185
186void TestWebContents::AddPendingContents(TestWebContents* contents) {
187  // This is normally only done in WebContentsImpl::CreateNewWindow.
188  pending_contents_[contents->GetRenderViewHost()->GetRoutingID()] = contents;
189  AddDestructionObserver(contents);
190}
191
192void TestWebContents::ExpectSetHistoryLengthAndPrune(
193    const SiteInstance* site_instance,
194    int history_length,
195    int32 min_page_id) {
196  expect_set_history_length_and_prune_ = true;
197  expect_set_history_length_and_prune_site_instance_ =
198      static_cast<const SiteInstanceImpl*>(site_instance);
199  expect_set_history_length_and_prune_history_length_ = history_length;
200  expect_set_history_length_and_prune_min_page_id_ = min_page_id;
201}
202
203void TestWebContents::SetHistoryLengthAndPrune(
204    const SiteInstance* site_instance, int history_length,
205    int32 min_page_id) {
206  EXPECT_TRUE(expect_set_history_length_and_prune_);
207  expect_set_history_length_and_prune_ = false;
208  EXPECT_EQ(expect_set_history_length_and_prune_site_instance_.get(),
209            site_instance);
210  EXPECT_EQ(expect_set_history_length_and_prune_history_length_,
211            history_length);
212  EXPECT_EQ(expect_set_history_length_and_prune_min_page_id_, min_page_id);
213}
214
215void TestWebContents::TestDidFinishLoad(const GURL& url) {
216  FrameHostMsg_DidFinishLoad msg(0, url);
217  frame_tree_.root()->current_frame_host()->OnMessageReceived(msg);
218}
219
220void TestWebContents::TestDidFailLoadWithError(
221    const GURL& url,
222    int error_code,
223    const base::string16& error_description) {
224  FrameHostMsg_DidFailLoadWithError msg(
225      0, url, error_code, error_description);
226  frame_tree_.root()->current_frame_host()->OnMessageReceived(msg);
227}
228
229void TestWebContents::CreateNewWindow(
230    int render_process_id,
231    int route_id,
232    int main_frame_route_id,
233    const ViewHostMsg_CreateWindow_Params& params,
234    SessionStorageNamespace* session_storage_namespace) {
235}
236
237void TestWebContents::CreateNewWidget(int render_process_id,
238                                      int route_id,
239                                      blink::WebPopupType popup_type) {
240}
241
242void TestWebContents::CreateNewFullscreenWidget(int render_process_id,
243                                                int route_id) {
244}
245
246void TestWebContents::ShowCreatedWindow(int route_id,
247                                        WindowOpenDisposition disposition,
248                                        const gfx::Rect& initial_pos,
249                                        bool user_gesture) {
250}
251
252void TestWebContents::ShowCreatedWidget(int route_id,
253                                        const gfx::Rect& initial_pos) {
254}
255
256void TestWebContents::ShowCreatedFullscreenWidget(int route_id) {
257}
258
259}  // namespace content
260