Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This file contains download browser tests that are known to be runnable | 5 // This file contains download browser tests that are known to be runnable |
| 6 // in a pure content context. Over time tests should be migrated here. | 6 // in a pure content context. Over time tests should be migrated here. |
| 7 | 7 |
| 8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/scoped_temp_dir.h" | 10 #include "base/scoped_temp_dir.h" |
| 11 #include "content/browser/download/download_file_factory.h" | |
| 12 #include "content/browser/download/download_file_impl.h" | |
| 11 #include "content/browser/download/download_item_impl.h" | 13 #include "content/browser/download/download_item_impl.h" |
| 12 #include "content/browser/download/download_manager_impl.h" | 14 #include "content/browser/download/download_manager_impl.h" |
| 15 #include "content/browser/power_save_blocker.h" | |
| 13 #include "content/browser/web_contents/web_contents_impl.h" | 16 #include "content/browser/web_contents/web_contents_impl.h" |
| 14 #include "content/public/test/download_test_observer.h" | 17 #include "content/public/test/download_test_observer.h" |
| 18 #include "content/public/test/test_utils.h" | |
| 15 #include "content/shell/shell.h" | 19 #include "content/shell/shell.h" |
| 16 #include "content/shell/shell_browser_context.h" | 20 #include "content/shell/shell_browser_context.h" |
| 17 #include "content/shell/shell_download_manager_delegate.h" | 21 #include "content/shell/shell_download_manager_delegate.h" |
| 18 #include "content/test/content_browser_test.h" | 22 #include "content/test/content_browser_test.h" |
| 19 #include "content/test/content_browser_test_utils.h" | 23 #include "content/test/content_browser_test_utils.h" |
| 20 #include "content/test/net/url_request_mock_http_job.h" | 24 #include "content/test/net/url_request_mock_http_job.h" |
| 21 #include "content/test/net/url_request_slow_download_job.h" | 25 #include "content/test/net/url_request_slow_download_job.h" |
| 22 #include "googleurl/src/gurl.h" | 26 #include "googleurl/src/gurl.h" |
| 23 | 27 |
| 24 namespace content { | 28 namespace content { |
| 25 | 29 |
| 26 namespace { | 30 namespace { |
| 27 | 31 |
| 28 static DownloadManager* DownloadManagerForShell(Shell* shell) { | 32 class DownloadFileWithDelayFactory; |
| 29 return BrowserContext::GetDownloadManager( | 33 |
| 30 shell->web_contents()->GetBrowserContext()); | 34 static DownloadManagerImpl* DownloadManagerForShell(Shell* shell) { |
| 35 // We're in a content_browsertest; we know that the DownloadManager | |
| 36 // is a DownloadManagerImpl. | |
| 37 return static_cast<DownloadManagerImpl*>( | |
| 38 BrowserContext::GetDownloadManager( | |
| 39 shell->web_contents()->GetBrowserContext())); | |
| 40 } | |
| 41 | |
| 42 class DownloadFileWithDelay : public DownloadFileImpl { | |
| 43 public: | |
| 44 DownloadFileWithDelay( | |
| 45 const content::DownloadSaveInfo& save_info, | |
| 46 const GURL& url, | |
| 47 const GURL& referrer_url, | |
| 48 int64 received_bytes, | |
| 49 bool calculate_hash, | |
| 50 scoped_ptr<content::ByteStreamReader> stream, | |
| 51 const net::BoundNetLog& bound_net_log, | |
| 52 scoped_ptr<content::PowerSaveBlocker> power_save_blocker, | |
| 53 base::WeakPtr<content::DownloadDestinationObserver> observer, | |
| 54 base::WeakPtr<DownloadFileWithDelayFactory> owner); | |
| 55 | |
|
benjhayden
2012/09/12 21:01:01
Don't you need a virtual destructor?
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
Done.
| |
| 56 // Wraps DownloadFileImpl::Rename and intercepts the return callback, | |
| 57 // storing it in the factory that produced this object for later | |
| 58 // retrieval. | |
| 59 virtual void Rename(const FilePath& full_path, | |
| 60 bool overwrite_existing_file, | |
| 61 const RenameCompletionCallback& callback) OVERRIDE; | |
| 62 | |
| 63 // Wraps DownloadFileImpl::Detach and intercepts the return callback, | |
| 64 // storing it in the factory that produced this object for later | |
|
benjhayden
2012/09/12 21:01:01
double space
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
Done.
| |
| 65 // retrieval. | |
| 66 virtual void Detach(base::Closure callback) OVERRIDE; | |
| 67 | |
| 68 private: | |
| 69 // Must be called on the UI thread. | |
| 70 static void RenameCallbackWrapper( | |
| 71 DownloadFileWithDelayFactory* factory, | |
| 72 const RenameCompletionCallback& original_callback, | |
| 73 content::DownloadInterruptReason reason, | |
| 74 const FilePath& path); | |
| 75 | |
| 76 // Must be called on the UI thread. | |
|
benjhayden
2012/09/12 21:01:01
Instead of these comments, can you just have the D
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
I don't consider the two equivalent; one's interfa
| |
| 77 static void DetachCallbackWrapper( | |
| 78 DownloadFileWithDelayFactory* factory, | |
| 79 const base::Closure& original_callback); | |
| 80 | |
| 81 // Must only be accessed on the FILE thread; must be used only on the | |
|
benjhayden
2012/09/12 21:01:01
What's the difference between access and use?
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
The variable must be read on the FILE thread, and
| |
| 82 // UI thread. (This object lives on the file thread, and the | |
| 83 // DownloadFileWithDelayFactory lives on the UI thread). | |
| 84 base::WeakPtr<DownloadFileWithDelayFactory> owner_; | |
| 85 }; | |
| 86 | |
| 87 // All routines on this class must be called on the UI thread. | |
| 88 class DownloadFileWithDelayFactory : public DownloadFileFactory { | |
| 89 public: | |
| 90 DownloadFileWithDelayFactory(); | |
| 91 virtual ~DownloadFileWithDelayFactory(); | |
| 92 | |
| 93 // DownloadFileFactory interface. | |
| 94 virtual DownloadFile* CreateFile( | |
| 95 const content::DownloadSaveInfo& save_info, | |
| 96 GURL url, | |
| 97 GURL referrer_url, | |
| 98 int64 received_bytes, | |
| 99 bool calculate_hash, | |
| 100 scoped_ptr<content::ByteStreamReader> stream, | |
| 101 const net::BoundNetLog& bound_net_log, | |
| 102 base::WeakPtr<content::DownloadDestinationObserver> observer) OVERRIDE; | |
| 103 | |
| 104 void PostRenameCallback(base::Closure callback); | |
|
benjhayden
2012/09/12 21:01:01
s/Post/Add/g ?
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
Done.
| |
| 105 void PostDetachCallback(base::Closure callback); | |
| 106 void GetRenameCallbacks(std::vector<base::Closure>* results); | |
|
benjhayden
2012/09/12 21:01:01
s/Get/GetAll/g ?
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
Done.
| |
| 107 void GetDetachCallbacks(std::vector<base::Closure>* results); | |
| 108 | |
| 109 // Do not return until either GetRenameCallbacks() or GetDetachCallbacks() | |
| 110 // will return a non-empty list. | |
| 111 void WaitForSomeCallback(); | |
| 112 | |
| 113 private: | |
| 114 base::WeakPtrFactory<DownloadFileWithDelayFactory> factory_; | |
|
benjhayden
2012/09/12 21:01:01
weak_ptr_factor_?
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
Done.
| |
| 115 std::vector<base::Closure> rename_callbacks_; | |
| 116 std::vector<base::Closure> detach_callbacks_; | |
| 117 bool waiting_; | |
| 118 }; | |
|
benjhayden
2012/09/12 21:01:01
DISALLOW_COPY_AND_ASSIGN?
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
Done.
| |
| 119 | |
| 120 DownloadFileWithDelay::DownloadFileWithDelay( | |
|
benjhayden
2012/09/12 21:01:01
Since we're in a test, would you mind defining the
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
I started out doing that. The problem is that the
| |
| 121 const content::DownloadSaveInfo& save_info, | |
| 122 const GURL& url, | |
| 123 const GURL& referrer_url, | |
| 124 int64 received_bytes, | |
| 125 bool calculate_hash, | |
| 126 scoped_ptr<content::ByteStreamReader> stream, | |
| 127 const net::BoundNetLog& bound_net_log, | |
| 128 scoped_ptr<content::PowerSaveBlocker> power_save_blocker, | |
| 129 base::WeakPtr<content::DownloadDestinationObserver> observer, | |
| 130 base::WeakPtr<DownloadFileWithDelayFactory> owner) | |
| 131 : DownloadFileImpl( | |
| 132 save_info, url, referrer_url, received_bytes, calculate_hash, | |
| 133 stream.Pass(), bound_net_log, power_save_blocker.Pass(), | |
| 134 observer), | |
| 135 owner_(owner) {} | |
| 136 | |
| 137 void DownloadFileWithDelay::Rename(const FilePath& full_path, | |
| 138 bool overwrite_existing_file, | |
| 139 const RenameCompletionCallback& callback) { | |
| 140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 141 DownloadFileImpl::Rename( | |
| 142 full_path, overwrite_existing_file, | |
| 143 base::Bind(DownloadFileWithDelay::RenameCallbackWrapper, | |
| 144 owner_, callback)); | |
| 145 } | |
| 146 | |
| 147 void DownloadFileWithDelay::Detach(base::Closure callback) { | |
| 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 149 DownloadFileImpl::Detach( | |
| 150 base::Bind(DownloadFileWithDelay::DetachCallbackWrapper, | |
| 151 owner_, callback)); | |
| 152 } | |
| 153 | |
| 154 // static | |
| 155 void DownloadFileWithDelay::RenameCallbackWrapper( | |
| 156 DownloadFileWithDelayFactory* factory, | |
| 157 const RenameCompletionCallback& original_callback, | |
| 158 content::DownloadInterruptReason reason, | |
| 159 const FilePath& path) { | |
| 160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 161 factory->PostRenameCallback(base::Bind(original_callback, reason, path)); | |
| 162 } | |
| 163 | |
| 164 // static | |
| 165 void DownloadFileWithDelay::DetachCallbackWrapper( | |
| 166 DownloadFileWithDelayFactory* factory, | |
| 167 const base::Closure& original_callback) { | |
| 168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 169 factory->PostDetachCallback(original_callback); | |
| 170 } | |
| 171 | |
| 172 DownloadFileWithDelayFactory::DownloadFileWithDelayFactory() | |
| 173 : factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | |
| 174 waiting_(false) {} | |
| 175 DownloadFileWithDelayFactory::~DownloadFileWithDelayFactory() {} | |
| 176 | |
| 177 DownloadFile* DownloadFileWithDelayFactory::CreateFile( | |
| 178 const content::DownloadSaveInfo& save_info, | |
| 179 GURL url, | |
| 180 GURL referrer_url, | |
| 181 int64 received_bytes, | |
| 182 bool calculate_hash, | |
| 183 scoped_ptr<content::ByteStreamReader> stream, | |
| 184 const net::BoundNetLog& bound_net_log, | |
| 185 base::WeakPtr<content::DownloadDestinationObserver> observer) { | |
| 186 scoped_ptr<content::PowerSaveBlocker> psb( | |
| 187 new content::PowerSaveBlocker( | |
| 188 content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, | |
| 189 "Download in progress")); | |
| 190 return new DownloadFileWithDelay( | |
| 191 save_info, url, referrer_url, received_bytes, calculate_hash, | |
| 192 stream.Pass(), bound_net_log, psb.Pass(), observer, | |
| 193 factory_.GetWeakPtr()); | |
| 194 } | |
| 195 | |
| 196 void DownloadFileWithDelayFactory::PostRenameCallback(base::Closure callback) { | |
| 197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 198 rename_callbacks_.push_back(callback); | |
| 199 if (waiting_) | |
| 200 MessageLoopForUI::current()->Quit(); | |
| 201 } | |
| 202 | |
| 203 void DownloadFileWithDelayFactory::PostDetachCallback(base::Closure callback) { | |
| 204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 205 detach_callbacks_.push_back(callback); | |
| 206 if (waiting_) | |
| 207 MessageLoopForUI::current()->Quit(); | |
| 208 } | |
| 209 | |
| 210 void DownloadFileWithDelayFactory::GetRenameCallbacks( | |
| 211 std::vector<base::Closure>* results) { | |
| 212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 213 results->swap(rename_callbacks_); | |
| 214 } | |
| 215 | |
| 216 void DownloadFileWithDelayFactory::GetDetachCallbacks( | |
| 217 std::vector<base::Closure>* results) { | |
| 218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 219 results->swap(detach_callbacks_); | |
| 220 } | |
| 221 | |
| 222 void DownloadFileWithDelayFactory::WaitForSomeCallback() { | |
| 223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 224 | |
| 225 while (rename_callbacks_.empty() && detach_callbacks_.empty()) { | |
|
benjhayden
2012/09/12 21:01:01
'while' or 'if'?
Randy Smith (Not in Mondays)
2012/09/13 20:15:12
Presuming comment means you prefer 'if'; done.
(T
| |
| 226 waiting_ = true; | |
| 227 RunMessageLoop(); | |
| 228 waiting_ = false; | |
| 229 } | |
| 31 } | 230 } |
| 32 | 231 |
| 33 } // namespace | 232 } // namespace |
| 34 | 233 |
| 35 class DownloadContentTest : public ContentBrowserTest { | 234 class DownloadContentTest : public ContentBrowserTest { |
| 36 protected: | 235 protected: |
| 37 virtual void SetUpOnMainThread() OVERRIDE { | 236 virtual void SetUpOnMainThread() OVERRIDE { |
| 38 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); | 237 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); |
| 39 | 238 |
| 40 ShellDownloadManagerDelegate* delegate = | 239 ShellDownloadManagerDelegate* delegate = |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 *result = false; | 319 *result = false; |
| 121 BrowserThread::PostTask( | 320 BrowserThread::PostTask( |
| 122 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); | 321 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); |
| 123 } | 322 } |
| 124 | 323 |
| 125 // Location of the downloads directory for these tests | 324 // Location of the downloads directory for these tests |
| 126 ScopedTempDir downloads_directory_; | 325 ScopedTempDir downloads_directory_; |
| 127 }; | 326 }; |
| 128 | 327 |
| 129 IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) { | 328 IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) { |
| 130 // TODO(rdsmith): Fragile code warning! The code below relies on the | 329 // TODO(rdsmith): Fragile code warning! The code below relies on |
| 131 // DownloadTestObserverInProgress only finishing when the new download | 330 // the DownloadTestObserverInProgress only finishing when the new |
| 132 // has reached the state of being entered into the history and being | 331 // download has reached the state of being entered into the history |
| 133 // user-visible (that's what's required for the Remove to be valid and | 332 // and being user-visible (that's what's required for the Remove to |
| 134 // for the download shelf to be visible). By the pure semantics of | 333 // be valid). By the pure semantics of |
| 135 // DownloadTestObserverInProgress, that's not guaranteed; DownloadItems | 334 // DownloadTestObserverInProgress, that's not guaranteed; |
| 136 // are created in the IN_PROGRESS state and made known to the DownloadManager | 335 // DownloadItems are created in the IN_PROGRESS state and made known |
| 137 // immediately, so any ModelChanged event on the DownloadManager after | 336 // to the DownloadManager immediately, so any ModelChanged event on |
| 138 // navigation would allow the observer to return. However, the only | 337 // the DownloadManager after navigation would allow the observer to |
| 139 // ModelChanged() event the code will currently fire is in | 338 // return. However, the only ModelChanged() event the code will |
| 140 // OnCreateDownloadEntryComplete, at which point the download item will | 339 // currently fire is in OnCreateDownloadEntryComplete, at which |
| 141 // be in the state we need. | 340 // point the download item will be in the state we need. |
| 142 // The right way to fix this is to create finer grained states on the | 341 // The right way to fix this is to create finer grained states on the |
| 143 // DownloadItem, and wait for the state that indicates the item has been | 342 // DownloadItem, and wait for the state that indicates the item has been |
| 144 // entered in the history and made visible in the UI. | 343 // entered in the history and made visible in the UI. |
| 145 | 344 |
| 146 // Create a download, wait until it's started, and confirm | 345 // Create a download, wait until it's started, and confirm |
| 147 // we're in the expected state. | 346 // we're in the expected state. |
| 148 scoped_ptr<DownloadTestObserver> observer(CreateInProgressWaiter(shell(), 1)); | 347 scoped_ptr<DownloadTestObserver> observer(CreateInProgressWaiter(shell(), 1)); |
| 149 NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl)); | 348 NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl)); |
| 150 observer->WaitForFinished(); | 349 observer->WaitForFinished(); |
| 151 | 350 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 213 size_t file_size1 = URLRequestSlowDownloadJob::kFirstDownloadSize + | 412 size_t file_size1 = URLRequestSlowDownloadJob::kFirstDownloadSize + |
| 214 URLRequestSlowDownloadJob::kSecondDownloadSize; | 413 URLRequestSlowDownloadJob::kSecondDownloadSize; |
| 215 std::string expected_contents(file_size1, '*'); | 414 std::string expected_contents(file_size1, '*'); |
| 216 ASSERT_TRUE(VerifyFile(file1, expected_contents, file_size1)); | 415 ASSERT_TRUE(VerifyFile(file1, expected_contents, file_size1)); |
| 217 | 416 |
| 218 FilePath file2(download2->GetFullPath()); | 417 FilePath file2(download2->GetFullPath()); |
| 219 ASSERT_TRUE(file_util::ContentsEqual( | 418 ASSERT_TRUE(file_util::ContentsEqual( |
| 220 file2, GetTestFilePath("download", "download-test.lib"))); | 419 file2, GetTestFilePath("download", "download-test.lib"))); |
| 221 } | 420 } |
| 222 | 421 |
| 422 // Try to cancel just before we release the download file, by delaying final | |
| 423 // rename callback. | |
| 424 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtFinalRename) { | |
| 425 // Setup new factory. | |
| 426 DownloadFileWithDelayFactory* file_factory = | |
| 427 new DownloadFileWithDelayFactory(); | |
| 428 DownloadManagerImpl* download_manager(DownloadManagerForShell(shell())); | |
| 429 download_manager->SetDownloadFileFactoryForTesting( | |
| 430 scoped_ptr<content::DownloadFileFactory>(file_factory).Pass()); | |
| 431 | |
| 432 // Create a download | |
| 433 FilePath file(FILE_PATH_LITERAL("download-test.lib")); | |
| 434 NavigateToURL(shell(), URLRequestMockHTTPJob::GetMockUrl(file)); | |
| 435 | |
| 436 // Wait until the first (intermediate file) rename and execute the callback. | |
| 437 file_factory->WaitForSomeCallback(); | |
| 438 std::vector<base::Closure> callbacks; | |
| 439 file_factory->GetDetachCallbacks(&callbacks); | |
| 440 ASSERT_TRUE(callbacks.empty()); | |
| 441 file_factory->GetRenameCallbacks(&callbacks); | |
| 442 ASSERT_EQ(1u, callbacks.size()); | |
| 443 callbacks[0].Run(); | |
| 444 callbacks.clear(); | |
| 445 | |
| 446 // Wait until the second (final) rename callback is posted. | |
| 447 file_factory->WaitForSomeCallback(); | |
| 448 file_factory->GetDetachCallbacks(&callbacks); | |
| 449 ASSERT_TRUE(callbacks.empty()); | |
| 450 file_factory->GetRenameCallbacks(&callbacks); | |
| 451 ASSERT_EQ(1u, callbacks.size()); | |
| 452 | |
| 453 // Cancel it. | |
| 454 std::vector<DownloadItem*> items; | |
| 455 download_manager->GetAllDownloads(&items); | |
| 456 ASSERT_EQ(1u, items.size()); | |
| 457 items[0]->Cancel(true); | |
| 458 RunAllPendingInMessageLoop(); | |
| 459 | |
| 460 // Check state. | |
| 461 EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState()); | |
| 462 | |
| 463 // Run final rename callback. | |
| 464 callbacks[0].Run(); | |
| 465 callbacks.clear(); | |
| 466 | |
| 467 // Check state. | |
| 468 EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState()); | |
| 469 } | |
| 470 | |
| 471 // Try to cancel just after we release the download file, by delaying | |
| 472 // release. | |
| 473 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtRelease) { | |
| 474 // Setup new factory. | |
| 475 DownloadFileWithDelayFactory* file_factory = | |
| 476 new DownloadFileWithDelayFactory(); | |
| 477 DownloadManagerImpl* download_manager(DownloadManagerForShell(shell())); | |
| 478 download_manager->SetDownloadFileFactoryForTesting( | |
| 479 scoped_ptr<content::DownloadFileFactory>(file_factory).Pass()); | |
| 480 | |
| 481 // Create a download | |
| 482 FilePath file(FILE_PATH_LITERAL("download-test.lib")); | |
| 483 NavigateToURL(shell(), URLRequestMockHTTPJob::GetMockUrl(file)); | |
| 484 | |
| 485 // Wait until the first (intermediate file) rename and execute the callback. | |
| 486 file_factory->WaitForSomeCallback(); | |
| 487 std::vector<base::Closure> callbacks; | |
| 488 file_factory->GetDetachCallbacks(&callbacks); | |
| 489 ASSERT_TRUE(callbacks.empty()); | |
| 490 file_factory->GetRenameCallbacks(&callbacks); | |
| 491 ASSERT_EQ(1u, callbacks.size()); | |
| 492 callbacks[0].Run(); | |
| 493 callbacks.clear(); | |
| 494 | |
| 495 // Wait until the second (final) rename callback is posted. | |
| 496 file_factory->WaitForSomeCallback(); | |
| 497 file_factory->GetDetachCallbacks(&callbacks); | |
| 498 ASSERT_TRUE(callbacks.empty()); | |
| 499 file_factory->GetRenameCallbacks(&callbacks); | |
| 500 ASSERT_EQ(1u, callbacks.size()); | |
| 501 | |
| 502 // Call it. | |
| 503 callbacks[0].Run(); | |
| 504 callbacks.clear(); | |
| 505 | |
| 506 // Confirm download now complete. | |
| 507 std::vector<DownloadItem*> items; | |
| 508 download_manager->GetAllDownloads(&items); | |
| 509 EXPECT_EQ(DownloadItem::COMPLETE, items[0]->GetState()); | |
| 510 | |
| 511 // Cancel the download; confirm cancel fails. | |
| 512 ASSERT_EQ(1u, items.size()); | |
| 513 items[0]->Cancel(true); | |
| 514 EXPECT_EQ(DownloadItem::COMPLETE, items[0]->GetState()); | |
| 515 RunAllPendingInMessageLoop(); | |
| 516 EXPECT_EQ(DownloadItem::COMPLETE, items[0]->GetState()); | |
| 517 | |
| 518 // Confirm detach callback and run it. | |
| 519 file_factory->WaitForSomeCallback(); | |
| 520 file_factory->GetRenameCallbacks(&callbacks); | |
| 521 ASSERT_TRUE(callbacks.empty()); | |
| 522 file_factory->GetDetachCallbacks(&callbacks); | |
| 523 ASSERT_EQ(1u, callbacks.size()); | |
| 524 callbacks[0].Run(); | |
| 525 callbacks.clear(); | |
| 526 } | |
| 527 | |
| 223 } // namespace content | 528 } // namespace content |
| OLD | NEW |