1 // Copyright (c) 2011 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/file_path.h" 6 #include "base/file_util.h" 7 #include "base/memory/ref_counted.h" 8 #include "base/memory/scoped_temp_dir.h" 9 #include "base/path_service.h" 10 #include "base/test/test_file_util.h" 11 #include "base/utf_string_conversions.h" 12 #include "chrome/browser/browser_process.h" 13 #include "chrome/browser/download/download_item.h" 14 #include "chrome/browser/download/download_file_manager.h" 15 #include "chrome/browser/download/download_manager.h" 16 #include "chrome/browser/download/download_prefs.h" 17 #include "chrome/browser/download/download_shelf.h" 18 #include "chrome/browser/history/download_create_info.h" 19 #include "chrome/browser/history/history.h" 20 #include "chrome/browser/net/url_request_mock_http_job.h" 21 #include "chrome/browser/net/url_request_slow_download_job.h" 22 #include "chrome/browser/prefs/pref_service.h" 23 #include "chrome/browser/profiles/profile.h" 24 #include "chrome/browser/ui/browser.h" 25 #include "chrome/browser/ui/browser_list.h" 26 #include "chrome/browser/ui/browser_window.h" 27 #include "chrome/common/chrome_paths.h" 28 #include "chrome/common/pref_names.h" 29 #include "chrome/common/url_constants.h" 30 #include "chrome/test/in_process_browser_test.h" 31 #include "chrome/test/ui_test_utils.h" 32 #include "content/browser/cancelable_request.h" 33 #include "content/browser/renderer_host/resource_dispatcher_host.h" 34 #include "content/common/page_transition_types.h" 35 #include "net/base/net_util.h" 36 #include "testing/gtest/include/gtest/gtest.h" 37 38 namespace { 39 40 // Variation of DownloadsCompleteObserver from ui_test_utils.cc; the 41 // specifically targeted download tests need finer granularity on waiting. 42 // Construction of this class defines a system state, based on some number 43 // of downloads being seen in a particular state + other events that 44 // may occur in the download system. That state will be recorded if it 45 // occurs at any point after construction. When that state occurs, the class 46 // is considered finished. Callers may either probe for the finished state, or 47 // wait on it. 48 // 49 // TODO(rdsmith): Detect manager going down, remove pointer to 50 // DownloadManager, transition to finished. (For right now we 51 // just use a scoped_refptr<> to keep it around, but that may cause 52 // timeouts on waiting if a DownloadManager::Shutdown() occurs which 53 // cancels our in-progress downloads.) 54 class DownloadsObserver : public DownloadManager::Observer, 55 public DownloadItem::Observer { 56 public: 57 // Create an object that will be considered finished when |wait_count| 58 // download items have entered state |download_finished_state|. 59 // If |finish_on_select_file| is true, the object will also be 60 // considered finished if the DownloadManager raises a 61 // SelectFileDialogDisplayed() notification. 62 63 // TODO(rdsmith): Add option of "dangerous accept/reject dialog" as 64 // a unblocking event; if that shows up when you aren't expecting it, 65 // it'll result in a hang/timeout as we'll never get to final rename. 66 // This probably means rewriting the interface to take a list of events 67 // to treat as completion events. 68 DownloadsObserver(DownloadManager* download_manager, 69 size_t wait_count, 70 DownloadItem::DownloadState download_finished_state, 71 bool finish_on_select_file) 72 : download_manager_(download_manager), 73 wait_count_(wait_count), 74 finished_downloads_at_construction_(0), 75 waiting_(false), 76 download_finished_state_(download_finished_state), 77 finish_on_select_file_(finish_on_select_file), 78 select_file_dialog_seen_(false) { 79 download_manager_->AddObserver(this); // Will call initial ModelChanged(). 80 finished_downloads_at_construction_ = finished_downloads_.size(); 81 } 82 83 ~DownloadsObserver() { 84 std::set<DownloadItem*>::iterator it = downloads_observed_.begin(); 85 for (; it != downloads_observed_.end(); ++it) { 86 (*it)->RemoveObserver(this); 87 } 88 download_manager_->RemoveObserver(this); 89 } 90 91 // State accessors. 92 bool select_file_dialog_seen() { return select_file_dialog_seen_; } 93 94 // Wait for whatever state was specified in the constructor. 95 void WaitForFinished() { 96 if (!IsFinished()) { 97 waiting_ = true; 98 ui_test_utils::RunMessageLoop(); 99 waiting_ = false; 100 } 101 } 102 103 // Return true if everything's happened that we're configured for. 104 bool IsFinished() { 105 if (finished_downloads_.size() - finished_downloads_at_construction_ 106 >= wait_count_) 107 return true; 108 return (finish_on_select_file_ && select_file_dialog_seen_); 109 } 110 111 // DownloadItem::Observer 112 virtual void OnDownloadUpdated(DownloadItem* download) { 113 if (download->state() == download_finished_state_) 114 DownloadInFinalState(download); 115 } 116 117 virtual void OnDownloadOpened(DownloadItem* download) {} 118 119 // DownloadManager::Observer 120 virtual void ModelChanged() { 121 // Regenerate DownloadItem observers. If there are any download items 122 // in our final state, note them in |finished_downloads_| 123 // (done by |OnDownloadUpdated()|). 124 std::vector<DownloadItem*> downloads; 125 download_manager_->SearchDownloads(string16(), &downloads); 126 127 std::vector<DownloadItem*>::iterator it = downloads.begin(); 128 for (; it != downloads.end(); ++it) { 129 OnDownloadUpdated(*it); // Safe to call multiple times; checks state. 130 131 std::set<DownloadItem*>::const_iterator 132 finished_it(finished_downloads_.find(*it)); 133 std::set<DownloadItem*>::iterator 134 observed_it(downloads_observed_.find(*it)); 135 136 // If it isn't finished and we're aren't observing it, start. 137 if (finished_it == finished_downloads_.end() && 138 observed_it == downloads_observed_.end()) { 139 (*it)->AddObserver(this); 140 downloads_observed_.insert(*it); 141 continue; 142 } 143 144 // If it is finished and we are observing it, stop. 145 if (finished_it != finished_downloads_.end() && 146 observed_it != downloads_observed_.end()) { 147 (*it)->RemoveObserver(this); 148 downloads_observed_.erase(observed_it); 149 continue; 150 } 151 } 152 } 153 154 virtual void SelectFileDialogDisplayed(int32 /* id */) { 155 select_file_dialog_seen_ = true; 156 SignalIfFinished(); 157 } 158 159 private: 160 // Called when we know that a download item is in a final state. 161 // Note that this is not the same as it first transitioning in to the 162 // final state; multiple notifications may occur once the item is in 163 // that state. So we keep our own track of transitions into final. 164 void DownloadInFinalState(DownloadItem* download) { 165 if (finished_downloads_.find(download) != finished_downloads_.end()) { 166 // We've already seen terminal state on this download. 167 return; 168 } 169 170 // Record the transition. 171 finished_downloads_.insert(download); 172 173 SignalIfFinished(); 174 } 175 176 void SignalIfFinished() { 177 if (waiting_ && IsFinished()) 178 MessageLoopForUI::current()->Quit(); 179 } 180 181 // The observed download manager. 182 scoped_refptr<DownloadManager> download_manager_; 183 184 // The set of DownloadItem's that have transitioned to their finished state 185 // since construction of this object. When the size of this array 186 // reaches wait_count_, we're done. 187 std::set<DownloadItem*> finished_downloads_; 188 189 // The set of DownloadItem's we are currently observing. Generally there 190 // won't be any overlap with the above; once we see the final state 191 // on a DownloadItem, we'll stop observing it. 192 std::set<DownloadItem*> downloads_observed_; 193 194 // The number of downloads to wait on completing. 195 size_t wait_count_; 196 197 // The number of downloads entered in final state in initial 198 // ModelChanged(). We use |finished_downloads_| to track the incoming 199 // transitions to final state we should ignore, and to track the 200 // number of final state transitions that occurred between 201 // construction and return from wait. But some downloads may be in our 202 // final state (and thus be entered into |finished_downloads_|) when we 203 // construct this class. We don't want to count those in our transition 204 // to finished. 205 int finished_downloads_at_construction_; 206 207 // Whether an internal message loop has been started and must be quit upon 208 // all downloads completing. 209 bool waiting_; 210 211 // The state on which to consider the DownloadItem finished. 212 DownloadItem::DownloadState download_finished_state_; 213 214 // True if we should transition the DownloadsObserver to finished if 215 // the select file dialog comes up. 216 bool finish_on_select_file_; 217 218 // True if we've seen the select file dialog. 219 bool select_file_dialog_seen_; 220 221 DISALLOW_COPY_AND_ASSIGN(DownloadsObserver); 222 }; 223 224 // WaitForFlush() returns after: 225 // * There are no IN_PROGRESS download items remaining on the 226 // DownloadManager. 227 // * There have been two round trip messages through the file and 228 // IO threads. 229 // This almost certainly means that a Download cancel has propagated through 230 // the system. 231 class DownloadsFlushObserver 232 : public DownloadManager::Observer, 233 public DownloadItem::Observer, 234 public base::RefCountedThreadSafe<DownloadsFlushObserver> { 235 public: 236 explicit DownloadsFlushObserver(DownloadManager* download_manager) 237 : download_manager_(download_manager), 238 waiting_for_zero_inprogress_(true) { } 239 240 void WaitForFlush() { 241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 242 download_manager_->AddObserver(this); 243 ui_test_utils::RunMessageLoop(); 244 } 245 246 // DownloadsManager observer methods. 247 virtual void ModelChanged() { 248 // Model has changed, so there may be more DownloadItems to observe. 249 CheckDownloadsInProgress(true); 250 } 251 252 // DownloadItem observer methods. 253 virtual void OnDownloadUpdated(DownloadItem* download) { 254 // No change in DownloadItem set on manager. 255 CheckDownloadsInProgress(false); 256 } 257 virtual void OnDownloadOpened(DownloadItem* download) {} 258 259 protected: 260 friend class base::RefCountedThreadSafe<DownloadsFlushObserver>; 261 262 virtual ~DownloadsFlushObserver() { 263 download_manager_->RemoveObserver(this); 264 for (std::set<DownloadItem*>::iterator it = downloads_observed_.begin(); 265 it != downloads_observed_.end(); ++it) { 266 (*it)->RemoveObserver(this); 267 } 268 } 269 270 private: 271 // If we're waiting for that flush point, check the number 272 // of downloads in the IN_PROGRESS state and take appropriate 273 // action. If requested, also observes all downloads while iterating. 274 void CheckDownloadsInProgress(bool observe_downloads) { 275 if (waiting_for_zero_inprogress_) { 276 int count = 0; 277 278 std::vector<DownloadItem*> downloads; 279 download_manager_->SearchDownloads(string16(), &downloads); 280 std::vector<DownloadItem*>::iterator it = downloads.begin(); 281 for (; it != downloads.end(); ++it) { 282 if ((*it)->state() == DownloadItem::IN_PROGRESS) 283 count++; 284 if (observe_downloads) { 285 if (downloads_observed_.find(*it) == downloads_observed_.end()) { 286 (*it)->AddObserver(this); 287 } 288 // Download items are forever, and we don't want to make 289 // assumptions about future state transitions, so once we 290 // start observing them, we don't stop until destruction. 291 } 292 } 293 294 if (count == 0) { 295 waiting_for_zero_inprogress_ = false; 296 // Stop observing DownloadItems. We maintain the observation 297 // of DownloadManager so that we don't have to independently track 298 // whether we are observing it for conditional destruction. 299 for (std::set<DownloadItem*>::iterator it = downloads_observed_.begin(); 300 it != downloads_observed_.end(); ++it) { 301 (*it)->RemoveObserver(this); 302 } 303 downloads_observed_.clear(); 304 305 // Trigger next step. We need to go past the IO thread twice, as 306 // there's a self-task posting in the IO thread cancel path. 307 BrowserThread::PostTask( 308 BrowserThread::FILE, FROM_HERE, 309 NewRunnableMethod(this, 310 &DownloadsFlushObserver::PingFileThread, 2)); 311 } 312 } 313 } 314 315 void PingFileThread(int cycle) { 316 BrowserThread::PostTask( 317 BrowserThread::IO, FROM_HERE, 318 NewRunnableMethod(this, &DownloadsFlushObserver::PingIOThread, 319 cycle)); 320 } 321 322 void PingIOThread(int cycle) { 323 if (--cycle) { 324 BrowserThread::PostTask( 325 BrowserThread::UI, FROM_HERE, 326 NewRunnableMethod(this, &DownloadsFlushObserver::PingFileThread, 327 cycle)); 328 } else { 329 BrowserThread::PostTask( 330 BrowserThread::UI, FROM_HERE, new MessageLoop::QuitTask()); 331 } 332 } 333 334 DownloadManager* download_manager_; 335 std::set<DownloadItem*> downloads_observed_; 336 bool waiting_for_zero_inprogress_; 337 338 DISALLOW_COPY_AND_ASSIGN(DownloadsFlushObserver); 339 }; 340 341 // Collect the information from FILE and IO threads needed for the Cancel 342 // Test, specifically the number of outstanding requests on the 343 // ResourceDispatcherHost and the number of pending downloads on the 344 // DownloadFileManager. 345 class CancelTestDataCollector 346 : public base::RefCountedThreadSafe<CancelTestDataCollector> { 347 public: 348 CancelTestDataCollector() 349 : resource_dispatcher_host_( 350 g_browser_process->resource_dispatcher_host()), 351 rdh_pending_requests_(0), 352 dfm_pending_downloads_(0) { } 353 354 void WaitForDataCollected() { 355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 356 BrowserThread::PostTask( 357 BrowserThread::IO, FROM_HERE, 358 NewRunnableMethod(this, &CancelTestDataCollector::IOInfoCollector)); 359 ui_test_utils::RunMessageLoop(); 360 } 361 362 int rdh_pending_requests() { return rdh_pending_requests_; } 363 int dfm_pending_downloads() { return dfm_pending_downloads_; } 364 365 protected: 366 friend class base::RefCountedThreadSafe<CancelTestDataCollector>; 367 368 virtual ~CancelTestDataCollector() {} 369 370 private: 371 372 void IOInfoCollector() { 373 download_file_manager_ = resource_dispatcher_host_->download_file_manager(); 374 rdh_pending_requests_ = resource_dispatcher_host_->pending_requests(); 375 BrowserThread::PostTask( 376 BrowserThread::FILE, FROM_HERE, 377 NewRunnableMethod(this, &CancelTestDataCollector::FileInfoCollector)); 378 } 379 380 void FileInfoCollector() { 381 dfm_pending_downloads_ = download_file_manager_->NumberOfActiveDownloads(); 382 BrowserThread::PostTask( 383 BrowserThread::UI, FROM_HERE, new MessageLoop::QuitTask()); 384 } 385 386 ResourceDispatcherHost* resource_dispatcher_host_; 387 DownloadFileManager* download_file_manager_; 388 int rdh_pending_requests_; 389 int dfm_pending_downloads_; 390 391 DISALLOW_COPY_AND_ASSIGN(CancelTestDataCollector); 392 }; 393 394 } // namespace 395 396 class DownloadTest : public InProcessBrowserTest { 397 public: 398 enum SelectExpectation { 399 EXPECT_NO_SELECT_DIALOG = -1, 400 EXPECT_NOTHING, 401 EXPECT_SELECT_DIALOG 402 }; 403 404 // Returning false indicates a failure of the setup, and should be asserted 405 // in the caller. 406 virtual bool InitialSetup(bool prompt_for_download) { 407 bool have_test_dir = PathService::Get(chrome::DIR_TEST_DATA, &test_dir_); 408 EXPECT_TRUE(have_test_dir); 409 if (!have_test_dir) 410 return false; 411 412 // Sanity check default values for window / tab count and shelf visibility. 413 int window_count = BrowserList::size(); 414 EXPECT_EQ(1, window_count); 415 EXPECT_EQ(1, browser()->tab_count()); 416 bool is_shelf_visible = browser()->window()->IsDownloadShelfVisible(); 417 EXPECT_FALSE(is_shelf_visible); 418 419 // Set up the temporary download folder. 420 bool created_downloads_dir = CreateAndSetDownloadsDirectory(browser()); 421 EXPECT_TRUE(created_downloads_dir); 422 if (!created_downloads_dir) 423 return false; 424 browser()->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload, 425 prompt_for_download); 426 427 return true; 428 } 429 430 protected: 431 432 enum SizeTestType { 433 SIZE_TEST_TYPE_KNOWN, 434 SIZE_TEST_TYPE_UNKNOWN, 435 }; 436 437 // Location of the file source (the place from which it is downloaded). 438 FilePath OriginFile(FilePath file) { 439 return test_dir_.Append(file); 440 } 441 442 // Location of the file destination (place to which it is downloaded). 443 FilePath DestinationFile(Browser* browser, FilePath file) { 444 return GetDownloadDirectory(browser).Append(file); 445 } 446 447 // Must be called after browser creation. Creates a temporary 448 // directory for downloads that is auto-deleted on destruction. 449 // Returning false indicates a failure of the function, and should be asserted 450 // in the caller. 451 bool CreateAndSetDownloadsDirectory(Browser* browser) { 452 if (!browser) 453 return false; 454 455 if (!downloads_directory_.CreateUniqueTempDir()) 456 return false; 457 458 browser->profile()->GetPrefs()->SetFilePath( 459 prefs::kDownloadDefaultDirectory, 460 downloads_directory_.path()); 461 462 return true; 463 } 464 465 FilePath GetDownloadDirectory(Browser* browser) { 466 DownloadManager* download_mananger = 467 browser->profile()->GetDownloadManager(); 468 return download_mananger->download_prefs()->download_path(); 469 } 470 471 // Create a DownloadsObserver that will wait for the 472 // specified number of downloads to finish. 473 DownloadsObserver* CreateWaiter(Browser* browser, int num_downloads) { 474 DownloadManager* download_manager = 475 browser->profile()->GetDownloadManager(); 476 return new DownloadsObserver( 477 download_manager, num_downloads, 478 DownloadItem::COMPLETE, // Really done 479 true); // Bail on select file 480 } 481 482 // Create a DownloadsObserver that will wait for the 483 // specified number of downloads to start. 484 DownloadsObserver* CreateInProgressWaiter(Browser* browser, 485 int num_downloads) { 486 DownloadManager* download_manager = 487 browser->profile()->GetDownloadManager(); 488 return new DownloadsObserver( 489 download_manager, num_downloads, 490 DownloadItem::IN_PROGRESS, // Has started 491 true); // Bail on select file 492 } 493 494 // Download |url|, then wait for the download to finish. 495 // |disposition| indicates where the navigation occurs (current tab, new 496 // foreground tab, etc). 497 // |expectation| indicates whether or not a Select File dialog should be 498 // open when the download is finished, or if we don't care. 499 // If the dialog appears, the routine exits. The only effect |expectation| 500 // has is whether or not the test succeeds. 501 // |browser_test_flags| indicate what to wait for, and is an OR of 0 or more 502 // values in the ui_test_utils::BrowserTestWaitFlags enum. 503 void DownloadAndWaitWithDisposition(Browser* browser, 504 const GURL& url, 505 WindowOpenDisposition disposition, 506 SelectExpectation expectation, 507 int browser_test_flags) { 508 // Setup notification, navigate, and block. 509 scoped_ptr<DownloadsObserver> observer(CreateWaiter(browser, 1)); 510 // This call will block until the condition specified by 511 // |browser_test_flags|, but will not wait for the download to finish. 512 ui_test_utils::NavigateToURLWithDisposition(browser, 513 url, 514 disposition, 515 browser_test_flags); 516 // Waits for the download to complete. 517 observer->WaitForFinished(); 518 519 // If specified, check the state of the select file dialog. 520 if (expectation != EXPECT_NOTHING) { 521 EXPECT_EQ(expectation == EXPECT_SELECT_DIALOG, 522 observer->select_file_dialog_seen()); 523 } 524 } 525 526 // Download a file in the current tab, then wait for the download to finish. 527 void DownloadAndWait(Browser* browser, 528 const GURL& url, 529 SelectExpectation expectation) { 530 DownloadAndWaitWithDisposition( 531 browser, 532 url, 533 CURRENT_TAB, 534 expectation, 535 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 536 } 537 538 // Should only be called when the download is known to have finished 539 // (in error or not). 540 // Returning false indicates a failure of the function, and should be asserted 541 // in the caller. 542 bool CheckDownload(Browser* browser, 543 const FilePath& downloaded_filename, 544 const FilePath& origin_filename) { 545 // Find the path to which the data will be downloaded. 546 FilePath downloaded_file(DestinationFile(browser, downloaded_filename)); 547 548 // Find the origin path (from which the data comes). 549 FilePath origin_file(OriginFile(origin_filename)); 550 bool origin_file_exists = file_util::PathExists(origin_file); 551 EXPECT_TRUE(origin_file_exists); 552 if (!origin_file_exists) 553 return false; 554 555 // Confirm the downloaded data file exists. 556 bool downloaded_file_exists = file_util::PathExists(downloaded_file); 557 EXPECT_TRUE(downloaded_file_exists); 558 if (!downloaded_file_exists) 559 return false; 560 561 int64 origin_file_size = 0; 562 int64 downloaded_file_size = 0; 563 EXPECT_TRUE(file_util::GetFileSize(origin_file, &origin_file_size)); 564 EXPECT_TRUE(file_util::GetFileSize(downloaded_file, &downloaded_file_size)); 565 EXPECT_EQ(origin_file_size, downloaded_file_size); 566 EXPECT_TRUE(file_util::ContentsEqual(downloaded_file, origin_file)); 567 568 // Delete the downloaded copy of the file. 569 bool downloaded_file_deleted = 570 file_util::DieFileDie(downloaded_file, false); 571 EXPECT_TRUE(downloaded_file_deleted); 572 return downloaded_file_deleted; 573 } 574 575 bool RunSizeTest(Browser* browser, 576 SizeTestType type, 577 const std::string& partial_indication, 578 const std::string& total_indication) { 579 if (!InitialSetup(false)) 580 return false; 581 582 EXPECT_TRUE(type == SIZE_TEST_TYPE_UNKNOWN || type == SIZE_TEST_TYPE_KNOWN); 583 if (type != SIZE_TEST_TYPE_KNOWN && type != SIZE_TEST_TYPE_UNKNOWN) 584 return false; 585 GURL url(type == SIZE_TEST_TYPE_KNOWN ? 586 URLRequestSlowDownloadJob::kKnownSizeUrl : 587 URLRequestSlowDownloadJob::kUnknownSizeUrl); 588 589 // TODO(ahendrickson) -- |expected_title_in_progress| and 590 // |expected_title_finished| need to be checked. 591 FilePath filename; 592 net::FileURLToFilePath(url, &filename); 593 string16 expected_title_in_progress( 594 ASCIIToUTF16(partial_indication) + filename.LossyDisplayName()); 595 string16 expected_title_finished( 596 ASCIIToUTF16(total_indication) + filename.LossyDisplayName()); 597 598 // Download a partial web page in a background tab and wait. 599 // The mock system will not complete until it gets a special URL. 600 scoped_ptr<DownloadsObserver> observer(CreateWaiter(browser, 1)); 601 ui_test_utils::NavigateToURL(browser, url); 602 603 // TODO(ahendrickson): check download status text before downloading. 604 // Need to: 605 // - Add a member function to the |DownloadShelf| interface class, that 606 // indicates how many members it has. 607 // - Add a member function to |DownloadShelf| to get the status text 608 // of a given member (for example, via the name in |DownloadItemView|'s 609 // GetAccessibleState() member function), by index. 610 // - Iterate over browser->window()->GetDownloadShelf()'s members 611 // to see if any match the status text we want. Start with the last one. 612 613 // Allow the request to finish. We do this by loading a second URL in a 614 // separate tab. 615 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); 616 ui_test_utils::NavigateToURLWithDisposition( 617 browser, 618 finish_url, 619 NEW_FOREGROUND_TAB, 620 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 621 observer->WaitForFinished(); 622 623 EXPECT_EQ(2, browser->tab_count()); 624 625 // TODO(ahendrickson): check download status text after downloading. 626 627 // Make sure the download shelf is showing. 628 EXPECT_TRUE(IsDownloadUIVisible(browser)); 629 630 FilePath basefilename(filename.BaseName()); 631 net::FileURLToFilePath(url, &filename); 632 FilePath download_path = downloads_directory_.path().Append(basefilename); 633 634 bool downloaded_path_exists = file_util::PathExists(download_path); 635 EXPECT_TRUE(downloaded_path_exists); 636 if (!downloaded_path_exists) 637 return false; 638 639 // Delete the file we just downloaded. 640 EXPECT_TRUE(file_util::DieFileDie(download_path, true)); 641 EXPECT_FALSE(file_util::PathExists(download_path)); 642 643 return true; 644 } 645 646 void GetDownloads(Browser* browser, std::vector<DownloadItem*>* downloads) { 647 DCHECK(downloads); 648 DownloadManager* manager = browser->profile()->GetDownloadManager(); 649 manager->SearchDownloads(string16(), downloads); 650 } 651 652 // Figure out if the appropriate download visibility was done. A 653 // utility function to support ChromeOS variations. On ChromeOS 654 // a webui panel is used instead of the download shelf; the 655 // test for TYPE_APP_PANEL detects this type of panel. 656 static bool IsDownloadUIVisible(Browser* browser) { 657 #if defined(OS_CHROMEOS) 658 for (BrowserList::const_iterator it = BrowserList::begin(); 659 it != BrowserList::end(); ++it) { 660 if ((*it)->type() == Browser::TYPE_APP_PANEL) { 661 return true; 662 } 663 } 664 return false; 665 #else 666 return browser->window()->IsDownloadShelfVisible(); 667 #endif 668 } 669 670 static void ExpectWindowCountAfterDownload(size_t expected) { 671 #if defined(OS_CHROMEOS) 672 // On ChromeOS, a download panel is created to display 673 // download information, and this counts as a window. 674 expected++; 675 #endif 676 EXPECT_EQ(expected, BrowserList::size()); 677 } 678 679 private: 680 // Location of the test data. 681 FilePath test_dir_; 682 683 // Location of the downloads directory for these tests 684 ScopedTempDir downloads_directory_; 685 }; 686 687 // Get History Information. 688 class DownloadsHistoryDataCollector { 689 public: 690 explicit DownloadsHistoryDataCollector(int64 download_db_handle, 691 DownloadManager* manager) 692 : result_valid_(false), 693 download_db_handle_(download_db_handle) { 694 HistoryService* hs = 695 manager->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); 696 DCHECK(hs); 697 hs->QueryDownloads( 698 &callback_consumer_, 699 NewCallback(this, 700 &DownloadsHistoryDataCollector::OnQueryDownloadsComplete)); 701 702 // Cannot complete immediately because the history backend runs on a 703 // separate thread, so we can assume that the RunMessageLoop below will 704 // be exited by the Quit in OnQueryDownloadsComplete. 705 ui_test_utils::RunMessageLoop(); 706 } 707 708 bool GetDownloadsHistoryEntry(DownloadCreateInfo* result) { 709 DCHECK(result); 710 *result = result_; 711 return result_valid_; 712 } 713 714 private: 715 void OnQueryDownloadsComplete( 716 std::vector<DownloadCreateInfo>* entries) { 717 result_valid_ = false; 718 for (std::vector<DownloadCreateInfo>::const_iterator it = entries->begin(); 719 it != entries->end(); ++it) { 720 if (it->db_handle == download_db_handle_) { 721 result_ = *it; 722 result_valid_ = true; 723 } 724 } 725 MessageLoopForUI::current()->Quit(); 726 } 727 728 DownloadCreateInfo result_; 729 bool result_valid_; 730 int64 download_db_handle_; 731 CancelableRequestConsumer callback_consumer_; 732 733 DISALLOW_COPY_AND_ASSIGN(DownloadsHistoryDataCollector); 734 }; 735 736 // NOTES: 737 // 738 // Files for these tests are found in DIR_TEST_DATA (currently 739 // "chrome\test\data\", see chrome_paths.cc). 740 // Mock responses have extension .mock-http-headers appended to the file name. 741 742 // Download a file due to the associated MIME type. 743 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadMimeType) { 744 ASSERT_TRUE(InitialSetup(false)); 745 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 746 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 747 748 // Download the file and wait. We do not expect the Select File dialog. 749 DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG); 750 751 // Check state. 752 EXPECT_EQ(1, browser()->tab_count()); 753 CheckDownload(browser(), file, file); 754 EXPECT_TRUE(IsDownloadUIVisible(browser())); 755 } 756 757 #if defined(OS_WIN) 758 // Download a file and confirm that the zone identifier (on windows) 759 // is set to internet. 760 IN_PROC_BROWSER_TEST_F(DownloadTest, CheckInternetZone) { 761 ASSERT_TRUE(InitialSetup(false)); 762 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 763 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 764 765 // Download the file and wait. We do not expect the Select File dialog. 766 DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG); 767 768 // Check state. Special file state must be checked before CheckDownload, 769 // as CheckDownload will delete the output file. 770 EXPECT_EQ(1, browser()->tab_count()); 771 FilePath downloaded_file(DestinationFile(browser(), file)); 772 if (file_util::VolumeSupportsADS(downloaded_file)) 773 EXPECT_TRUE(file_util::HasInternetZoneIdentifier(downloaded_file)); 774 CheckDownload(browser(), file, file); 775 EXPECT_TRUE(IsDownloadUIVisible(browser())); 776 } 777 #endif 778 779 // Put up a Select File dialog when the file is downloaded, due to its MIME 780 // type. 781 // 782 // This test runs correctly, but leaves behind turds in the test user's 783 // download directory because of http://crbug.com/62099. No big loss; it 784 // was primarily confirming DownloadsObserver wait on select file dialog 785 // functionality anyway. 786 IN_PROC_BROWSER_TEST_F(DownloadTest, DISABLED_DownloadMimeTypeSelect) { 787 ASSERT_TRUE(InitialSetup(true)); 788 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 789 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 790 791 // Download the file and wait. We expect the Select File dialog to appear 792 // due to the MIME type. 793 DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG); 794 795 // Check state. 796 EXPECT_EQ(1, browser()->tab_count()); 797 // Since we exited while the Select File dialog was visible, there should not 798 // be anything in the download shelf and so it should not be visible. 799 EXPECT_FALSE(IsDownloadUIVisible(browser())); 800 } 801 802 // Access a file with a viewable mime-type, verify that a download 803 // did not initiate. 804 IN_PROC_BROWSER_TEST_F(DownloadTest, NoDownload) { 805 ASSERT_TRUE(InitialSetup(false)); 806 FilePath file(FILE_PATH_LITERAL("download-test2.html")); 807 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 808 FilePath file_path(DestinationFile(browser(), file)); 809 810 // Open a web page and wait. 811 ui_test_utils::NavigateToURL(browser(), url); 812 813 // Check that we did not download the web page. 814 EXPECT_FALSE(file_util::PathExists(file_path)); 815 816 // Check state. 817 EXPECT_EQ(1, browser()->tab_count()); 818 EXPECT_FALSE(IsDownloadUIVisible(browser())); 819 } 820 821 // Download a 0-size file with a content-disposition header, verify that the 822 // download tab opened and the file exists as the filename specified in the 823 // header. This also ensures we properly handle empty file downloads. 824 // The download shelf should be visible in the current tab. 825 IN_PROC_BROWSER_TEST_F(DownloadTest, ContentDisposition) { 826 ASSERT_TRUE(InitialSetup(false)); 827 FilePath file(FILE_PATH_LITERAL("download-test3.gif")); 828 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 829 FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif")); 830 831 // Download a file and wait. 832 DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG); 833 834 CheckDownload(browser(), download_file, file); 835 836 // Check state. 837 EXPECT_EQ(1, browser()->tab_count()); 838 EXPECT_TRUE(IsDownloadUIVisible(browser())); 839 } 840 841 #if !defined(OS_CHROMEOS) // Download shelf is not per-window on ChromeOS. 842 // Test that the download shelf is per-window by starting a download in one 843 // tab, opening a second tab, closing the shelf, going back to the first tab, 844 // and checking that the shelf is closed. 845 IN_PROC_BROWSER_TEST_F(DownloadTest, PerWindowShelf) { 846 ASSERT_TRUE(InitialSetup(false)); 847 FilePath file(FILE_PATH_LITERAL("download-test3.gif")); 848 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 849 FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif")); 850 851 // Download a file and wait. 852 DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG); 853 854 CheckDownload(browser(), download_file, file); 855 856 // Check state. 857 EXPECT_EQ(1, browser()->tab_count()); 858 EXPECT_TRUE(IsDownloadUIVisible(browser())); 859 860 // Open a second tab and wait. 861 EXPECT_NE(static_cast<TabContentsWrapper*>(NULL), 862 browser()->AddSelectedTabWithURL(GURL(), PageTransition::TYPED)); 863 EXPECT_EQ(2, browser()->tab_count()); 864 EXPECT_TRUE(IsDownloadUIVisible(browser())); 865 866 // Hide the download shelf. 867 browser()->window()->GetDownloadShelf()->Close(); 868 EXPECT_FALSE(IsDownloadUIVisible(browser())); 869 870 // Go to the first tab. 871 browser()->ActivateTabAt(0, true); 872 EXPECT_EQ(2, browser()->tab_count()); 873 874 // The download shelf should not be visible. 875 EXPECT_FALSE(IsDownloadUIVisible(browser())); 876 } 877 #endif // !OS_CHROMEOS 878 879 // UnknownSize and KnownSize are tests which depend on 880 // URLRequestSlowDownloadJob to serve content in a certain way. Data will be 881 // sent in two chunks where the first chunk is 35K and the second chunk is 10K. 882 // The test will first attempt to download a file; but the server will "pause" 883 // in the middle until the server receives a second request for 884 // "download-finish". At that time, the download will finish. 885 // These tests don't currently test much due to holes in |RunSizeTest()|. See 886 // comments in that routine for details. 887 IN_PROC_BROWSER_TEST_F(DownloadTest, UnknownSize) { 888 ASSERT_TRUE(RunSizeTest(browser(), SIZE_TEST_TYPE_UNKNOWN, 889 "32.0 KB - ", "100% - ")); 890 } 891 892 IN_PROC_BROWSER_TEST_F(DownloadTest, KnownSize) { 893 ASSERT_TRUE(RunSizeTest(browser(), SIZE_TEST_TYPE_KNOWN, 894 "71% - ", "100% - ")); 895 } 896 897 // Test that when downloading an item in Incognito mode, we don't crash when 898 // closing the last Incognito window (http://crbug.com/13983). 899 // Also check that the download shelf is not visible after closing the 900 // Incognito window. 901 IN_PROC_BROWSER_TEST_F(DownloadTest, IncognitoDownload) { 902 ASSERT_TRUE(InitialSetup(false)); 903 904 // Open an Incognito window. 905 Browser* incognito = CreateIncognitoBrowser(); // Waits. 906 ASSERT_TRUE(incognito); 907 int window_count = BrowserList::size(); 908 EXPECT_EQ(2, window_count); 909 910 // Download a file in the Incognito window and wait. 911 CreateAndSetDownloadsDirectory(incognito); 912 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 913 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 914 // Since |incognito| is a separate browser, we have to set it up explicitly. 915 incognito->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload, 916 false); 917 DownloadAndWait(incognito, url, EXPECT_NO_SELECT_DIALOG); 918 919 // We should still have 2 windows. 920 ExpectWindowCountAfterDownload(2); 921 922 // Verify that the download shelf is showing for the Incognito window. 923 bool is_shelf_visible = IsDownloadUIVisible(incognito); 924 EXPECT_TRUE(is_shelf_visible); 925 926 // Close the Incognito window and don't crash. 927 incognito->CloseWindow(); 928 #if !defined(OS_MACOSX) 929 // On Mac OS X, the UI window close is delayed until the outermost 930 // message loop runs. So it isn't possible to get a BROWSER_CLOSED 931 // notification inside of a test. 932 ui_test_utils::WaitForNotificationFrom(NotificationType::BROWSER_CLOSED, 933 Source<Browser>(incognito)); 934 935 ExpectWindowCountAfterDownload(1); 936 #endif 937 938 // Verify that the regular window does not have a download shelf. 939 is_shelf_visible = IsDownloadUIVisible(browser()); 940 941 #if defined(OS_CHROMEOS) 942 // On ChromeOS it's a popup rather than a download shelf, and it sticks 943 // around. 944 EXPECT_TRUE(is_shelf_visible); 945 #else 946 EXPECT_FALSE(is_shelf_visible); 947 #endif 948 949 CheckDownload(browser(), file, file); 950 } 951 952 // Navigate to a new background page, but don't download. Confirm that the 953 // download shelf is not visible and that we have two tabs. 954 IN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab1) { 955 ASSERT_TRUE(InitialSetup(false)); 956 // Because it's an HTML link, it should open a web page rather than 957 // downloading. 958 FilePath file1(FILE_PATH_LITERAL("download-test2.html")); 959 GURL url(URLRequestMockHTTPJob::GetMockUrl(file1)); 960 961 // Open a web page and wait. 962 ui_test_utils::NavigateToURLWithDisposition( 963 browser(), 964 url, 965 NEW_BACKGROUND_TAB, 966 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 967 968 // We should have two tabs now. 969 EXPECT_EQ(2, browser()->tab_count()); 970 EXPECT_FALSE(IsDownloadUIVisible(browser())); 971 } 972 973 // Download a file in a background tab. Verify that the tab is closed 974 // automatically, and that the download shelf is visible in the current tab. 975 IN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab1) { 976 ASSERT_TRUE(InitialSetup(false)); 977 978 // Download a file in a new background tab and wait. The tab is automatically 979 // closed when the download begins. 980 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 981 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 982 DownloadAndWaitWithDisposition( 983 browser(), 984 url, 985 NEW_BACKGROUND_TAB, 986 EXPECT_NO_SELECT_DIALOG, 987 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 988 989 // When the download finishes, we should still have one tab. 990 EXPECT_TRUE(IsDownloadUIVisible(browser())); 991 EXPECT_EQ(1, browser()->tab_count()); 992 993 CheckDownload(browser(), file, file); 994 } 995 996 // Open a web page in the current tab, then download a file in another tab via 997 // a Javascript call. 998 // Verify that we have 2 tabs, and the download shelf is visible in the current 999 // tab. 1000 // 1001 // The download_page1.html page contains an openNew() function that opens a 1002 // tab and then downloads download-test1.lib. 1003 IN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab2) { 1004 ASSERT_TRUE(InitialSetup(false)); 1005 // Because it's an HTML link, it should open a web page rather than 1006 // downloading. 1007 FilePath file1(FILE_PATH_LITERAL("download_page1.html")); 1008 GURL url(URLRequestMockHTTPJob::GetMockUrl(file1)); 1009 1010 // Open a web page and wait. 1011 ui_test_utils::NavigateToURL(browser(), url); 1012 1013 // Download a file in a new tab and wait (via Javascript). 1014 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 1015 DownloadAndWaitWithDisposition(browser(), 1016 GURL("javascript:openNew()"), 1017 CURRENT_TAB, 1018 EXPECT_NO_SELECT_DIALOG, 1019 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); 1020 1021 // When the download finishes, we should have two tabs. 1022 EXPECT_TRUE(IsDownloadUIVisible(browser())); 1023 EXPECT_EQ(2, browser()->tab_count()); 1024 1025 CheckDownload(browser(), file, file); 1026 } 1027 1028 // Open a web page in the current tab, open another tab via a Javascript call, 1029 // then download a file in the new tab. 1030 // Verify that we have 2 tabs, and the download shelf is visible in the current 1031 // tab. 1032 // 1033 // The download_page2.html page contains an openNew() function that opens a 1034 // tab. 1035 IN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab3) { 1036 ASSERT_TRUE(InitialSetup(false)); 1037 // Because it's an HTML link, it should open a web page rather than 1038 // downloading. 1039 FilePath file1(FILE_PATH_LITERAL("download_page2.html")); 1040 GURL url1(URLRequestMockHTTPJob::GetMockUrl(file1)); 1041 1042 // Open a web page and wait. 1043 ui_test_utils::NavigateToURL(browser(), url1); 1044 1045 // Open a new tab and wait. 1046 ui_test_utils::NavigateToURLWithDisposition( 1047 browser(), 1048 GURL("javascript:openNew()"), 1049 CURRENT_TAB, 1050 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); 1051 1052 EXPECT_EQ(2, browser()->tab_count()); 1053 1054 // Download a file and wait. 1055 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 1056 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 1057 DownloadAndWaitWithDisposition(browser(), 1058 url, 1059 CURRENT_TAB, 1060 EXPECT_NO_SELECT_DIALOG, 1061 ui_test_utils::BROWSER_TEST_NONE); 1062 1063 // When the download finishes, we should have two tabs. 1064 EXPECT_TRUE(IsDownloadUIVisible(browser())); 1065 EXPECT_EQ(2, browser()->tab_count()); 1066 1067 CheckDownload(browser(), file, file); 1068 } 1069 1070 // Open a web page in the current tab, then download a file via Javascript, 1071 // which will do so in a temporary tab. 1072 // Verify that we have 1 tab, and the download shelf is visible. 1073 // 1074 // The download_page3.html page contains an openNew() function that opens a 1075 // tab with download-test1.lib in the URL. When the URL is determined to be 1076 // a download, the tab is closed automatically. 1077 IN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab2) { 1078 ASSERT_TRUE(InitialSetup(false)); 1079 // Because it's an HTML link, it should open a web page rather than 1080 // downloading. 1081 FilePath file1(FILE_PATH_LITERAL("download_page3.html")); 1082 GURL url(URLRequestMockHTTPJob::GetMockUrl(file1)); 1083 1084 // Open a web page and wait. 1085 ui_test_utils::NavigateToURL(browser(), url); 1086 1087 // Download a file and wait. 1088 // The file to download is "download-test1.lib". 1089 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 1090 DownloadAndWaitWithDisposition(browser(), 1091 GURL("javascript:openNew()"), 1092 CURRENT_TAB, 1093 EXPECT_NO_SELECT_DIALOG, 1094 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); 1095 1096 // When the download finishes, we should still have one tab. 1097 EXPECT_TRUE(IsDownloadUIVisible(browser())); 1098 EXPECT_EQ(1, browser()->tab_count()); 1099 1100 CheckDownload(browser(), file, file); 1101 } 1102 1103 // Open a web page in the current tab, then call Javascript via a button to 1104 // download a file in a new tab, which is closed automatically when the 1105 // download begins. 1106 // Verify that we have 1 tab, and the download shelf is visible. 1107 // 1108 // The download_page4.html page contains a form with download-test1.lib as the 1109 // action. 1110 IN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab3) { 1111 ASSERT_TRUE(InitialSetup(false)); 1112 // Because it's an HTML link, it should open a web page rather than 1113 // downloading. 1114 FilePath file1(FILE_PATH_LITERAL("download_page4.html")); 1115 GURL url(URLRequestMockHTTPJob::GetMockUrl(file1)); 1116 1117 // Open a web page and wait. 1118 ui_test_utils::NavigateToURL(browser(), url); 1119 1120 // Download a file in a new tab and wait. The tab will automatically close 1121 // when the download begins. 1122 // The file to download is "download-test1.lib". 1123 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 1124 DownloadAndWaitWithDisposition( 1125 browser(), 1126 GURL("javascript:document.getElementById('form').submit()"), 1127 CURRENT_TAB, 1128 EXPECT_NO_SELECT_DIALOG, 1129 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); 1130 1131 // When the download finishes, we should still have one tab. 1132 EXPECT_TRUE(IsDownloadUIVisible(browser())); 1133 EXPECT_EQ(1, browser()->tab_count()); 1134 1135 CheckDownload(browser(), file, file); 1136 } 1137 1138 // Download a file in a new window. 1139 // Verify that we have 2 windows, and the download shelf is not visible in the 1140 // first window, but is visible in the second window. 1141 // Close the new window. 1142 // Verify that we have 1 window, and the download shelf is not visible. 1143 // 1144 // Regression test for http://crbug.com/44454 1145 IN_PROC_BROWSER_TEST_F(DownloadTest, NewWindow) { 1146 ASSERT_TRUE(InitialSetup(false)); 1147 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 1148 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 1149 #if !defined(OS_MACOSX) 1150 // See below. 1151 Browser* first_browser = browser(); 1152 #endif 1153 1154 // Download a file in a new window and wait. 1155 DownloadAndWaitWithDisposition(browser(), 1156 url, 1157 NEW_WINDOW, 1158 EXPECT_NO_SELECT_DIALOG, 1159 ui_test_utils::BROWSER_TEST_NONE); 1160 1161 // When the download finishes, the download shelf SHOULD NOT be visible in 1162 // the first window. 1163 ExpectWindowCountAfterDownload(2); 1164 EXPECT_EQ(1, browser()->tab_count()); 1165 #if defined(OS_CHROMEOS) 1166 // Except on chromeos the download UI isn't window-specific. 1167 EXPECT_TRUE(IsDownloadUIVisible(browser())); 1168 #else 1169 EXPECT_FALSE(IsDownloadUIVisible(browser())); 1170 #endif 1171 1172 // The download shelf SHOULD be visible in the second window. 1173 std::set<Browser*> original_browsers; 1174 original_browsers.insert(browser()); 1175 Browser* download_browser = 1176 ui_test_utils::GetBrowserNotInSet(original_browsers); 1177 ASSERT_TRUE(download_browser != NULL); 1178 EXPECT_NE(download_browser, browser()); 1179 EXPECT_EQ(1, download_browser->tab_count()); 1180 EXPECT_TRUE(IsDownloadUIVisible(download_browser)); 1181 1182 // Close the new window. 1183 download_browser->CloseWindow(); 1184 #if !defined(OS_MACOSX) 1185 // On Mac OS X, the UI window close is delayed until the outermost 1186 // message loop runs. So it isn't possible to get a BROWSER_CLOSED 1187 // notification inside of a test. 1188 ui_test_utils::WaitForNotificationFrom(NotificationType::BROWSER_CLOSED, 1189 Source<Browser>(download_browser)); 1190 EXPECT_EQ(first_browser, browser()); 1191 ExpectWindowCountAfterDownload(1); 1192 #endif 1193 1194 EXPECT_EQ(1, browser()->tab_count()); 1195 #if defined(OS_CHROMEOS) 1196 // On ChromeOS the popup sticks around. 1197 EXPECT_TRUE(IsDownloadUIVisible(browser())); 1198 #else 1199 // Otherwise, the download shelf should not be visible in the 1200 // remaining window. 1201 EXPECT_FALSE(IsDownloadUIVisible(browser())); 1202 #endif 1203 1204 CheckDownload(browser(), file, file); 1205 } 1206 1207 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadCancelled) { 1208 ASSERT_TRUE(InitialSetup(false)); 1209 EXPECT_EQ(1, browser()->tab_count()); 1210 1211 // TODO(rdsmith): Fragile code warning! The code below relies on the 1212 // DownloadsObserver only finishing when the new download has reached 1213 // the state of being entered into the history and being user-visible 1214 // (that's what's required for the Remove to be valid and for the 1215 // download shelf to be visible). By the pure semantics of 1216 // DownloadsObserver, that's not guaranteed; DownloadItems are created 1217 // in the IN_PROGRESS state and made known to the DownloadManager 1218 // immediately, so any ModelChanged event on the DownloadManager after 1219 // navigation would allow the observer to return. However, the only 1220 // ModelChanged() event the code will currently fire is in 1221 // OnCreateDownloadEntryComplete, at which point the download item will 1222 // be in the state we need. 1223 // The right way to fix this is to create finer grained states on the 1224 // DownloadItem, and wait for the state that indicates the item has been 1225 // entered in the history and made visible in the UI. 1226 1227 // Create a download, wait until it's started, and confirm 1228 // we're in the expected state. 1229 scoped_ptr<DownloadsObserver> observer(CreateInProgressWaiter(browser(), 1)); 1230 ui_test_utils::NavigateToURL( 1231 browser(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl)); 1232 observer->WaitForFinished(); 1233 1234 std::vector<DownloadItem*> downloads; 1235 browser()->profile()->GetDownloadManager()->SearchDownloads( 1236 string16(), &downloads); 1237 ASSERT_EQ(1u, downloads.size()); 1238 ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->state()); 1239 EXPECT_TRUE(IsDownloadUIVisible(browser())); 1240 1241 // Cancel the download and wait for download system quiesce. 1242 downloads[0]->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); 1243 scoped_refptr<DownloadsFlushObserver> flush_observer( 1244 new DownloadsFlushObserver(browser()->profile()->GetDownloadManager())); 1245 flush_observer->WaitForFlush(); 1246 1247 // Get the important info from other threads and check it. 1248 scoped_refptr<CancelTestDataCollector> info(new CancelTestDataCollector()); 1249 info->WaitForDataCollected(); 1250 EXPECT_EQ(0, info->rdh_pending_requests()); 1251 EXPECT_EQ(0, info->dfm_pending_downloads()); 1252 1253 // Using "DownloadItem::Remove" follows the discard dangerous download path, 1254 // which completely removes the browser from the shelf and closes the shelf 1255 // if it was there. 1256 #if defined(OS_CHROMEOS) 1257 // Except under ChromeOS in which case if we've brought up the file 1258 // picker panel, it stays. 1259 EXPECT_TRUE(IsDownloadUIVisible(browser())); 1260 #else 1261 EXPECT_FALSE(IsDownloadUIVisible(browser())); 1262 #endif 1263 } 1264 1265 // Confirm a download makes it into the history properly. 1266 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadHistoryCheck) { 1267 ASSERT_TRUE(InitialSetup(false)); 1268 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 1269 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 1270 FilePath origin_file(OriginFile(file)); 1271 int64 origin_size; 1272 file_util::GetFileSize(origin_file, &origin_size); 1273 1274 // Download the file and wait. We do not expect the Select File dialog. 1275 DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG); 1276 1277 // Get details of what downloads have just happened. 1278 std::vector<DownloadItem*> downloads; 1279 GetDownloads(browser(), &downloads); 1280 ASSERT_EQ(1u, downloads.size()); 1281 int64 db_handle = downloads[0]->db_handle(); 1282 1283 // Check state. 1284 EXPECT_EQ(1, browser()->tab_count()); 1285 CheckDownload(browser(), file, file); 1286 EXPECT_TRUE(IsDownloadUIVisible(browser())); 1287 1288 // Check history results. 1289 DownloadsHistoryDataCollector history_collector( 1290 db_handle, 1291 browser()->profile()->GetDownloadManager()); 1292 DownloadCreateInfo info; 1293 EXPECT_TRUE(history_collector.GetDownloadsHistoryEntry(&info)) << db_handle; 1294 EXPECT_EQ(file, info.path.BaseName()); 1295 EXPECT_EQ(url, info.url()); 1296 // Ignore start_time. 1297 EXPECT_EQ(origin_size, info.received_bytes); 1298 EXPECT_EQ(origin_size, info.total_bytes); 1299 EXPECT_EQ(DownloadItem::COMPLETE, info.state); 1300 } 1301