15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string.h> 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/command_line.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/guid.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/path_service.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/dom_distiller/content/dom_distiller_viewer_source.h" 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/dom_distiller/core/article_entry.h" 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/dom_distiller/core/distilled_page_prefs.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/dom_distiller/core/distiller.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/dom_distiller/core/dom_distiller_service.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/dom_distiller/core/dom_distiller_store.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/dom_distiller/core/dom_distiller_test_util.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/dom_distiller/core/fake_distiller.h" 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/dom_distiller/core/fake_distiller_page.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/dom_distiller/core/task_tracker.h" 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/dom_distiller/core/url_constants.h" 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/dom_distiller/core/url_utils.h" 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/leveldb_proto/testing/fake_db.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/url_data_source.h" 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/web_contents.h" 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/web_contents_observer.h" 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/test/browser_test_utils.h" 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace dom_distiller { 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using leveldb_proto::test::FakeDB; 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using test::FakeDistiller; 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using test::MockDistillerPage; 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using test::MockDistillerFactory; 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using test::MockDistillerPageFactory; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using test::util::CreateStoreWithFakeDB; 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using testing::HasSubstr; 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using testing::Not; 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kGetLoadIndicatorClassName[] = 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "window.domAutomationController.send(" 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "document.getElementById('loadingIndicator').className)"; 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kGetContent[] = 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "window.domAutomationController.send(" 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "document.getElementById('content').innerHTML)"; 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kGetBodyClass[] = 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "window.domAutomationController.send(" 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "document.body.className)"; 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AddEntry(const ArticleEntry& e, FakeDB<ArticleEntry>::EntryMap* map) { 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*map)[e.entry_id()] = e; 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ArticleEntry CreateEntry(std::string entry_id, std::string page_url) { 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ArticleEntry entry; 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry.set_entry_id(entry_id); 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!page_url.empty()) { 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ArticleEntryPage* page = entry.add_pages(); 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) page->set_url(page_url); 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return entry; 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DomDistillerViewerSourceBrowserTest : public InProcessBrowserTest { 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DomDistillerViewerSourceBrowserTest() {} 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~DomDistillerViewerSourceBrowserTest() {} 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void SetUpOnMainThread() OVERRIDE { 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) database_model_ = new FakeDB<ArticleEntry>::EntryMap; 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void TearDownOnMainThread() OVERRIDE { delete database_model_; } 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) command_line->AppendSwitch(switches::kEnableDomDistiller); 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static KeyedService* Build(content::BrowserContext* context) { 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FakeDB<ArticleEntry>* fake_db = new FakeDB<ArticleEntry>(database_model_); 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) distiller_factory_ = new MockDistillerFactory(); 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockDistillerPageFactory* distiller_page_factory_ = 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new MockDistillerPageFactory(); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DomDistillerContextKeyedService* service = 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new DomDistillerContextKeyedService( 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<DomDistillerStoreInterface>( 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateStoreWithFakeDB(fake_db, 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FakeDB<ArticleEntry>::EntryMap())), 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<DistillerFactory>(distiller_factory_), 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<DistillerPageFactory>(distiller_page_factory_), 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<DistilledPagePrefs>( 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new DistilledPagePrefs( 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Profile::FromBrowserContext( 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch context)->GetPrefs()))); 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fake_db->InitCallback(true); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fake_db->LoadCallback(true); 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (expect_distillation_) { 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There will only be destillation of an article if the database contains 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the article. 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FakeDistiller* distiller = new FakeDistiller(true); 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .WillOnce(testing::Return(distiller)); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (expect_distiller_page_) { 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockDistillerPage* distiller_page = new MockDistillerPage(); 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(*distiller_page_factory_, CreateDistillerPageImpl()) 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(testing::Return(distiller_page)); 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return service; 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void ViewSingleDistilledPage(const GURL& url, 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& expected_mime_type); 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Database entries. 131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static FakeDB<ArticleEntry>::EntryMap* database_model_; 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static bool expect_distillation_; 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static bool expect_distiller_page_; 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static MockDistillerFactory* distiller_factory_; 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)FakeDB<ArticleEntry>::EntryMap* 138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DomDistillerViewerSourceBrowserTest::database_model_; 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool DomDistillerViewerSourceBrowserTest::expect_distillation_ = false; 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool DomDistillerViewerSourceBrowserTest::expect_distiller_page_ = false; 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MockDistillerFactory* DomDistillerViewerSourceBrowserTest::distiller_factory_ = 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NULL; 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The DomDistillerViewerSource renders untrusted content, so ensure no bindings 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// are enabled when the article exists in the database. 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NoWebUIBindingsArticleExists) { 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ensure there is one item in the database, which will trigger distillation. 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ArticleEntry entry = CreateEntry("DISTILLED", "http://example.com/1"); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddEntry(entry, database_model_); 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) expect_distillation_ = true; 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distiller_page_ = true; 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const GURL url = url_utils::GetDistillerViewUrlFromEntryId( 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kDomDistillerScheme, entry.entry_id()); 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ViewSingleDistilledPage(url, "text/html"); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The DomDistillerViewerSource renders untrusted content, so ensure no bindings 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// are enabled when the article is not found. 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NoWebUIBindingsArticleNotFound) { 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The article does not exist, so assume no distillation will happen. 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) expect_distillation_ = false; 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distiller_page_ = false; 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL url = url_utils::GetDistillerViewUrlFromEntryId( 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kDomDistillerScheme, "DOES_NOT_EXIST"); 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ViewSingleDistilledPage(url, "text/html"); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The DomDistillerViewerSource renders untrusted content, so ensure no bindings 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// are enabled when requesting to view an arbitrary URL. 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NoWebUIBindingsViewUrl) { 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We should expect distillation for any valid URL. 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) expect_distillation_ = true; 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distiller_page_ = true; 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL view_url("http://www.example.com/1"); 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL url = 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) url_utils::GetDistillerViewUrlFromUrl(kDomDistillerScheme, view_url); 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ViewSingleDistilledPage(url, "text/html"); 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DomDistillerViewerSourceBrowserTest::ViewSingleDistilledPage( 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& url, 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& expected_mime_type) { 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Ensure the correct factory is used for the DomDistillerService. 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dom_distiller::DomDistillerServiceFactory::GetInstance() 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ->SetTestingFactoryAndUse(browser()->profile(), &Build); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Navigate to a URL which the source should respond to. 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui_test_utils::NavigateToURL(browser(), url); 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Ensure no bindings for the loaded |url|. 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::WebContents* contents_after_nav = 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(); 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(contents_after_nav != NULL); 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(url, contents_after_nav->GetLastCommittedURL()); 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const content::RenderViewHost* render_view_host = 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) contents_after_nav->GetRenderViewHost(); 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0, render_view_host->GetEnabledBindings()); 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(expected_mime_type, contents_after_nav->GetContentsMimeType()); 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The DomDistillerViewerSource renders untrusted content, so ensure no bindings 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// are enabled when the CSS resource is loaded. This CSS might be bundle with 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Chrome or provided by an extension. 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NoWebUIBindingsDisplayCSS) { 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distillation_ = false; 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distiller_page_ = false; 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Navigate to a URL which the source should respond to with CSS. 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string url_without_scheme = std::string("://foobar/") + kViewerCssPath; 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GURL url(kDomDistillerScheme + url_without_scheme); 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ViewSingleDistilledPage(url, "text/css"); 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EmptyURLShouldNotCrash) { 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // This is a bogus URL, so no distillation will happen. 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distillation_ = false; 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distiller_page_ = false; 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL url(std::string(kDomDistillerScheme) + "://bogus/"); 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ViewSingleDistilledPage(url, "text/html"); 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) InvalidURLShouldNotCrash) { 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // This is a bogus URL, so no distillation will happen. 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distillation_ = false; 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distiller_page_ = false; 2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL url(std::string(kDomDistillerScheme) + "://bogus/foobar"); 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ViewSingleDistilledPage(url, "text/html"); 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MultiPageArticle) { 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distillation_ = false; 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) expect_distiller_page_ = true; 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dom_distiller::DomDistillerServiceFactory::GetInstance() 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ->SetTestingFactoryAndUse(browser()->profile(), &Build); 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<content::MessageLoopRunner> distillation_done_runner = 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new content::MessageLoopRunner; 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FakeDistiller* distiller = new FakeDistiller( 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) false, 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) distillation_done_runner->QuitClosure()); 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(testing::Return(distiller)); 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Setup observer to inspect the RenderViewHost after committed navigation. 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::WebContents* contents = 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(); 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Navigate to a URL and wait for the distiller to flush contents to the page. 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GURL url(dom_distiller::url_utils::GetDistillerViewUrlFromUrl( 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kDomDistillerScheme, GURL("http://urlthatlooksvalid.com"))); 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_TYPED); 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome::Navigate(¶ms); 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) distillation_done_runner->Run(); 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Fake a multi-page response from distiller. 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<scoped_refptr<ArticleDistillationUpdate::RefCountedPageProto> > 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) update_pages; 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<DistilledArticleProto> article(new DistilledArticleProto()); 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Flush page 1. 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) { 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::RefCountedData<DistilledPageProto> > page_proto = 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new base::RefCountedData<DistilledPageProto>(); 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) page_proto->data.set_url("http://foobar.1.html"); 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) page_proto->data.set_html("<div>Page 1 content</div>"); 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) update_pages.push_back(page_proto); 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *(article->add_pages()) = page_proto->data; 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ArticleDistillationUpdate update(update_pages, true, false); 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) distiller->RunDistillerUpdateCallback(update); 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Wait for the page load to complete as the first page completes the root 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // document. 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::WaitForLoadStop(contents); 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string result; 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(content::ExecuteScriptAndExtractString( 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) contents, kGetLoadIndicatorClassName , &result)); 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ("visible", result); 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(content::ExecuteScriptAndExtractString( 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) contents, kGetContent , &result)); 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_THAT(result, HasSubstr("Page 1 content")); 292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_THAT(result, Not(HasSubstr("Page 2 content"))); 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Flush page 2. 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) { 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::RefCountedData<DistilledPageProto> > page_proto = 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new base::RefCountedData<DistilledPageProto>(); 299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) page_proto->data.set_url("http://foobar.2.html"); 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) page_proto->data.set_html("<div>Page 2 content</div>"); 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) update_pages.push_back(page_proto); 302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *(article->add_pages()) = page_proto->data; 303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ArticleDistillationUpdate update(update_pages, false, false); 305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) distiller->RunDistillerUpdateCallback(update); 306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string result; 308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(content::ExecuteScriptAndExtractString( 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) contents, kGetLoadIndicatorClassName , &result)); 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ("visible", result); 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(content::ExecuteScriptAndExtractString( 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) contents, kGetContent , &result)); 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_THAT(result, HasSubstr("Page 1 content")); 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_THAT(result, HasSubstr("Page 2 content")); 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Complete the load. 319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) distiller->RunDistillerCallback(article.Pass()); 320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string result; 323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(content::ExecuteScriptAndExtractString( 324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) contents, kGetLoadIndicatorClassName, &result)); 325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ("hidden", result); 326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(content::ExecuteScriptAndExtractString( 327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) contents, kGetContent , &result)); 328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_THAT(result, HasSubstr("Page 1 content")); 329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_THAT(result, HasSubstr("Page 2 content")); 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 332116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, PrefChange) { 333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch expect_distillation_ = true; 334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch expect_distiller_page_ = true; 335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GURL view_url("http://www.example.com/1"); 336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::WebContents* contents = 337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch browser()->tab_strip_model()->GetActiveWebContents(); 3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL url = 3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) url_utils::GetDistillerViewUrlFromUrl(kDomDistillerScheme, view_url); 340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ViewSingleDistilledPage(url, "text/html"); 341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::WaitForLoadStop(contents); 342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string result; 343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(content::ExecuteScriptAndExtractString( 344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch contents, kGetBodyClass, &result)); 3456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ("light sans-serif", result); 346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DistilledPagePrefs* distilled_page_prefs = 348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DomDistillerServiceFactory::GetForBrowserContext( 349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch browser()->profile())->GetDistilledPagePrefs(); 350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch distilled_page_prefs->SetTheme(DistilledPagePrefs::DARK); 352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::RunLoop().RunUntilIdle(); 353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(content::ExecuteScriptAndExtractString( 354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch contents, kGetBodyClass, &result)); 3556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ("dark sans-serif", result); 3566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) distilled_page_prefs->SetFontFamily(DistilledPagePrefs::SERIF); 3586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 3596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE( 3606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) content::ExecuteScriptAndExtractString(contents, kGetBodyClass, &result)); 3616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ("dark serif", result); 362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace dom_distiller 365