Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc

Issue 288353002: [dom_distiller] Fix crash for invalid chrome-distiller:// requests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Change to use ASSERT_TRUE instead of DCHECK Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | components/dom_distiller/content/dom_distiller_viewer_source.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string.h> 5 #include <string.h>
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/guid.h" 8 #include "base/guid.h"
9 #include "base/path_service.h" 9 #include "base/path_service.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 entry.set_entry_id(entry_id); 65 entry.set_entry_id(entry_id);
66 if (!page_url.empty()) { 66 if (!page_url.empty()) {
67 ArticleEntryPage* page = entry.add_pages(); 67 ArticleEntryPage* page = entry.add_pages();
68 page->set_url(page_url); 68 page->set_url(page_url);
69 } 69 }
70 return entry; 70 return entry;
71 } 71 }
72 72
73 } // namespace 73 } // namespace
74 74
75 // WebContents observer that stores reference to the current |RenderViewHost|.
76 class LoadSuccessObserver : public content::WebContentsObserver {
77 public:
78 explicit LoadSuccessObserver(content::WebContents* contents)
79 : content::WebContentsObserver(contents),
80 validated_url_(GURL()),
81 finished_load_(false),
82 load_failed_(false),
83 web_contents_(contents),
84 render_view_host_(NULL) {}
85
86 virtual void DidFinishLoad(int64 frame_id,
87 const GURL& validated_url,
88 bool is_main_frame,
89 content::RenderViewHost* render_view_host)
90 OVERRIDE {
91 validated_url_ = validated_url;
92 finished_load_ = true;
93 render_view_host_ = render_view_host;
94 }
95
96 virtual void DidFailProvisionalLoad(int64 frame_id,
97 const base::string16& frame_unique_name,
98 bool is_main_frame,
99 const GURL& validated_url,
100 int error_code,
101 const base::string16& error_description,
102 content::RenderViewHost* render_view_host)
103 OVERRIDE {
104 load_failed_ = true;
105 }
106
107 const GURL& validated_url() const { return validated_url_; }
108 bool finished_load() const { return finished_load_; }
109 bool load_failed() const { return load_failed_; }
110 content::WebContents* web_contents() const { return web_contents_; }
111
112 const content::RenderViewHost* render_view_host() const {
113 return render_view_host_;
114 }
115
116 private:
117 GURL validated_url_;
118 bool finished_load_;
119 bool load_failed_;
120 content::WebContents* web_contents_;
121 content::RenderViewHost* render_view_host_;
122
123 DISALLOW_COPY_AND_ASSIGN(LoadSuccessObserver);
124 };
125
126 class DomDistillerViewerSourceBrowserTest : public InProcessBrowserTest { 75 class DomDistillerViewerSourceBrowserTest : public InProcessBrowserTest {
127 public: 76 public:
128 DomDistillerViewerSourceBrowserTest() {} 77 DomDistillerViewerSourceBrowserTest() {}
129 virtual ~DomDistillerViewerSourceBrowserTest() {} 78 virtual ~DomDistillerViewerSourceBrowserTest() {}
130 79
131 virtual void SetUpOnMainThread() OVERRIDE { 80 virtual void SetUpOnMainThread() OVERRIDE {
132 database_model_ = new FakeDB::EntryMap; 81 database_model_ = new FakeDB::EntryMap;
133 } 82 }
134 83
135 virtual void CleanUpOnMainThread() OVERRIDE { delete database_model_; } 84 virtual void CleanUpOnMainThread() OVERRIDE { delete database_model_; }
136 85
137 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 86 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
138 command_line->AppendSwitch(switches::kEnableDomDistiller); 87 command_line->AppendSwitch(switches::kEnableDomDistiller);
139 } 88 }
140 89
141 static KeyedService* Build(content::BrowserContext* context) { 90 static KeyedService* Build(content::BrowserContext* context) {
142 FakeDB* fake_db = new FakeDB(database_model_); 91 FakeDB* fake_db = new FakeDB(database_model_);
143 distiller_factory_ = new MockDistillerFactory(); 92 distiller_factory_ = new MockDistillerFactory();
144 MockDistillerPageFactory* distiller_page_factory_ = 93 MockDistillerPageFactory* distiller_page_factory_ =
145 new MockDistillerPageFactory(); 94 new MockDistillerPageFactory();
146 DomDistillerContextKeyedService* service = 95 DomDistillerContextKeyedService* service =
147 new DomDistillerContextKeyedService( 96 new DomDistillerContextKeyedService(
148 scoped_ptr<DomDistillerStoreInterface>( 97 scoped_ptr<DomDistillerStoreInterface>(
149 CreateStoreWithFakeDB(fake_db, FakeDB::EntryMap())), 98 CreateStoreWithFakeDB(fake_db, FakeDB::EntryMap())),
150 scoped_ptr<DistillerFactory>(distiller_factory_), 99 scoped_ptr<DistillerFactory>(distiller_factory_),
151 scoped_ptr<DistillerPageFactory>(distiller_page_factory_)); 100 scoped_ptr<DistillerPageFactory>(distiller_page_factory_));
152 MockDistillerPage* distiller_page = new MockDistillerPage();
153 EXPECT_CALL(*distiller_page_factory_, CreateDistillerPageImpl())
154 .WillOnce(testing::Return(distiller_page));
155 fake_db->InitCallback(true); 101 fake_db->InitCallback(true);
156 fake_db->LoadCallback(true); 102 fake_db->LoadCallback(true);
157 if (expect_distillation_) { 103 if (expect_distillation_) {
158 // There will only be destillation of an article if the database contains 104 // There will only be destillation of an article if the database contains
159 // the article. 105 // the article.
160 FakeDistiller* distiller = new FakeDistiller(true); 106 FakeDistiller* distiller = new FakeDistiller(true);
161 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) 107 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl())
162 .WillOnce(testing::Return(distiller)); 108 .WillOnce(testing::Return(distiller));
109 MockDistillerPage* distiller_page = new MockDistillerPage();
110 EXPECT_CALL(*distiller_page_factory_, CreateDistillerPageImpl())
Yaron 2014/05/16 17:07:42 I think this is needed even in the expect_distilla
nyquist 2014/05/16 18:46:44 Done.
111 .WillOnce(testing::Return(distiller_page));
163 } 112 }
164 return service; 113 return service;
165 } 114 }
166 115
167 void ViewSingleDistilledPage(const GURL& url); 116 void ViewSingleDistilledPage(const GURL& url,
117 const std::string& expected_mime_type);
168 // Database entries. 118 // Database entries.
169 static FakeDB::EntryMap* database_model_; 119 static FakeDB::EntryMap* database_model_;
170 static bool expect_distillation_; 120 static bool expect_distillation_;
171 static MockDistillerFactory* distiller_factory_; 121 static MockDistillerFactory* distiller_factory_;
172 }; 122 };
173 123
174 FakeDB::EntryMap* DomDistillerViewerSourceBrowserTest::database_model_; 124 FakeDB::EntryMap* DomDistillerViewerSourceBrowserTest::database_model_;
175 bool DomDistillerViewerSourceBrowserTest::expect_distillation_ = false; 125 bool DomDistillerViewerSourceBrowserTest::expect_distillation_ = false;
176 MockDistillerFactory* DomDistillerViewerSourceBrowserTest::distiller_factory_ = 126 MockDistillerFactory* DomDistillerViewerSourceBrowserTest::distiller_factory_ =
177 NULL; 127 NULL;
178 128
179 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings 129 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings
180 // are enabled when the article exists in the database. 130 // are enabled when the article exists in the database.
181 // Flakiness: crbug.com/356866
182 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 131 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest,
183 DISABLED_NoWebUIBindingsArticleExists) { 132 NoWebUIBindingsArticleExists) {
184 // Ensure there is one item in the database, which will trigger distillation. 133 // Ensure there is one item in the database, which will trigger distillation.
185 const ArticleEntry entry = CreateEntry("DISTILLED", "http://example.com/1"); 134 const ArticleEntry entry = CreateEntry("DISTILLED", "http://example.com/1");
186 AddEntry(entry, database_model_); 135 AddEntry(entry, database_model_);
187 expect_distillation_ = true; 136 expect_distillation_ = true;
188 const GURL url = url_utils::GetDistillerViewUrlFromEntryId( 137 const GURL url = url_utils::GetDistillerViewUrlFromEntryId(
189 chrome::kDomDistillerScheme, entry.entry_id()); 138 chrome::kDomDistillerScheme, entry.entry_id());
190 ViewSingleDistilledPage(url); 139 ViewSingleDistilledPage(url, "text/html");
191 } 140 }
192 141
193 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings 142 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings
194 // are enabled when the article is not found. 143 // are enabled when the article is not found.
195 // Flakiness: crbug.com/356866
196 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 144 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest,
197 DISABLED_NoWebUIBindingsArticleNotFound) { 145 NoWebUIBindingsArticleNotFound) {
198 // The article does not exist, so assume no distillation will happen. 146 // The article does not exist, so assume no distillation will happen.
199 expect_distillation_ = false; 147 expect_distillation_ = false;
200 const GURL url(std::string(chrome::kDomDistillerScheme) + "://" + 148 const GURL url = url_utils::GetDistillerViewUrlFromEntryId(
201 base::GenerateGUID() + "/"); 149 chrome::kDomDistillerScheme, "DOES_NOT_EXIST");
202 ViewSingleDistilledPage(url); 150 ViewSingleDistilledPage(url, "text/html");
203 } 151 }
204 152
205 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings 153 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings
206 // are enabled when requesting to view an arbitrary URL. 154 // are enabled when requesting to view an arbitrary URL.
207 // Flakiness: crbug.com/356866
208 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 155 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest,
209 DISABLED_NoWebUIBindingsViewUrl) { 156 NoWebUIBindingsViewUrl) {
210 // We should expect distillation for any valid URL. 157 // We should expect distillation for any valid URL.
211 expect_distillation_ = true; 158 expect_distillation_ = true;
212 GURL view_url("http://www.example.com/1"); 159 GURL view_url("http://www.example.com/1");
213 const GURL url = url_utils::GetDistillerViewUrlFromUrl( 160 const GURL url = url_utils::GetDistillerViewUrlFromUrl(
214 chrome::kDomDistillerScheme, view_url); 161 chrome::kDomDistillerScheme, view_url);
215 ViewSingleDistilledPage(url); 162 ViewSingleDistilledPage(url, "text/html");
216 } 163 }
217 164
218 void DomDistillerViewerSourceBrowserTest::ViewSingleDistilledPage( 165 void DomDistillerViewerSourceBrowserTest::ViewSingleDistilledPage(
219 const GURL& url) { 166 const GURL& url,
167 const std::string& expected_mime_type) {
220 // Ensure the correct factory is used for the DomDistillerService. 168 // Ensure the correct factory is used for the DomDistillerService.
221 dom_distiller::DomDistillerServiceFactory::GetInstance() 169 dom_distiller::DomDistillerServiceFactory::GetInstance()
222 ->SetTestingFactoryAndUse(browser()->profile(), &Build); 170 ->SetTestingFactoryAndUse(browser()->profile(), &Build);
223 171
224 // Setup observer to inspect the RenderViewHost after committed navigation.
225 content::WebContents* contents =
226 browser()->tab_strip_model()->GetActiveWebContents();
227 LoadSuccessObserver observer(contents);
228
229 // Navigate to a URL which the source should respond to. 172 // Navigate to a URL which the source should respond to.
230 ui_test_utils::NavigateToURL(browser(), url); 173 ui_test_utils::NavigateToURL(browser(), url);
231 174
232 // A navigation should have succeeded to the correct URL. 175 // Ensure no bindings for the loaded |url|.
233 ASSERT_FALSE(observer.load_failed()); 176 content::WebContents* contents_after_nav =
234 ASSERT_TRUE(observer.finished_load()); 177 browser()->tab_strip_model()->GetActiveWebContents();
235 ASSERT_EQ(url, observer.validated_url()); 178 ASSERT_TRUE(contents_after_nav != NULL);
236 // Ensure no bindings. 179 EXPECT_EQ(url, contents_after_nav->GetLastCommittedURL());
237 const content::RenderViewHost* render_view_host = observer.render_view_host(); 180 const content::RenderViewHost* render_view_host =
238 ASSERT_EQ(0, render_view_host->GetEnabledBindings()); 181 contents_after_nav->GetRenderViewHost();
239 // The MIME-type should always be text/html for the distilled articles. 182 EXPECT_EQ(0, render_view_host->GetEnabledBindings());
240 EXPECT_EQ("text/html", observer.web_contents()->GetContentsMimeType()); 183 EXPECT_EQ(expected_mime_type, contents_after_nav->GetContentsMimeType());
241 } 184 }
242 185
243 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings 186 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings
244 // are enabled when the CSS resource is loaded. This CSS might be bundle with 187 // are enabled when the CSS resource is loaded. This CSS might be bundle with
245 // Chrome or provided by an extension. 188 // Chrome or provided by an extension.
246 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 189 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest,
247 NoWebUIBindingsDisplayCSS) { 190 NoWebUIBindingsDisplayCSS) {
248 // Setup observer to inspect the RenderViewHost after committed navigation. 191 expect_distillation_ = false;
249 content::WebContents* contents =
250 browser()->tab_strip_model()->GetActiveWebContents();
251 LoadSuccessObserver observer(contents);
252
253 // Navigate to a URL which the source should respond to with CSS. 192 // Navigate to a URL which the source should respond to with CSS.
254 std::string url_without_scheme = std::string("://foobar/") + kViewerCssPath; 193 std::string url_without_scheme = std::string("://foobar/") + kViewerCssPath;
255 GURL url(chrome::kDomDistillerScheme + url_without_scheme); 194 GURL url(chrome::kDomDistillerScheme + url_without_scheme);
256 ui_test_utils::NavigateToURL(browser(), url); 195 ViewSingleDistilledPage(url, "text/css");
257
258 // A navigation should have succeeded to the correct URL.
259 ASSERT_FALSE(observer.load_failed());
260 ASSERT_TRUE(observer.finished_load());
261 ASSERT_EQ(url, observer.validated_url());
262 // Ensure no bindings.
263 const content::RenderViewHost* render_view_host = observer.render_view_host();
264 ASSERT_EQ(0, render_view_host->GetEnabledBindings());
265 // The MIME-type should always be text/css for the CSS resources.
266 EXPECT_EQ("text/css", observer.web_contents()->GetContentsMimeType());
267 } 196 }
268 197
198 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest,
199 EmptyURLShouldNotCrash) {
200 // This is a bogus URL, so no distillation will happen.
201 expect_distillation_ = false;
202 const GURL url(std::string(chrome::kDomDistillerScheme) + "://bogus/");
203 ViewSingleDistilledPage(url, "text/html");
204 }
205
206 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest,
207 InvalidURLShouldNotCrash) {
208 // This is a bogus URL, so no distillation will happen.
209 expect_distillation_ = false;
210 const GURL url(std::string(chrome::kDomDistillerScheme) + "://bogus/foobar");
211 ViewSingleDistilledPage(url, "text/html");
212 }
269 213
270 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 214 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest,
271 MultiPageArticle) { 215 MultiPageArticle) {
272 expect_distillation_ = false; 216 expect_distillation_ = false;
273 dom_distiller::DomDistillerServiceFactory::GetInstance() 217 dom_distiller::DomDistillerServiceFactory::GetInstance()
274 ->SetTestingFactoryAndUse(browser()->profile(), &Build); 218 ->SetTestingFactoryAndUse(browser()->profile(), &Build);
275 219
276 scoped_refptr<content::MessageLoopRunner> distillation_done_runner = 220 scoped_refptr<content::MessageLoopRunner> distillation_done_runner =
277 new content::MessageLoopRunner; 221 new content::MessageLoopRunner;
278 222
279 FakeDistiller* distiller = new FakeDistiller( 223 FakeDistiller* distiller = new FakeDistiller(
280 false, 224 false,
281 distillation_done_runner->QuitClosure()); 225 distillation_done_runner->QuitClosure());
282 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) 226 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl())
283 .WillOnce(testing::Return(distiller)); 227 .WillOnce(testing::Return(distiller));
284 228
285 // Setup observer to inspect the RenderViewHost after committed navigation. 229 // Setup observer to inspect the RenderViewHost after committed navigation.
286 content::WebContents* contents = 230 content::WebContents* contents =
287 browser()->tab_strip_model()->GetActiveWebContents(); 231 browser()->tab_strip_model()->GetActiveWebContents();
288 LoadSuccessObserver observer(contents);
289 232
290 // Navigate to a URL and wait for the distiller to flush contents to the page. 233 // Navigate to a URL and wait for the distiller to flush contents to the page.
291 GURL url(dom_distiller::url_utils::GetDistillerViewUrlFromUrl( 234 GURL url(dom_distiller::url_utils::GetDistillerViewUrlFromUrl(
292 chrome::kDomDistillerScheme, GURL("http://urlthatlooksvalid.com"))); 235 chrome::kDomDistillerScheme, GURL("http://urlthatlooksvalid.com")));
293 chrome::NavigateParams params(browser(), url, content::PAGE_TRANSITION_TYPED); 236 chrome::NavigateParams params(browser(), url, content::PAGE_TRANSITION_TYPED);
294 chrome::Navigate(&params); 237 chrome::Navigate(&params);
295 distillation_done_runner->Run(); 238 distillation_done_runner->Run();
296 239
297 // Fake a multi-page response from distiller. 240 // Fake a multi-page response from distiller.
298 241
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 EXPECT_TRUE(content::ExecuteScriptAndExtractString( 301 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
359 contents, kGetLoadIndicatorClassName, &result)); 302 contents, kGetLoadIndicatorClassName, &result));
360 EXPECT_EQ("hidden", result); 303 EXPECT_EQ("hidden", result);
361 EXPECT_TRUE(content::ExecuteScriptAndExtractString( 304 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
362 contents, kGetContent , &result)); 305 contents, kGetContent , &result));
363 EXPECT_THAT(result, HasSubstr("Page 1 content")); 306 EXPECT_THAT(result, HasSubstr("Page 1 content"));
364 EXPECT_THAT(result, HasSubstr("Page 2 content")); 307 EXPECT_THAT(result, HasSubstr("Page 2 content"));
365 } 308 }
366 309
367 } // namespace dom_distiller 310 } // namespace dom_distiller
OLDNEW
« no previous file with comments | « no previous file | components/dom_distiller/content/dom_distiller_viewer_source.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698