- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / download / save_page_browsertest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/files/file_path.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/path_service.h"
12 #include "base/prefs/pref_member.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/test/test_file_util.h"
15 #include "chrome/app/chrome_command_ids.h"
16 #include "chrome/browser/download/chrome_download_manager_delegate.h"
17 #include "chrome/browser/download/download_history.h"
18 #include "chrome/browser/download/download_prefs.h"
19 #include "chrome/browser/download/download_service.h"
20 #include "chrome/browser/download/download_service_factory.h"
21 #include "chrome/browser/download/save_package_file_picker.h"
22 #include "chrome/browser/history/download_row.h"
23 #include "chrome/browser/net/url_request_mock_util.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/browser_commands.h"
27 #include "chrome/browser/ui/browser_window.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
29 #include "chrome/common/chrome_paths.h"
30 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/common/url_constants.h"
33 #include "chrome/test/base/in_process_browser_test.h"
34 #include "chrome/test/base/ui_test_utils.h"
35 #include "content/public/browser/download_item.h"
36 #include "content/public/browser/download_manager.h"
37 #include "content/public/browser/notification_service.h"
38 #include "content/public/browser/notification_types.h"
39 #include "content/public/browser/web_contents.h"
40 #include "content/public/test/test_utils.h"
41 #include "content/test/net/url_request_mock_http_job.h"
42 #include "testing/gtest/include/gtest/gtest.h"
43
44 using content::BrowserContext;
45 using content::BrowserThread;
46 using content::DownloadItem;
47 using content::DownloadManager;
48 using content::URLRequestMockHTTPJob;
49 using content::WebContents;
50
51 namespace {
52
53 // Waits for an item record in the downloads database to match |filter|. See
54 // DownloadStoredProperly() below for an example filter.
55 class DownloadPersistedObserver : public DownloadHistory::Observer {
56  public:
57   typedef base::Callback<bool(
58       DownloadItem* item,
59       const history::DownloadRow&)> PersistedFilter;
60
61   DownloadPersistedObserver(Profile* profile, const PersistedFilter& filter)
62     : profile_(profile),
63       filter_(filter),
64       waiting_(false),
65       persisted_(false) {
66     DownloadServiceFactory::GetForBrowserContext(profile_)->
67       GetDownloadHistory()->AddObserver(this);
68   }
69
70   virtual ~DownloadPersistedObserver() {
71     DownloadService* service = DownloadServiceFactory::GetForBrowserContext(
72         profile_);
73     if (service && service->GetDownloadHistory())
74       service->GetDownloadHistory()->RemoveObserver(this);
75   }
76
77   bool WaitForPersisted() {
78     if (persisted_)
79       return true;
80     waiting_ = true;
81     content::RunMessageLoop();
82     waiting_ = false;
83     return persisted_;
84   }
85
86   virtual void OnDownloadStored(DownloadItem* item,
87                                 const history::DownloadRow& info) OVERRIDE {
88     persisted_ = persisted_ || filter_.Run(item, info);
89     if (persisted_ && waiting_)
90       base::MessageLoopForUI::current()->Quit();
91   }
92
93  private:
94   Profile* profile_;
95   DownloadItem* item_;
96   PersistedFilter filter_;
97   bool waiting_;
98   bool persisted_;
99
100   DISALLOW_COPY_AND_ASSIGN(DownloadPersistedObserver);
101 };
102
103 // Waits for an item record to be removed from the downloads database.
104 class DownloadRemovedObserver : public DownloadPersistedObserver {
105  public:
106   DownloadRemovedObserver(Profile* profile, int32 download_id)
107       : DownloadPersistedObserver(profile, PersistedFilter()),
108         removed_(false),
109         waiting_(false),
110         download_id_(download_id) {
111   }
112   virtual ~DownloadRemovedObserver() {}
113
114   bool WaitForRemoved() {
115     if (removed_)
116       return true;
117     waiting_ = true;
118     content::RunMessageLoop();
119     waiting_ = false;
120     return removed_;
121   }
122
123   virtual void OnDownloadStored(DownloadItem* item,
124                                 const history::DownloadRow& info) OVERRIDE {
125   }
126
127   virtual void OnDownloadsRemoved(const DownloadHistory::IdSet& ids) OVERRIDE {
128     removed_ = ids.find(download_id_) != ids.end();
129     if (removed_ && waiting_)
130       base::MessageLoopForUI::current()->Quit();
131   }
132
133  private:
134   bool removed_;
135   bool waiting_;
136   int32 download_id_;
137
138   DISALLOW_COPY_AND_ASSIGN(DownloadRemovedObserver);
139 };
140
141 bool DownloadStoredProperly(
142     const GURL& expected_url,
143     const base::FilePath& expected_path,
144     int64 num_files,
145     DownloadItem::DownloadState expected_state,
146     DownloadItem* item,
147     const history::DownloadRow& info) {
148   // This function may be called multiple times for a given test. Returning
149   // false doesn't necessarily mean that the test has failed or will fail, it
150   // might just mean that the test hasn't passed yet.
151   if (info.target_path != expected_path) {
152     VLOG(20) << __FUNCTION__ << " " << info.target_path.value()
153              << " != " << expected_path.value();
154     return false;
155   }
156   if (info.url_chain.size() != 1u) {
157     VLOG(20) << __FUNCTION__ << " " << info.url_chain.size()
158              << " != 1";
159     return false;
160   }
161   if (info.url_chain[0] != expected_url) {
162     VLOG(20) << __FUNCTION__ << " " << info.url_chain[0].spec()
163              << " != " << expected_url.spec();
164     return false;
165   }
166   if ((num_files >= 0) && (info.received_bytes != num_files)) {
167     VLOG(20) << __FUNCTION__ << " " << num_files
168              << " != " << info.received_bytes;
169     return false;
170   }
171   if (info.state != expected_state) {
172     VLOG(20) << __FUNCTION__ << " " << info.state
173              << " != " << expected_state;
174     return false;
175   }
176   return true;
177 }
178
179 const base::FilePath::CharType kTestDir[] = FILE_PATH_LITERAL("save_page");
180
181 static const char kAppendedExtension[] =
182 #if defined(OS_WIN)
183     ".htm";
184 #else
185     ".html";
186 #endif
187
188 // Loosely based on logic in DownloadTestObserver.
189 class DownloadItemCreatedObserver : public DownloadManager::Observer {
190  public:
191   explicit DownloadItemCreatedObserver(DownloadManager* manager)
192       : waiting_(false), manager_(manager) {
193     manager->AddObserver(this);
194   }
195
196   virtual ~DownloadItemCreatedObserver() {
197     if (manager_)
198       manager_->RemoveObserver(this);
199   }
200
201   // Wait for the first download item created after object creation.
202   // Note that this class provides no protection against the download
203   // being destroyed between creation and return of WaitForNewDownloadItem();
204   // the caller must guarantee that in some other fashion.
205   void WaitForDownloadItem(std::vector<DownloadItem*>* items_seen) {
206     if (!manager_) {
207       // The manager went away before we were asked to wait; return
208       // what we have, even if it's null.
209       *items_seen = items_seen_;
210       return;
211     }
212
213     if (items_seen_.empty()) {
214       waiting_ = true;
215       content::RunMessageLoop();
216       waiting_ = false;
217     }
218
219     *items_seen = items_seen_;
220     return;
221   }
222
223  private:
224   // DownloadManager::Observer
225   virtual void OnDownloadCreated(
226       DownloadManager* manager, DownloadItem* item) OVERRIDE {
227     DCHECK_EQ(manager, manager_);
228     items_seen_.push_back(item);
229
230     if (waiting_)
231       base::MessageLoopForUI::current()->Quit();
232   }
233
234   virtual void ManagerGoingDown(DownloadManager* manager) OVERRIDE {
235     manager_->RemoveObserver(this);
236     manager_ = NULL;
237     if (waiting_)
238       base::MessageLoopForUI::current()->Quit();
239   }
240
241   bool waiting_;
242   DownloadManager* manager_;
243   std::vector<DownloadItem*> items_seen_;
244
245   DISALLOW_COPY_AND_ASSIGN(DownloadItemCreatedObserver);
246 };
247
248 class SavePackageFinishedObserver : public content::DownloadManager::Observer {
249  public:
250   SavePackageFinishedObserver(content::DownloadManager* manager,
251                               const base::Closure& callback)
252       : download_manager_(manager),
253         callback_(callback) {
254     download_manager_->AddObserver(this);
255   }
256
257   virtual ~SavePackageFinishedObserver() {
258     if (download_manager_)
259       download_manager_->RemoveObserver(this);
260   }
261
262   // DownloadManager::Observer:
263   virtual void OnSavePackageSuccessfullyFinished(
264       content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE {
265     callback_.Run();
266   }
267   virtual void ManagerGoingDown(content::DownloadManager* manager) OVERRIDE {
268     download_manager_->RemoveObserver(this);
269     download_manager_ = NULL;
270   }
271
272  private:
273   content::DownloadManager* download_manager_;
274   base::Closure callback_;
275
276   DISALLOW_COPY_AND_ASSIGN(SavePackageFinishedObserver);
277 };
278
279 class SavePageBrowserTest : public InProcessBrowserTest {
280  public:
281   SavePageBrowserTest() {}
282   virtual ~SavePageBrowserTest();
283
284  protected:
285   virtual void SetUp() OVERRIDE {
286     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir_));
287     ASSERT_TRUE(save_dir_.CreateUniqueTempDir());
288     InProcessBrowserTest::SetUp();
289   }
290
291   virtual void SetUpOnMainThread() OVERRIDE {
292     browser()->profile()->GetPrefs()->SetFilePath(
293         prefs::kDownloadDefaultDirectory, save_dir_.path());
294     browser()->profile()->GetPrefs()->SetFilePath(
295         prefs::kSaveFileDefaultDirectory, save_dir_.path());
296     BrowserThread::PostTask(
297         BrowserThread::IO, FROM_HERE,
298         base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
299   }
300
301   GURL NavigateToMockURL(const std::string& prefix) {
302     GURL url = URLRequestMockHTTPJob::GetMockUrl(
303         base::FilePath(kTestDir).AppendASCII(prefix + ".htm"));
304     ui_test_utils::NavigateToURL(browser(), url);
305     return url;
306   }
307
308   // Returns full paths of destination file and directory.
309   void GetDestinationPaths(const std::string& prefix,
310                 base::FilePath* full_file_name,
311                 base::FilePath* dir) {
312     *full_file_name = save_dir_.path().AppendASCII(prefix + ".htm");
313     *dir = save_dir_.path().AppendASCII(prefix + "_files");
314   }
315
316   WebContents* GetCurrentTab(Browser* browser) const {
317     WebContents* current_tab =
318         browser->tab_strip_model()->GetActiveWebContents();
319     EXPECT_TRUE(current_tab);
320     return current_tab;
321   }
322
323   // Returns true if and when there was a single download created, and its url
324   // is |expected_url|.
325   bool VerifySavePackageExpectations(
326       Browser* browser,
327       const GURL& expected_url) const {
328     // Generally, there should only be one download item created
329     // in all of these tests.  If it's already here, grab it; if not,
330     // wait for it to show up.
331     std::vector<DownloadItem*> items;
332     DownloadManager* manager(
333         BrowserContext::GetDownloadManager(browser->profile()));
334     manager->GetAllDownloads(&items);
335     if (items.size() == 0u) {
336       DownloadItemCreatedObserver(manager).WaitForDownloadItem(&items);
337     }
338
339     EXPECT_EQ(1u, items.size());
340     if (1u != items.size())
341       return false;
342     DownloadItem* download_item(items[0]);
343
344     return (expected_url == download_item->GetOriginalUrl());
345   }
346
347   // Note on synchronization:
348   //
349   // For each Save Page As operation, we create a corresponding shell
350   // DownloadItem to display progress to the user.  That DownloadItem goes
351   // through its own state transitions, including being persisted out to the
352   // history database, and the download shelf is not shown until after the
353   // persistence occurs.  Save Package completion (and marking the DownloadItem
354   // as completed) occurs asynchronously from persistence.  Thus if we want to
355   // examine either UI state or DB state, we need to wait until both the save
356   // package operation is complete and the relevant download item has been
357   // persisted.
358
359   DownloadManager* GetDownloadManager() const {
360     DownloadManager* download_manager =
361         BrowserContext::GetDownloadManager(browser()->profile());
362     EXPECT_TRUE(download_manager);
363     return download_manager;
364   }
365
366   // Path to directory containing test data.
367   base::FilePath test_dir_;
368
369   // Temporary directory we will save pages to.
370   base::ScopedTempDir save_dir_;
371
372  private:
373   DISALLOW_COPY_AND_ASSIGN(SavePageBrowserTest);
374 };
375
376 SavePageBrowserTest::~SavePageBrowserTest() {
377 }
378
379 // Disabled on Windows due to flakiness. http://crbug.com/162323
380 // TODO(linux_aura) http://crbug.com/163931
381 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
382 #define MAYBE_SaveHTMLOnly DISABLED_SaveHTMLOnly
383 #else
384 #define MAYBE_SaveHTMLOnly SaveHTMLOnly
385 #endif
386 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveHTMLOnly) {
387   GURL url = NavigateToMockURL("a");
388
389   base::FilePath full_file_name, dir;
390   GetDestinationPaths("a", &full_file_name, &dir);
391   DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
392       &DownloadStoredProperly, url, full_file_name, 1,
393       DownloadItem::COMPLETE));
394   scoped_refptr<content::MessageLoopRunner> loop_runner(
395       new content::MessageLoopRunner);
396   SavePackageFinishedObserver observer(
397       content::BrowserContext::GetDownloadManager(browser()->profile()),
398       loop_runner->QuitClosure());
399   ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
400                                         content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
401   loop_runner->Run();
402   ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
403   persisted.WaitForPersisted();
404   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
405   EXPECT_TRUE(base::PathExists(full_file_name));
406   EXPECT_FALSE(base::PathExists(dir));
407   EXPECT_TRUE(base::ContentsEqual(test_dir_.Append(base::FilePath(
408       kTestDir)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name));
409 }
410
411 // http://crbug.com/162323
412 // http://crbug.com/163931
413 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, DISABLED_SaveHTMLOnlyCancel) {
414   GURL url = NavigateToMockURL("a");
415   DownloadManager* manager(GetDownloadManager());
416   std::vector<DownloadItem*> downloads;
417   manager->GetAllDownloads(&downloads);
418   ASSERT_EQ(0u, downloads.size());
419
420   base::FilePath full_file_name, dir;
421   GetDestinationPaths("a", &full_file_name, &dir);
422   DownloadItemCreatedObserver creation_observer(manager);
423   DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
424       &DownloadStoredProperly, url, full_file_name, -1,
425       DownloadItem::CANCELLED));
426   // -1 to disable number of files check; we don't update after cancel, and
427   // we don't know when the single file completed in relationship to
428   // the cancel.
429
430   ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
431                                         content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
432   std::vector<DownloadItem*> items;
433   creation_observer.WaitForDownloadItem(&items);
434   ASSERT_EQ(1UL, items.size());
435   ASSERT_EQ(url.spec(), items[0]->GetOriginalUrl().spec());
436   items[0]->Cancel(true);
437   // TODO(rdsmith): Fix DII::Cancel() to actually cancel the save package.
438   // Currently it's ignored.
439
440   persisted.WaitForPersisted();
441
442   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
443
444   // TODO(benjhayden): Figure out how to safely wait for SavePackage's finished
445   // notification, then expect the contents of the downloaded file.
446 }
447
448 class DelayingDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
449  public:
450   explicit DelayingDownloadManagerDelegate(Profile* profile)
451     : ChromeDownloadManagerDelegate(profile) {
452   }
453   virtual bool ShouldCompleteDownload(
454       content::DownloadItem* item,
455       const base::Closure& user_complete_callback) OVERRIDE {
456     return false;
457   }
458
459  protected:
460   virtual ~DelayingDownloadManagerDelegate() {}
461
462  private:
463   DISALLOW_COPY_AND_ASSIGN(DelayingDownloadManagerDelegate);
464 };
465
466 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveHTMLOnlyTabDestroy) {
467   GURL url = NavigateToMockURL("a");
468   DownloadManager* manager(GetDownloadManager());
469   scoped_refptr<DelayingDownloadManagerDelegate> delaying_delegate(
470       new DelayingDownloadManagerDelegate(browser()->profile()));
471   delaying_delegate->SetNextId(content::DownloadItem::kInvalidId + 1);
472   manager->SetDelegate(delaying_delegate.get());
473   std::vector<DownloadItem*> downloads;
474   manager->GetAllDownloads(&downloads);
475   ASSERT_EQ(0u, downloads.size());
476
477   base::FilePath full_file_name, dir;
478   GetDestinationPaths("a", &full_file_name, &dir);
479   DownloadItemCreatedObserver creation_observer(manager);
480   ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
481                                         content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
482   std::vector<DownloadItem*> items;
483   creation_observer.WaitForDownloadItem(&items);
484   ASSERT_TRUE(items.size() == 1);
485
486   // Close the tab; does this cancel the download?
487   GetCurrentTab(browser())->Close();
488   EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());
489
490   EXPECT_FALSE(base::PathExists(full_file_name));
491   EXPECT_FALSE(base::PathExists(dir));
492
493   manager->SetDelegate(NULL);
494 }
495
496 // Disabled on Windows due to flakiness. http://crbug.com/162323
497 // TODO(linux_aura) http://crbug.com/163931
498 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
499 #define MAYBE_SaveViewSourceHTMLOnly DISABLED_SaveViewSourceHTMLOnly
500 #else
501 #define MAYBE_SaveViewSourceHTMLOnly SaveViewSourceHTMLOnly
502 #endif
503 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveViewSourceHTMLOnly) {
504   base::FilePath file_name(FILE_PATH_LITERAL("a.htm"));
505   GURL view_source_url = URLRequestMockHTTPJob::GetMockViewSourceUrl(
506       base::FilePath(kTestDir).Append(file_name));
507   GURL actual_page_url = URLRequestMockHTTPJob::GetMockUrl(
508       base::FilePath(kTestDir).Append(file_name));
509   ui_test_utils::NavigateToURL(browser(), view_source_url);
510
511   base::FilePath full_file_name, dir;
512   GetDestinationPaths("a", &full_file_name, &dir);
513   DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
514       &DownloadStoredProperly, actual_page_url, full_file_name, 1,
515       DownloadItem::COMPLETE));
516   scoped_refptr<content::MessageLoopRunner> loop_runner(
517       new content::MessageLoopRunner);
518   SavePackageFinishedObserver observer(
519       content::BrowserContext::GetDownloadManager(browser()->profile()),
520       loop_runner->QuitClosure());
521   ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
522                                         content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
523   loop_runner->Run();
524   ASSERT_TRUE(VerifySavePackageExpectations(browser(), actual_page_url));
525   persisted.WaitForPersisted();
526
527   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
528
529   EXPECT_TRUE(base::PathExists(full_file_name));
530   EXPECT_FALSE(base::PathExists(dir));
531   EXPECT_TRUE(base::ContentsEqual(
532       test_dir_.Append(base::FilePath(kTestDir)).Append(file_name),
533       full_file_name));
534 }
535
536 // Disabled on Windows due to flakiness. http://crbug.com/162323
537 // TODO(linux_aura) http://crbug.com/163931
538 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
539 #define MAYBE_SaveCompleteHTML DISABLED_SaveCompleteHTML
540 #else
541 #define MAYBE_SaveCompleteHTML SaveCompleteHTML
542 #endif
543 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveCompleteHTML) {
544   GURL url = NavigateToMockURL("b");
545
546   base::FilePath full_file_name, dir;
547   GetDestinationPaths("b", &full_file_name, &dir);
548   DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
549       &DownloadStoredProperly, url, full_file_name, 3,
550       DownloadItem::COMPLETE));
551   scoped_refptr<content::MessageLoopRunner> loop_runner(
552       new content::MessageLoopRunner);
553   SavePackageFinishedObserver observer(
554       content::BrowserContext::GetDownloadManager(browser()->profile()),
555       loop_runner->QuitClosure());
556   ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
557       full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
558   loop_runner->Run();
559   ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
560   persisted.WaitForPersisted();
561
562   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
563
564   EXPECT_TRUE(base::PathExists(full_file_name));
565   EXPECT_TRUE(base::PathExists(dir));
566   EXPECT_TRUE(base::TextContentsEqual(
567       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved1.htm"),
568       full_file_name));
569   EXPECT_TRUE(base::ContentsEqual(
570       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
571       dir.AppendASCII("1.png")));
572   EXPECT_TRUE(base::ContentsEqual(
573       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.css"),
574       dir.AppendASCII("1.css")));
575 }
576
577 // Invoke a save page during the initial navigation.
578 // (Regression test for http://crbug.com/156538).
579 // Disabled on Windows due to flakiness. http://crbug.com/162323
580 // TODO(linux_aura) http://crbug.com/163931
581 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
582 #define MAYBE_SaveDuringInitialNavigationIncognito DISABLED_SaveDuringInitialNavigationIncognito
583 #else
584 #define MAYBE_SaveDuringInitialNavigationIncognito SaveDuringInitialNavigationIncognito
585 #endif
586 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest,
587                        MAYBE_SaveDuringInitialNavigationIncognito) {
588   // Open an Incognito window.
589   Browser* incognito = CreateIncognitoBrowser();  // Waits.
590   ASSERT_TRUE(incognito);
591
592   // Create a download item creation waiter on that window.
593   DownloadItemCreatedObserver creation_observer(
594       BrowserContext::GetDownloadManager(incognito->profile()));
595
596   // Navigate, unblocking with new tab.
597   GURL url = URLRequestMockHTTPJob::GetMockUrl(
598       base::FilePath(kTestDir).AppendASCII("b.htm"));
599   NavigateToURLWithDisposition(incognito, url, NEW_FOREGROUND_TAB,
600                                ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
601
602   // Save the page before completion.
603   base::FilePath full_file_name, dir;
604   GetDestinationPaths("b", &full_file_name, &dir);
605   scoped_refptr<content::MessageLoopRunner> loop_runner(
606       new content::MessageLoopRunner);
607   SavePackageFinishedObserver observer(
608       content::BrowserContext::GetDownloadManager(incognito->profile()),
609       loop_runner->QuitClosure());
610   ASSERT_TRUE(GetCurrentTab(incognito)->SavePage(
611       full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
612
613   loop_runner->Run();
614   ASSERT_TRUE(VerifySavePackageExpectations(incognito, url));
615
616   // Confirm download shelf is visible.
617   EXPECT_TRUE(incognito->window()->IsDownloadShelfVisible());
618
619   // We can't check more than this because SavePackage is racing with
620   // the page load.  If the page load won the race, then SavePackage
621   // might have completed. If the page load lost the race, then
622   // SavePackage will cancel because there aren't any resources to
623   // save.
624 }
625
626 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, NoSave) {
627   ui_test_utils::NavigateToURL(browser(), GURL(content::kAboutBlankURL));
628   EXPECT_FALSE(chrome::CanSavePage(browser()));
629 }
630
631 // Disabled on Windows due to flakiness. http://crbug.com/162323
632 // TODO(linux_aura) http://crbug.com/163931
633 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
634 #define MAYBE_FileNameFromPageTitle DISABLED_FileNameFromPageTitle
635 #else
636 #define MAYBE_FileNameFromPageTitle FileNameFromPageTitle
637 #endif
638 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_FileNameFromPageTitle) {
639   GURL url = NavigateToMockURL("b");
640
641   base::FilePath full_file_name = save_dir_.path().AppendASCII(
642       std::string("Test page for saving page feature") + kAppendedExtension);
643   base::FilePath dir = save_dir_.path().AppendASCII(
644       "Test page for saving page feature_files");
645   DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
646       &DownloadStoredProperly, url, full_file_name, 3,
647       DownloadItem::COMPLETE));
648   scoped_refptr<content::MessageLoopRunner> loop_runner(
649       new content::MessageLoopRunner);
650   SavePackageFinishedObserver observer(
651       content::BrowserContext::GetDownloadManager(browser()->profile()),
652       loop_runner->QuitClosure());
653   ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
654       full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
655
656   loop_runner->Run();
657   ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
658   persisted.WaitForPersisted();
659
660   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
661
662   EXPECT_TRUE(base::PathExists(full_file_name));
663   EXPECT_TRUE(base::PathExists(dir));
664   EXPECT_TRUE(base::TextContentsEqual(
665       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved2.htm"),
666       full_file_name));
667   EXPECT_TRUE(base::ContentsEqual(
668       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
669       dir.AppendASCII("1.png")));
670   EXPECT_TRUE(base::ContentsEqual(
671       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.css"),
672       dir.AppendASCII("1.css")));
673 }
674
675 // Disabled on Windows due to flakiness. http://crbug.com/162323
676 // TODO(linux_aura) http://crbug.com/163931
677 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
678 #define MAYBE_RemoveFromList DISABLED_RemoveFromList
679 #else
680 #define MAYBE_RemoveFromList RemoveFromList
681 #endif
682 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_RemoveFromList) {
683   GURL url = NavigateToMockURL("a");
684
685   base::FilePath full_file_name, dir;
686   GetDestinationPaths("a", &full_file_name, &dir);
687   DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
688       &DownloadStoredProperly, url, full_file_name, 1,
689       DownloadItem::COMPLETE));
690   scoped_refptr<content::MessageLoopRunner> loop_runner(
691       new content::MessageLoopRunner);
692   SavePackageFinishedObserver observer(
693       content::BrowserContext::GetDownloadManager(browser()->profile()),
694       loop_runner->QuitClosure());
695   ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
696                                         content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
697
698   loop_runner->Run();
699   ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
700   persisted.WaitForPersisted();
701
702   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
703
704   DownloadManager* manager(GetDownloadManager());
705   std::vector<DownloadItem*> downloads;
706   manager->GetAllDownloads(&downloads);
707   ASSERT_EQ(1UL, downloads.size());
708   DownloadRemovedObserver removed(browser()->profile(), downloads[0]->GetId());
709
710   EXPECT_EQ(manager->RemoveAllDownloads(), 1);
711
712   removed.WaitForRemoved();
713
714   EXPECT_TRUE(base::PathExists(full_file_name));
715   EXPECT_FALSE(base::PathExists(dir));
716   EXPECT_TRUE(base::ContentsEqual(test_dir_.Append(base::FilePath(
717       kTestDir)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name));
718 }
719
720 // This tests that a webpage with the title "test.exe" is saved as
721 // "test.exe.htm".
722 // We probably don't care to handle this on Linux or Mac.
723 #if defined(OS_WIN)
724 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, CleanFilenameFromPageTitle) {
725   const base::FilePath file_name(FILE_PATH_LITERAL("c.htm"));
726   base::FilePath download_dir =
727       DownloadPrefs::FromDownloadManager(GetDownloadManager())->
728           DownloadPath();
729   base::FilePath full_file_name =
730       download_dir.AppendASCII(std::string("test.exe") + kAppendedExtension);
731   base::FilePath dir = download_dir.AppendASCII("test.exe_files");
732
733   EXPECT_FALSE(base::PathExists(full_file_name));
734   GURL url = URLRequestMockHTTPJob::GetMockUrl(
735       base::FilePath(kTestDir).Append(file_name));
736   ui_test_utils::NavigateToURL(browser(), url);
737
738   SavePackageFilePicker::SetShouldPromptUser(false);
739   scoped_refptr<content::MessageLoopRunner> loop_runner(
740       new content::MessageLoopRunner);
741   SavePackageFinishedObserver observer(
742       content::BrowserContext::GetDownloadManager(browser()->profile()),
743       loop_runner->QuitClosure());
744   chrome::SavePage(browser());
745   loop_runner->Run();
746
747   EXPECT_TRUE(base::PathExists(full_file_name));
748
749   EXPECT_TRUE(file_util::DieFileDie(full_file_name, false));
750   EXPECT_TRUE(file_util::DieFileDie(dir, true));
751 }
752 #endif
753
754 class SavePageAsMHTMLBrowserTest : public SavePageBrowserTest {
755  public:
756   SavePageAsMHTMLBrowserTest() {}
757   virtual ~SavePageAsMHTMLBrowserTest();
758   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
759     command_line->AppendSwitch(switches::kSavePageAsMHTML);
760   }
761
762  private:
763   DISALLOW_COPY_AND_ASSIGN(SavePageAsMHTMLBrowserTest);
764 };
765
766 SavePageAsMHTMLBrowserTest::~SavePageAsMHTMLBrowserTest() {
767 }
768
769 IN_PROC_BROWSER_TEST_F(SavePageAsMHTMLBrowserTest, SavePageAsMHTML) {
770   static const int64 kFileSizeMin = 2758;
771   GURL url = NavigateToMockURL("b");
772   base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
773       GetDownloadManager())->DownloadPath();
774   base::FilePath full_file_name = download_dir.AppendASCII(std::string(
775       "Test page for saving page feature.mhtml"));
776   SavePackageFilePicker::SetShouldPromptUser(false);
777   DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
778       &DownloadStoredProperly, url, full_file_name, -1,
779       DownloadItem::COMPLETE));
780   scoped_refptr<content::MessageLoopRunner> loop_runner(
781       new content::MessageLoopRunner);
782   SavePackageFinishedObserver observer(
783       content::BrowserContext::GetDownloadManager(browser()->profile()),
784       loop_runner->QuitClosure());
785   chrome::SavePage(browser());
786   loop_runner->Run();
787   ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
788   persisted.WaitForPersisted();
789
790   ASSERT_TRUE(base::PathExists(full_file_name));
791   int64 actual_file_size = -1;
792   EXPECT_TRUE(file_util::GetFileSize(full_file_name, &actual_file_size));
793   EXPECT_LE(kFileSizeMin, actual_file_size);
794 }
795
796 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SavePageBrowserTest_NonMHTML) {
797   SavePackageFilePicker::SetShouldPromptUser(false);
798   GURL url("data:text/plain,foo");
799   ui_test_utils::NavigateToURL(browser(), url);
800   scoped_refptr<content::MessageLoopRunner> loop_runner(
801       new content::MessageLoopRunner);
802   SavePackageFinishedObserver observer(
803       content::BrowserContext::GetDownloadManager(browser()->profile()),
804       loop_runner->QuitClosure());
805   chrome::SavePage(browser());
806   loop_runner->Run();
807   base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
808       GetDownloadManager())->DownloadPath();
809   base::FilePath filename = download_dir.AppendASCII("dataurl.txt");
810   ASSERT_TRUE(base::PathExists(filename));
811   std::string contents;
812   EXPECT_TRUE(base::ReadFileToString(filename, &contents));
813   EXPECT_EQ("foo", contents);
814 }
815
816 }  // namespace
817