Clean up the SendNavigate family of functions.
[chromium-blink-merge.git] / content / browser / renderer_host / render_view_host_unittest.cc
blobedf12f18e3eae0b8bc75339e8696048719ddbb21
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.
5 #include "base/path_service.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "content/browser/child_process_security_policy_impl.h"
8 #include "content/browser/frame_host/render_frame_host_impl.h"
9 #include "content/browser/renderer_host/render_message_filter.h"
10 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
11 #include "content/browser/renderer_host/render_widget_helper.h"
12 #include "content/common/frame_messages.h"
13 #include "content/common/input_messages.h"
14 #include "content/common/view_messages.h"
15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/navigation_entry.h"
17 #include "content/public/common/bindings_policy.h"
18 #include "content/public/common/drop_data.h"
19 #include "content/public/common/url_constants.h"
20 #include "content/public/test/mock_render_process_host.h"
21 #include "content/test/test_content_browser_client.h"
22 #include "content/test/test_render_view_host.h"
23 #include "content/test/test_web_contents.h"
24 #include "net/base/filename_util.h"
25 #include "third_party/WebKit/public/web/WebDragOperation.h"
26 #include "ui/base/page_transition_types.h"
28 namespace content {
30 class RenderViewHostTestBrowserClient : public TestContentBrowserClient {
31 public:
32 RenderViewHostTestBrowserClient() {}
33 ~RenderViewHostTestBrowserClient() override {}
35 bool IsHandledURL(const GURL& url) override {
36 return url.scheme() == url::kFileScheme;
39 private:
40 DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestBrowserClient);
43 class RenderViewHostTest : public RenderViewHostImplTestHarness {
44 public:
45 RenderViewHostTest() : old_browser_client_(NULL) {}
46 ~RenderViewHostTest() override {}
48 void SetUp() override {
49 RenderViewHostImplTestHarness::SetUp();
50 old_browser_client_ = SetBrowserClientForTesting(&test_browser_client_);
53 void TearDown() override {
54 SetBrowserClientForTesting(old_browser_client_);
55 RenderViewHostImplTestHarness::TearDown();
58 private:
59 RenderViewHostTestBrowserClient test_browser_client_;
60 ContentBrowserClient* old_browser_client_;
62 DISALLOW_COPY_AND_ASSIGN(RenderViewHostTest);
65 // All about URLs reported by the renderer should get rewritten to about:blank.
66 // See RenderViewHost::OnNavigate for a discussion.
67 TEST_F(RenderViewHostTest, FilterAbout) {
68 main_test_rfh()->NavigateAndCommitRendererInitiated(
69 1, true, GURL("about:cache"));
70 ASSERT_TRUE(controller().GetVisibleEntry());
71 EXPECT_EQ(GURL(url::kAboutBlankURL),
72 controller().GetVisibleEntry()->GetURL());
75 // Create a full screen popup RenderWidgetHost and View.
76 TEST_F(RenderViewHostTest, CreateFullscreenWidget) {
77 int routing_id = process()->GetNextRoutingID();
78 test_rvh()->CreateNewFullscreenWidget(routing_id);
81 // Makes sure that the RenderViewHost is not waiting for an unload ack when
82 // reloading a page. If this is not the case, when reloading, the contents may
83 // get closed out even though the user pressed the reload button.
84 TEST_F(RenderViewHostTest, ResetUnloadOnReload) {
85 const GURL url1("http://foo1");
86 const GURL url2("http://foo2");
88 // This test is for a subtle timing bug. Here's the sequence that triggered
89 // the bug:
90 // . go to a page.
91 // . go to a new page, preferably one that takes a while to resolve, such
92 // as one on a site that doesn't exist.
93 // . After this step IsWaitingForUnloadACK returns true on the first RVH.
94 // . click stop before the page has been commited.
95 // . click reload.
96 // . IsWaitingForUnloadACK still returns true, and if the hang monitor fires
97 // the contents gets closed.
99 NavigateAndCommit(url1);
100 controller().LoadURL(
101 url2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
102 // Simulate the ClosePage call which is normally sent by the net::URLRequest.
103 test_rvh()->ClosePage();
104 // Needed so that navigations are not suspended on the RFH.
105 main_test_rfh()->SendBeforeUnloadACK(true);
106 contents()->Stop();
107 controller().Reload(false);
108 EXPECT_FALSE(main_test_rfh()->IsWaitingForUnloadACK());
111 // Ensure we do not grant bindings to a process shared with unprivileged views.
112 TEST_F(RenderViewHostTest, DontGrantBindingsToSharedProcess) {
113 // Create another view in the same process.
114 scoped_ptr<TestWebContents> new_web_contents(
115 TestWebContents::Create(browser_context(), rvh()->GetSiteInstance()));
117 rvh()->AllowBindings(BINDINGS_POLICY_WEB_UI);
118 EXPECT_FALSE(rvh()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
121 class MockDraggingRenderViewHostDelegateView
122 : public RenderViewHostDelegateView {
123 public:
124 ~MockDraggingRenderViewHostDelegateView() override {}
125 void StartDragging(const DropData& drop_data,
126 blink::WebDragOperationsMask allowed_ops,
127 const gfx::ImageSkia& image,
128 const gfx::Vector2d& image_offset,
129 const DragEventSourceInfo& event_info) override {
130 drag_url_ = drop_data.url;
131 html_base_url_ = drop_data.html_base_url;
133 void UpdateDragCursor(blink::WebDragOperation operation) override {}
134 void GotFocus() override {}
135 void TakeFocus(bool reverse) override {}
136 virtual void UpdatePreferredSize(const gfx::Size& pref_size) {}
138 GURL drag_url() {
139 return drag_url_;
142 GURL html_base_url() {
143 return html_base_url_;
146 private:
147 GURL drag_url_;
148 GURL html_base_url_;
151 TEST_F(RenderViewHostTest, StartDragging) {
152 TestWebContents* web_contents = contents();
153 MockDraggingRenderViewHostDelegateView delegate_view;
154 web_contents->set_delegate_view(&delegate_view);
156 DropData drop_data;
157 GURL file_url = GURL("file:///home/user/secrets.txt");
158 drop_data.url = file_url;
159 drop_data.html_base_url = file_url;
160 test_rvh()->TestOnStartDragging(drop_data);
161 EXPECT_EQ(GURL(url::kAboutBlankURL), delegate_view.drag_url());
162 EXPECT_EQ(GURL(url::kAboutBlankURL), delegate_view.html_base_url());
164 GURL http_url = GURL("http://www.domain.com/index.html");
165 drop_data.url = http_url;
166 drop_data.html_base_url = http_url;
167 test_rvh()->TestOnStartDragging(drop_data);
168 EXPECT_EQ(http_url, delegate_view.drag_url());
169 EXPECT_EQ(http_url, delegate_view.html_base_url());
171 GURL https_url = GURL("https://www.domain.com/index.html");
172 drop_data.url = https_url;
173 drop_data.html_base_url = https_url;
174 test_rvh()->TestOnStartDragging(drop_data);
175 EXPECT_EQ(https_url, delegate_view.drag_url());
176 EXPECT_EQ(https_url, delegate_view.html_base_url());
178 GURL javascript_url = GURL("javascript:alert('I am a bookmarklet')");
179 drop_data.url = javascript_url;
180 drop_data.html_base_url = http_url;
181 test_rvh()->TestOnStartDragging(drop_data);
182 EXPECT_EQ(javascript_url, delegate_view.drag_url());
183 EXPECT_EQ(http_url, delegate_view.html_base_url());
186 TEST_F(RenderViewHostTest, DragEnteredFileURLsStillBlocked) {
187 DropData dropped_data;
188 gfx::Point client_point;
189 gfx::Point screen_point;
190 // We use "//foo/bar" path (rather than "/foo/bar") since dragged paths are
191 // expected to be absolute on any platforms.
192 base::FilePath highlighted_file_path(FILE_PATH_LITERAL("//tmp/foo.html"));
193 base::FilePath dragged_file_path(FILE_PATH_LITERAL("//tmp/image.jpg"));
194 base::FilePath sensitive_file_path(FILE_PATH_LITERAL("//etc/passwd"));
195 GURL highlighted_file_url = net::FilePathToFileURL(highlighted_file_path);
196 GURL dragged_file_url = net::FilePathToFileURL(dragged_file_path);
197 GURL sensitive_file_url = net::FilePathToFileURL(sensitive_file_path);
198 dropped_data.url = highlighted_file_url;
199 dropped_data.filenames.push_back(
200 ui::FileInfo(dragged_file_path, base::FilePath()));
202 rvh()->DragTargetDragEnter(dropped_data, client_point, screen_point,
203 blink::WebDragOperationNone, 0);
205 int id = process()->GetID();
206 ChildProcessSecurityPolicyImpl* policy =
207 ChildProcessSecurityPolicyImpl::GetInstance();
209 EXPECT_FALSE(policy->CanRequestURL(id, highlighted_file_url));
210 EXPECT_FALSE(policy->CanReadFile(id, highlighted_file_path));
211 EXPECT_TRUE(policy->CanRequestURL(id, dragged_file_url));
212 EXPECT_TRUE(policy->CanReadFile(id, dragged_file_path));
213 EXPECT_FALSE(policy->CanRequestURL(id, sensitive_file_url));
214 EXPECT_FALSE(policy->CanReadFile(id, sensitive_file_path));
217 TEST_F(RenderViewHostTest, MessageWithBadHistoryItemFiles) {
218 base::FilePath file_path;
219 EXPECT_TRUE(PathService::Get(base::DIR_TEMP, &file_path));
220 file_path = file_path.AppendASCII("foo");
221 EXPECT_EQ(0, process()->bad_msg_count());
222 test_rvh()->TestOnUpdateStateWithFile(-1, file_path);
223 EXPECT_EQ(1, process()->bad_msg_count());
225 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
226 process()->GetID(), file_path);
227 test_rvh()->TestOnUpdateStateWithFile(-1, file_path);
228 EXPECT_EQ(1, process()->bad_msg_count());
231 namespace {
232 void SetBadFilePath(const GURL& url,
233 const base::FilePath& file_path,
234 FrameHostMsg_DidCommitProvisionalLoad_Params* params) {
235 params->page_state =
236 PageState::CreateForTesting(url, false, "data", &file_path);
240 TEST_F(RenderViewHostTest, NavigationWithBadHistoryItemFiles) {
241 GURL url("http://www.google.com");
242 base::FilePath file_path;
243 EXPECT_TRUE(PathService::Get(base::DIR_TEMP, &file_path));
244 file_path = file_path.AppendASCII("bar");
245 auto set_bad_file_path_callback = base::Bind(SetBadFilePath, url, file_path);
247 EXPECT_EQ(0, process()->bad_msg_count());
248 main_test_rfh()->SendRendererInitiatedNavigationRequest(url, false);
249 main_test_rfh()->PrepareForCommit();
250 contents()->GetMainFrame()->SendNavigateWithModificationCallback(
251 1, 1, true, url, set_bad_file_path_callback);
252 EXPECT_EQ(1, process()->bad_msg_count());
254 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
255 process()->GetID(), file_path);
256 main_test_rfh()->SendRendererInitiatedNavigationRequest(url, false);
257 main_test_rfh()->PrepareForCommit();
258 contents()->GetMainFrame()->SendNavigateWithModificationCallback(
259 2, 2, true, url, set_bad_file_path_callback);
260 EXPECT_EQ(1, process()->bad_msg_count());
263 TEST_F(RenderViewHostTest, RoutingIdSane) {
264 RenderFrameHostImpl* root_rfh =
265 contents()->GetFrameTree()->root()->current_frame_host();
266 EXPECT_EQ(contents()->GetMainFrame(), root_rfh);
267 EXPECT_EQ(test_rvh()->GetProcess(), root_rfh->GetProcess());
268 EXPECT_NE(test_rvh()->GetRoutingID(), root_rfh->routing_id());
271 class TestSaveImageFromDataURL : public RenderMessageFilter {
272 public:
273 TestSaveImageFromDataURL(
274 BrowserContext* context)
275 : RenderMessageFilter(
277 nullptr,
278 context,
279 context->GetRequestContext(),
280 nullptr,
281 nullptr,
282 nullptr,
283 nullptr) {
284 Reset();
287 void Reset() {
288 url_string_ = std::string();
289 is_downloaded_ = false;
292 std::string& UrlString() const {
293 return url_string_;
296 bool IsDownloaded() const {
297 return is_downloaded_;
300 void Test(const std::string& url) {
301 OnMessageReceived(ViewHostMsg_SaveImageFromDataURL(0, url));
304 protected:
305 ~TestSaveImageFromDataURL() override {}
306 void DownloadUrl(int render_view_id,
307 const GURL& url,
308 const Referrer& referrer,
309 const base::string16& suggested_name,
310 const bool use_prompt) const override {
311 url_string_ = url.spec();
312 is_downloaded_ = true;
315 private:
316 mutable std::string url_string_;
317 mutable bool is_downloaded_;
320 TEST_F(RenderViewHostTest, SaveImageFromDataURL) {
321 scoped_refptr<TestSaveImageFromDataURL> tester(
322 new TestSaveImageFromDataURL(browser_context()));
324 tester->Reset();
325 tester->Test("http://non-data-url.com");
326 EXPECT_EQ(tester->UrlString(), "");
327 EXPECT_FALSE(tester->IsDownloaded());
329 const std::string data_url = "data:image/gif;base64,"
330 "R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
332 tester->Reset();
333 tester->Test(data_url);
334 EXPECT_EQ(tester->UrlString(), data_url);
335 EXPECT_TRUE(tester->IsDownloaded());
338 } // namespace content