blob: 8b66340a212c706bffe5e54d7b80dccbcc96c2ec [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_service.h"
#include "chrome/browser/download/download_service_factory.h"
#include "chrome/browser/net/url_request_mock_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/webui/active_downloads_ui.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/download/download_item.h"
#include "content/browser/download/download_manager.h"
#include "content/browser/download/download_persistent_store_info.h"
#include "content/browser/net/url_request_mock_http_job.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "testing/gtest/include/gtest/gtest.h"
using content::BrowserThread;
namespace {
static const FilePath::CharType* kTestDir = FILE_PATH_LITERAL("save_page");
static const char* kAppendedExtension =
#if defined(OS_WIN)
".htm";
#else
".html";
#endif
class SavePageBrowserTest : public InProcessBrowserTest {
protected:
void SetUp() OVERRIDE {
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir_));
ASSERT_TRUE(save_dir_.CreateUniqueTempDir());
InProcessBrowserTest::SetUp();
}
void SetUpOnMainThread() OVERRIDE {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
}
GURL NavigateToMockURL(const std::string& prefix) {
GURL url = URLRequestMockHTTPJob::GetMockUrl(
FilePath(kTestDir).AppendASCII(prefix + ".htm"));
ui_test_utils::NavigateToURL(browser(), url);
return url;
}
// Returns full paths of destination file and directory.
void GetDestinationPaths(const std::string& prefix,
FilePath* full_file_name,
FilePath* dir) {
*full_file_name = save_dir_.path().AppendASCII(prefix + ".htm");
*dir = save_dir_.path().AppendASCII(prefix + "_files");
}
TabContents* GetCurrentTab() const {
TabContents* current_tab = browser()->GetSelectedTabContents();
EXPECT_TRUE(current_tab);
return current_tab;
}
GURL WaitForSavePackageToFinish() const {
ui_test_utils::TestNotificationObserver observer;
ui_test_utils::RegisterAndWait(&observer,
content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
content::NotificationService::AllSources());
return content::Details<DownloadItem>(observer.details()).ptr()->
GetOriginalUrl();
}
#if defined(OS_CHROMEOS) && defined(TOUCH_UI)
const ActiveDownloadsUI::DownloadList& GetDownloads() const {
TabContents* download_contents = ActiveDownloadsUI::GetPopup(NULL);
ActiveDownloadsUI* downloads_ui = static_cast<ActiveDownloadsUI*>(
download_contents->web_ui());
EXPECT_TRUE(downloads_ui);
return downloads_ui->GetDownloads();
}
#elif defined(OS_CHROMEOS) && !defined(USE_AURA)
const ActiveDownloadsUI::DownloadList& GetDownloads() const {
Browser* popup = ActiveDownloadsUI::GetPopup();
EXPECT_TRUE(popup);
ActiveDownloadsUI* downloads_ui = static_cast<ActiveDownloadsUI*>(
popup->GetSelectedTabContents()->web_ui());
EXPECT_TRUE(downloads_ui);
return downloads_ui->GetDownloads();
}
#endif
void CheckDownloadUI(const FilePath& download_path) const {
#if defined(OS_CHROMEOS) && !defined(USE_AURA)
const ActiveDownloadsUI::DownloadList& downloads = GetDownloads();
EXPECT_EQ(downloads.size(), 1U);
bool found = false;
for (size_t i = 0; i < downloads.size(); ++i) {
if (downloads[i]->GetFullPath() == download_path) {
found = true;
break;
}
}
EXPECT_TRUE(found);
#else
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
#endif
}
DownloadManager* GetDownloadManager() const {
DownloadManager* download_manager =
DownloadServiceFactory::GetForProfile(
browser()->profile())->GetDownloadManager();
EXPECT_TRUE(download_manager);
return download_manager;
}
void QueryDownloadHistory() {
// Query the history system.
ChromeDownloadManagerDelegate* delegate =
static_cast<ChromeDownloadManagerDelegate*>(
GetDownloadManager()->delegate());
delegate->download_history()->Load(
base::Bind(&SavePageBrowserTest::OnQueryDownloadEntriesComplete,
base::Unretained(this)));
// Run message loop until a quit message is sent from
// OnQueryDownloadEntriesComplete().
ui_test_utils::RunMessageLoop();
}
void OnQueryDownloadEntriesComplete(
std::vector<DownloadPersistentStoreInfo>* entries) {
history_entries_ = *entries;
// Indicate thet we have received the history and can continue.
MessageLoopForUI::current()->Quit();
}
struct DownloadPersistentStoreInfoMatch
: public std::unary_function<DownloadPersistentStoreInfo, bool> {
DownloadPersistentStoreInfoMatch(const GURL& url,
const FilePath& path,
int64 num_files)
: url_(url),
path_(path),
num_files_(num_files) {
}
bool operator() (const DownloadPersistentStoreInfo& info) const {
return info.url == url_ &&
info.path == path_ &&
// For save packages, received bytes is actually the number of files.
info.received_bytes == num_files_ &&
info.total_bytes == 0 &&
info.state == DownloadItem::COMPLETE;
}
GURL url_;
FilePath path_;
int64 num_files_;
};
void CheckDownloadHistory(const GURL& url,
const FilePath& path,
int64 num_files_) {
QueryDownloadHistory();
EXPECT_NE(std::find_if(history_entries_.begin(), history_entries_.end(),
DownloadPersistentStoreInfoMatch(url, path, num_files_)),
history_entries_.end());
}
std::vector<DownloadPersistentStoreInfo> history_entries_;
// Path to directory containing test data.
FilePath test_dir_;
// Temporary directory we will save pages to.
ScopedTempDir save_dir_;
};
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveHTMLOnly) {
GURL url = NavigateToMockURL("a");
FilePath full_file_name, dir;
GetDestinationPaths("a", &full_file_name, &dir);
ASSERT_TRUE(GetCurrentTab()->SavePage(full_file_name, dir,
SavePackage::SAVE_AS_ONLY_HTML));
EXPECT_EQ(url, WaitForSavePackageToFinish());
CheckDownloadUI(full_file_name);
CheckDownloadHistory(url, full_file_name, 1); // a.htm is 1 file.
EXPECT_TRUE(file_util::PathExists(full_file_name));
EXPECT_FALSE(file_util::PathExists(dir));
EXPECT_TRUE(file_util::ContentsEqual(
test_dir_.Append(FilePath(kTestDir)).Append(FILE_PATH_LITERAL("a.htm")),
full_file_name));
}
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveViewSourceHTMLOnly) {
FilePath file_name(FILE_PATH_LITERAL("a.htm"));
GURL view_source_url = URLRequestMockHTTPJob::GetMockViewSourceUrl(
FilePath(kTestDir).Append(file_name));
GURL actual_page_url = URLRequestMockHTTPJob::GetMockUrl(
FilePath(kTestDir).Append(file_name));
ui_test_utils::NavigateToURL(browser(), view_source_url);
FilePath full_file_name, dir;
GetDestinationPaths("a", &full_file_name, &dir);
ASSERT_TRUE(GetCurrentTab()->SavePage(full_file_name, dir,
SavePackage::SAVE_AS_ONLY_HTML));
EXPECT_EQ(actual_page_url, WaitForSavePackageToFinish());
CheckDownloadUI(full_file_name);
CheckDownloadHistory(actual_page_url, full_file_name, 1); // a.htm is 1 file.
EXPECT_TRUE(file_util::PathExists(full_file_name));
EXPECT_FALSE(file_util::PathExists(dir));
EXPECT_TRUE(file_util::ContentsEqual(
test_dir_.Append(FilePath(kTestDir)).Append(file_name),
full_file_name));
}
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveCompleteHTML) {
GURL url = NavigateToMockURL("b");
FilePath full_file_name, dir;
GetDestinationPaths("b", &full_file_name, &dir);
ASSERT_TRUE(GetCurrentTab()->SavePage(full_file_name, dir,
SavePackage::SAVE_AS_COMPLETE_HTML));
EXPECT_EQ(url, WaitForSavePackageToFinish());
CheckDownloadUI(full_file_name);
CheckDownloadHistory(url, full_file_name, 3); // b.htm is 3 files.
EXPECT_TRUE(file_util::PathExists(full_file_name));
EXPECT_TRUE(file_util::PathExists(dir));
EXPECT_TRUE(file_util::TextContentsEqual(
test_dir_.Append(FilePath(kTestDir)).AppendASCII("b.saved1.htm"),
full_file_name));
EXPECT_TRUE(file_util::ContentsEqual(
test_dir_.Append(FilePath(kTestDir)).AppendASCII("1.png"),
dir.AppendASCII("1.png")));
EXPECT_TRUE(file_util::ContentsEqual(
test_dir_.Append(FilePath(kTestDir)).AppendASCII("1.css"),
dir.AppendASCII("1.css")));
}
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, NoSave) {
ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
ASSERT_TRUE(browser()->command_updater()->SupportsCommand(IDC_SAVE_PAGE));
EXPECT_FALSE(browser()->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE));
}
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, FileNameFromPageTitle) {
GURL url = NavigateToMockURL("b");
FilePath full_file_name = save_dir_.path().AppendASCII(
std::string("Test page for saving page feature") + kAppendedExtension);
FilePath dir = save_dir_.path().AppendASCII(
"Test page for saving page feature_files");
ASSERT_TRUE(GetCurrentTab()->SavePage(full_file_name, dir,
SavePackage::SAVE_AS_COMPLETE_HTML));
EXPECT_EQ(url, WaitForSavePackageToFinish());
CheckDownloadUI(full_file_name);
CheckDownloadHistory(url, full_file_name, 3); // b.htm is 3 files.
EXPECT_TRUE(file_util::PathExists(full_file_name));
EXPECT_TRUE(file_util::PathExists(dir));
EXPECT_TRUE(file_util::TextContentsEqual(
test_dir_.Append(FilePath(kTestDir)).AppendASCII("b.saved2.htm"),
full_file_name));
EXPECT_TRUE(file_util::ContentsEqual(
test_dir_.Append(FilePath(kTestDir)).AppendASCII("1.png"),
dir.AppendASCII("1.png")));
EXPECT_TRUE(file_util::ContentsEqual(
test_dir_.Append(FilePath(kTestDir)).AppendASCII("1.css"),
dir.AppendASCII("1.css")));
}
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, RemoveFromList) {
GURL url = NavigateToMockURL("a");
FilePath full_file_name, dir;
GetDestinationPaths("a", &full_file_name, &dir);
ASSERT_TRUE(GetCurrentTab()->SavePage(full_file_name, dir,
SavePackage::SAVE_AS_ONLY_HTML));
EXPECT_EQ(url, WaitForSavePackageToFinish());
CheckDownloadUI(full_file_name);
CheckDownloadHistory(url, full_file_name, 1); // a.htm is 1 file.
EXPECT_EQ(GetDownloadManager()->RemoveAllDownloads(), 1);
#if defined(OS_CHROMEOS) && !defined(USE_AURA)
EXPECT_EQ(GetDownloads().size(), 0U);
#endif
// Should not be in history.
QueryDownloadHistory();
EXPECT_EQ(std::find_if(history_entries_.begin(), history_entries_.end(),
DownloadPersistentStoreInfoMatch(url, full_file_name, 1)),
history_entries_.end());
EXPECT_TRUE(file_util::PathExists(full_file_name));
EXPECT_FALSE(file_util::PathExists(dir));
EXPECT_TRUE(file_util::ContentsEqual(
test_dir_.Append(FilePath(kTestDir)).Append(FILE_PATH_LITERAL("a.htm")),
full_file_name));
}
// Create a SavePackage and delete it without calling Init.
// SavePackage dtor has various asserts/checks that should not fire.
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, ImplicitCancel) {
GURL url = NavigateToMockURL("a");
FilePath full_file_name, dir;
GetDestinationPaths("a", &full_file_name, &dir);
scoped_refptr<SavePackage> save_package(new SavePackage(GetCurrentTab(),
SavePackage::SAVE_AS_ONLY_HTML, full_file_name, dir));
}
// Create a SavePackage, call Cancel, then delete it.
// SavePackage dtor has various asserts/checks that should not fire.
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, ExplicitCancel) {
GURL url = NavigateToMockURL("a");
FilePath full_file_name, dir;
GetDestinationPaths("a", &full_file_name, &dir);
scoped_refptr<SavePackage> save_package(new SavePackage(GetCurrentTab(),
SavePackage::SAVE_AS_ONLY_HTML, full_file_name, dir));
save_package->Cancel(true);
}
} // namespace