| 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 |