OLD | NEW |
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 "chrome/browser/dom_distiller/dom_distiller_service_factory.h" | 9 #include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" |
9 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
10 #include "chrome/browser/ui/browser.h" | 11 #include "chrome/browser/ui/browser.h" |
11 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 12 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
12 #include "chrome/common/chrome_switches.h" | 13 #include "chrome/common/chrome_switches.h" |
13 #include "chrome/common/url_constants.h" | 14 #include "chrome/common/url_constants.h" |
14 #include "chrome/test/base/in_process_browser_test.h" | 15 #include "chrome/test/base/in_process_browser_test.h" |
15 #include "chrome/test/base/ui_test_utils.h" | 16 #include "chrome/test/base/ui_test_utils.h" |
16 #include "components/dom_distiller/content/dom_distiller_viewer_source.h" | 17 #include "components/dom_distiller/content/dom_distiller_viewer_source.h" |
17 #include "components/dom_distiller/core/distiller.h" | 18 #include "components/dom_distiller/core/distiller.h" |
18 #include "components/dom_distiller/core/dom_distiller_service.h" | 19 #include "components/dom_distiller/core/dom_distiller_service.h" |
19 #include "components/dom_distiller/core/dom_distiller_store.h" | 20 #include "components/dom_distiller/core/dom_distiller_store.h" |
20 #include "components/dom_distiller/core/dom_distiller_test_util.h" | 21 #include "components/dom_distiller/core/dom_distiller_test_util.h" |
21 #include "components/dom_distiller/core/fake_db.h" | 22 #include "components/dom_distiller/core/fake_db.h" |
22 #include "components/dom_distiller/core/fake_distiller.h" | 23 #include "components/dom_distiller/core/fake_distiller.h" |
23 #include "components/dom_distiller/core/task_tracker.h" | 24 #include "components/dom_distiller/core/task_tracker.h" |
| 25 #include "components/dom_distiller/core/url_constants.h" |
24 #include "content/public/browser/render_view_host.h" | 26 #include "content/public/browser/render_view_host.h" |
25 #include "content/public/browser/url_data_source.h" | 27 #include "content/public/browser/url_data_source.h" |
26 #include "content/public/browser/web_contents.h" | 28 #include "content/public/browser/web_contents.h" |
27 #include "content/public/browser/web_contents_observer.h" | 29 #include "content/public/browser/web_contents_observer.h" |
| 30 #include "net/base/escape.h" |
| 31 #include "net/base/url_util.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
29 | 33 |
30 namespace dom_distiller { | 34 namespace dom_distiller { |
31 | 35 |
32 using test::FakeDB; | 36 using test::FakeDB; |
33 using test::FakeDistiller; | 37 using test::FakeDistiller; |
34 using test::MockDistillerFactory; | 38 using test::MockDistillerFactory; |
35 using test::util::CreateStoreWithFakeDB; | 39 using test::util::CreateStoreWithFakeDB; |
36 | 40 |
37 namespace { | 41 namespace { |
38 | 42 |
39 void AddEntry(const ArticleEntry& e, FakeDB::EntryMap* map) { | 43 void AddEntry(const ArticleEntry& e, FakeDB::EntryMap* map) { |
40 (*map)[e.entry_id()] = e; | 44 (*map)[e.entry_id()] = e; |
41 } | 45 } |
42 | 46 |
43 ArticleEntry CreateEntry(std::string entry_id, std::string page_url) { | 47 ArticleEntry CreateEntry(std::string entry_id, std::string page_url) { |
44 ArticleEntry entry; | 48 ArticleEntry entry; |
45 entry.set_entry_id(entry_id); | 49 entry.set_entry_id(entry_id); |
46 if (!page_url.empty()) { | 50 if (!page_url.empty()) { |
47 ArticleEntryPage* page = entry.add_pages(); | 51 ArticleEntryPage* page = entry.add_pages(); |
48 page->set_url(page_url); | 52 page->set_url(page_url); |
49 } | 53 } |
50 return entry; | 54 return entry; |
51 } | 55 } |
52 | 56 |
| 57 const GURL GetDistillerViewUrlFromEntryId(const std::string& entry_id) { |
| 58 GURL url(std::string(chrome::kDomDistillerScheme) + "://" + |
| 59 base::GenerateGUID()); |
| 60 return net::AppendOrReplaceQueryParameter(url, kEntryIdKey, entry_id); |
| 61 } |
| 62 |
| 63 const GURL GetDistillerViewUrlFromUrl(const std::string& view_url) { |
| 64 GURL url(std::string(chrome::kDomDistillerScheme) + "://" + |
| 65 base::GenerateGUID()); |
| 66 return net::AppendOrReplaceQueryParameter(url, kUrlKey, view_url); |
| 67 } |
| 68 |
53 } // namespace | 69 } // namespace |
54 | 70 |
55 // WebContents observer that stores reference to the current |RenderViewHost|. | 71 // WebContents observer that stores reference to the current |RenderViewHost|. |
56 class LoadSuccessObserver : public content::WebContentsObserver { | 72 class LoadSuccessObserver : public content::WebContentsObserver { |
57 public: | 73 public: |
58 explicit LoadSuccessObserver(content::WebContents* contents) | 74 explicit LoadSuccessObserver(content::WebContents* contents) |
59 : content::WebContentsObserver(contents), | 75 : content::WebContentsObserver(contents), |
60 validated_url_(GURL()), | 76 validated_url_(GURL()), |
61 finished_load_(false), | 77 finished_load_(false), |
62 load_failed_(false), | 78 load_failed_(false), |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 if (expect_distillation_) { | 147 if (expect_distillation_) { |
132 // There will only be destillation of an article if the database contains | 148 // There will only be destillation of an article if the database contains |
133 // the article. | 149 // the article. |
134 FakeDistiller* distiller = new FakeDistiller(true); | 150 FakeDistiller* distiller = new FakeDistiller(true); |
135 EXPECT_CALL(*factory, CreateDistillerImpl()) | 151 EXPECT_CALL(*factory, CreateDistillerImpl()) |
136 .WillOnce(testing::Return(distiller)); | 152 .WillOnce(testing::Return(distiller)); |
137 } | 153 } |
138 return service; | 154 return service; |
139 } | 155 } |
140 | 156 |
141 void ViewSingleDistilledPage(); | 157 void ViewSingleDistilledPage(const GURL& url); |
142 | 158 |
143 // Database entries. | 159 // Database entries. |
144 static FakeDB::EntryMap* database_model_; | 160 static FakeDB::EntryMap* database_model_; |
145 static bool expect_distillation_; | 161 static bool expect_distillation_; |
146 }; | 162 }; |
147 | 163 |
148 FakeDB::EntryMap* DomDistillerViewerSourceBrowserTest::database_model_; | 164 FakeDB::EntryMap* DomDistillerViewerSourceBrowserTest::database_model_; |
149 bool DomDistillerViewerSourceBrowserTest::expect_distillation_ = false; | 165 bool DomDistillerViewerSourceBrowserTest::expect_distillation_ = false; |
150 | 166 |
151 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings | 167 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings |
152 // are enabled when the article exists in the database. | 168 // are enabled when the article exists in the database. |
153 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, | 169 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, |
154 NoWebUIBindingsArticleExists) { | 170 NoWebUIBindingsArticleExists) { |
155 // Ensure there is one item in the database, which will trigger distillation. | 171 // Ensure there is one item in the database, which will trigger distillation. |
156 ArticleEntry entry = CreateEntry("DISTILLED", "http://example.com/1"); | 172 const ArticleEntry entry = CreateEntry("DISTILLED", "http://example.com/1"); |
157 AddEntry(entry, database_model_); | 173 AddEntry(entry, database_model_); |
158 expect_distillation_ = true; | 174 expect_distillation_ = true; |
159 ViewSingleDistilledPage(); | 175 const GURL url = GetDistillerViewUrlFromEntryId(entry.entry_id()); |
| 176 ViewSingleDistilledPage(url); |
160 } | 177 } |
161 | 178 |
162 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings | 179 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings |
163 // are enabled when the article is not found. | 180 // are enabled when the article is not found. |
164 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, | 181 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, |
165 NoWebUIBindingsArticleNotFound) { | 182 NoWebUIBindingsArticleNotFound) { |
166 // The article does not exist, so assume no distillation will happen. | 183 // The article does not exist, so assume no distillation will happen. |
167 expect_distillation_ = false; | 184 expect_distillation_ = false; |
168 ViewSingleDistilledPage(); | 185 const GURL url(std::string(chrome::kDomDistillerScheme) + "://" + |
| 186 base::GenerateGUID() + "/"); |
| 187 ViewSingleDistilledPage(url); |
169 } | 188 } |
170 | 189 |
171 void DomDistillerViewerSourceBrowserTest::ViewSingleDistilledPage() { | 190 // The DomDistillerViewerSource renders untrusted content, so ensure no bindings |
| 191 // are enabled when requesting to view an arbitrary URL. |
| 192 IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, |
| 193 NoWebUIBindingsViewUrl) { |
| 194 // We should expect distillation for any valid URL. |
| 195 expect_distillation_ = true; |
| 196 std::string view_url = "http://www.example.com/1"; |
| 197 const GURL url = GetDistillerViewUrlFromUrl(view_url); |
| 198 ViewSingleDistilledPage(url); |
| 199 } |
| 200 |
| 201 void DomDistillerViewerSourceBrowserTest::ViewSingleDistilledPage( |
| 202 const GURL& url) { |
172 // Create the service. | 203 // Create the service. |
173 DomDistillerContextKeyedService* service = | 204 DomDistillerContextKeyedService* service = |
174 static_cast<DomDistillerContextKeyedService*>( | 205 static_cast<DomDistillerContextKeyedService*>( |
175 dom_distiller::DomDistillerServiceFactory::GetInstance() | 206 dom_distiller::DomDistillerServiceFactory::GetInstance() |
176 ->SetTestingFactoryAndUse(browser()->profile(), &Build)); | 207 ->SetTestingFactoryAndUse(browser()->profile(), &Build)); |
177 | 208 |
178 // Ensure the source is registered. | 209 // Ensure the source is registered. |
179 // TODO(nyquist): Remove when the source is always registered on startup. | 210 // TODO(nyquist): Remove when the source is always registered on startup. |
180 DomDistillerViewerSource* source = | 211 DomDistillerViewerSource* source = |
181 new DomDistillerViewerSource(service, chrome::kDomDistillerScheme); | 212 new DomDistillerViewerSource(service, chrome::kDomDistillerScheme); |
182 content::URLDataSource::Add(browser()->profile(), source); | 213 content::URLDataSource::Add(browser()->profile(), source); |
183 | 214 |
184 // Setup observer to inspect the RenderViewHost after committed navigation. | 215 // Setup observer to inspect the RenderViewHost after committed navigation. |
185 content::WebContents* contents = | 216 content::WebContents* contents = |
186 browser()->tab_strip_model()->GetActiveWebContents(); | 217 browser()->tab_strip_model()->GetActiveWebContents(); |
187 LoadSuccessObserver observer(contents); | 218 LoadSuccessObserver observer(contents); |
188 | 219 |
189 // Navigate to a URL which the source should respond to. | 220 // Navigate to a URL which the source should respond to. |
190 std::string url_without_scheme = "://distilled"; | |
191 GURL url(chrome::kDomDistillerScheme + url_without_scheme); | |
192 ui_test_utils::NavigateToURL(browser(), url); | 221 ui_test_utils::NavigateToURL(browser(), url); |
193 | 222 |
194 // A navigation should have succeeded to the correct URL. | 223 // A navigation should have succeeded to the correct URL. |
195 ASSERT_FALSE(observer.load_failed()); | 224 ASSERT_FALSE(observer.load_failed()); |
196 ASSERT_TRUE(observer.finished_load()); | 225 ASSERT_TRUE(observer.finished_load()); |
197 ASSERT_EQ(url, observer.validated_url()); | 226 ASSERT_EQ(url, observer.validated_url()); |
198 // Ensure no bindings. | 227 // Ensure no bindings. |
199 const content::RenderViewHost* render_view_host = observer.render_view_host(); | 228 const content::RenderViewHost* render_view_host = observer.render_view_host(); |
200 ASSERT_EQ(0, render_view_host->GetEnabledBindings()); | 229 ASSERT_EQ(0, render_view_host->GetEnabledBindings()); |
201 // The MIME-type should always be text/html for the distilled articles. | 230 // The MIME-type should always be text/html for the distilled articles. |
(...skipping 26 matching lines...) Expand all Loading... |
228 ASSERT_TRUE(observer.finished_load()); | 257 ASSERT_TRUE(observer.finished_load()); |
229 ASSERT_EQ(url, observer.validated_url()); | 258 ASSERT_EQ(url, observer.validated_url()); |
230 // Ensure no bindings. | 259 // Ensure no bindings. |
231 const content::RenderViewHost* render_view_host = observer.render_view_host(); | 260 const content::RenderViewHost* render_view_host = observer.render_view_host(); |
232 ASSERT_EQ(0, render_view_host->GetEnabledBindings()); | 261 ASSERT_EQ(0, render_view_host->GetEnabledBindings()); |
233 // The MIME-type should always be text/css for the CSS resources. | 262 // The MIME-type should always be text/css for the CSS resources. |
234 EXPECT_EQ("text/css", observer.web_contents()->GetContentsMimeType()); | 263 EXPECT_EQ("text/css", observer.web_contents()->GetContentsMimeType()); |
235 } | 264 } |
236 | 265 |
237 } // namespace dom_distiller | 266 } // namespace dom_distiller |
OLD | NEW |