| 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 #include "content/browser/download/download_item_impl.h" | 5 #include "content/browser/download/download_item_impl.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| 11 #include "base/feature_list.h" | 11 #include "base/feature_list.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/run_loop.h" |
| 13 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 14 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
| 15 #include "content/browser/byte_stream.h" | 16 #include "content/browser/byte_stream.h" |
| 16 #include "content/browser/download/download_create_info.h" | 17 #include "content/browser/download/download_create_info.h" |
| 17 #include "content/browser/download/download_file_factory.h" | 18 #include "content/browser/download/download_file_factory.h" |
| 18 #include "content/browser/download/download_item_impl_delegate.h" | 19 #include "content/browser/download/download_item_impl_delegate.h" |
| 19 #include "content/browser/download/download_request_handle.h" | 20 #include "content/browser/download/download_request_handle.h" |
| 20 #include "content/browser/download/mock_download_file.h" | 21 #include "content/browser/download/mock_download_file.h" |
| 22 #include "content/public/browser/browser_thread.h" |
| 21 #include "content/public/browser/download_destination_observer.h" | 23 #include "content/public/browser/download_destination_observer.h" |
| 22 #include "content/public/browser/download_interrupt_reasons.h" | 24 #include "content/public/browser/download_interrupt_reasons.h" |
| 23 #include "content/public/browser/download_url_parameters.h" | 25 #include "content/public/browser/download_url_parameters.h" |
| 26 #include "content/public/browser/site_instance.h" |
| 27 #include "content/public/browser/web_contents.h" |
| 24 #include "content/public/common/content_features.h" | 28 #include "content/public/common/content_features.h" |
| 25 #include "content/public/test/mock_download_item.h" | 29 #include "content/public/test/mock_download_item.h" |
| 30 #include "content/public/test/mock_download_item.h" |
| 31 #include "content/public/test/test_browser_context.h" |
| 26 #include "content/public/test/test_browser_context.h" | 32 #include "content/public/test/test_browser_context.h" |
| 27 #include "content/public/test/test_browser_thread.h" | 33 #include "content/public/test/test_browser_thread.h" |
| 34 #include "content/public/test/test_browser_thread_bundle.h" |
| 35 #include "content/public/test/web_contents_tester.h" |
| 28 #include "testing/gmock/include/gmock/gmock.h" | 36 #include "testing/gmock/include/gmock/gmock.h" |
| 29 #include "testing/gtest/include/gtest/gtest.h" | 37 #include "testing/gtest/include/gtest/gtest.h" |
| 30 | 38 |
| 31 using ::testing::_; | 39 using ::testing::_; |
| 32 using ::testing::NiceMock; | 40 using ::testing::NiceMock; |
| 33 using ::testing::Property; | 41 using ::testing::Property; |
| 34 using ::testing::Return; | 42 using ::testing::Return; |
| 35 using ::testing::SaveArg; | 43 using ::testing::SaveArg; |
| 36 using ::testing::StrictMock; | 44 using ::testing::StrictMock; |
| 37 | 45 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 59 MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*)); | 67 MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*)); |
| 60 | 68 |
| 61 void ResumeInterruptedDownload(scoped_ptr<DownloadUrlParameters> params, | 69 void ResumeInterruptedDownload(scoped_ptr<DownloadUrlParameters> params, |
| 62 uint32_t id) override { | 70 uint32_t id) override { |
| 63 MockResumeInterruptedDownload(params.get(), id); | 71 MockResumeInterruptedDownload(params.get(), id); |
| 64 } | 72 } |
| 65 MOCK_METHOD2(MockResumeInterruptedDownload, | 73 MOCK_METHOD2(MockResumeInterruptedDownload, |
| 66 void(DownloadUrlParameters* params, uint32_t id)); | 74 void(DownloadUrlParameters* params, uint32_t id)); |
| 67 | 75 |
| 68 MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*()); | 76 MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*()); |
| 69 MOCK_METHOD1(UpdatePersistence, void(DownloadItemImpl*)); | |
| 70 MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*)); | 77 MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*)); |
| 71 MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*)); | 78 MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*)); |
| 72 MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*)); | 79 MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*)); |
| 73 | 80 |
| 74 void VerifyAndClearExpectations() { | 81 void VerifyAndClearExpectations() { |
| 75 ::testing::Mock::VerifyAndClearExpectations(this); | 82 ::testing::Mock::VerifyAndClearExpectations(this); |
| 76 SetDefaultExpectations(); | 83 SetDefaultExpectations(); |
| 77 } | 84 } |
| 78 | 85 |
| 79 private: | 86 private: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 90 class MockRequestHandle : public DownloadRequestHandleInterface { | 97 class MockRequestHandle : public DownloadRequestHandleInterface { |
| 91 public: | 98 public: |
| 92 MOCK_CONST_METHOD0(GetWebContents, WebContents*()); | 99 MOCK_CONST_METHOD0(GetWebContents, WebContents*()); |
| 93 MOCK_CONST_METHOD0(GetDownloadManager, DownloadManager*()); | 100 MOCK_CONST_METHOD0(GetDownloadManager, DownloadManager*()); |
| 94 MOCK_CONST_METHOD0(PauseRequest, void()); | 101 MOCK_CONST_METHOD0(PauseRequest, void()); |
| 95 MOCK_CONST_METHOD0(ResumeRequest, void()); | 102 MOCK_CONST_METHOD0(ResumeRequest, void()); |
| 96 MOCK_CONST_METHOD0(CancelRequest, void()); | 103 MOCK_CONST_METHOD0(CancelRequest, void()); |
| 97 MOCK_CONST_METHOD0(DebugString, std::string()); | 104 MOCK_CONST_METHOD0(DebugString, std::string()); |
| 98 }; | 105 }; |
| 99 | 106 |
| 107 // |new_path| on the UI thread. Should only be used as the action for |
| 108 // MockDownloadFile::Rename as follows: |
| 109 // |
| 110 // EXPECT_CALL(download_file, Rename*(_,_)) |
| 111 // .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 112 // new_path)); |
| 113 ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) { |
| 114 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 115 base::Bind(arg1, interrupt_reason, new_path)); |
| 116 } |
| 117 |
| 118 // Schedules a task to invoke DownloadFile::InitializedCallback with |
| 119 // |interrupt_reason| on the UI thread. Should be used as the action for |
| 120 // MockDownloadFile::Initialize as follows: |
| 121 // EXPECT_CALL(download_file, Initialize(_)) |
| 122 // .WillOnce(ScheduleInitializeCallback(DOWNLOAD_INTERRUPT_REASON_NONE)); |
| 123 ACTION_P(ScheduleInitializeCallback, interrupt_reason) { |
| 124 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 125 base::Bind(arg0, interrupt_reason)); |
| 126 } |
| 127 |
| 100 class TestDownloadItemObserver : public DownloadItem::Observer { | 128 class TestDownloadItemObserver : public DownloadItem::Observer { |
| 101 public: | 129 public: |
| 102 explicit TestDownloadItemObserver(DownloadItem* item) | 130 explicit TestDownloadItemObserver(DownloadItem* item) |
| 103 : item_(item), | 131 : item_(item), |
| 104 last_state_(item->GetState()), | 132 last_state_(item->GetState()), |
| 105 removed_(false), | 133 removed_(false), |
| 106 destroyed_(false), | 134 destroyed_(false), |
| 107 updated_(false), | 135 updated_(false), |
| 108 interrupt_count_(0), | 136 interrupt_count_(0), |
| 109 resume_count_(0) { | 137 resume_count_(0) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 121 int resume_count() const { return resume_count_; } | 149 int resume_count() const { return resume_count_; } |
| 122 | 150 |
| 123 bool CheckAndResetDownloadUpdated() { | 151 bool CheckAndResetDownloadUpdated() { |
| 124 bool was_updated = updated_; | 152 bool was_updated = updated_; |
| 125 updated_ = false; | 153 updated_ = false; |
| 126 return was_updated; | 154 return was_updated; |
| 127 } | 155 } |
| 128 | 156 |
| 129 private: | 157 private: |
| 130 void OnDownloadRemoved(DownloadItem* download) override { | 158 void OnDownloadRemoved(DownloadItem* download) override { |
| 131 DVLOG(20) << " " << __FUNCTION__ | 159 SCOPED_TRACE(::testing::Message() << " " << __FUNCTION__ << " download = " |
| 132 << " download = " << download->DebugString(false); | 160 << download->DebugString(false)); |
| 133 removed_ = true; | 161 removed_ = true; |
| 134 } | 162 } |
| 135 | 163 |
| 136 void OnDownloadUpdated(DownloadItem* download) override { | 164 void OnDownloadUpdated(DownloadItem* download) override { |
| 137 DVLOG(20) << " " << __FUNCTION__ | 165 DVLOG(20) << " " << __FUNCTION__ |
| 138 << " download = " << download->DebugString(false); | 166 << " download = " << download->DebugString(false); |
| 139 updated_ = true; | 167 updated_ = true; |
| 140 DownloadItem::DownloadState new_state = download->GetState(); | 168 DownloadItem::DownloadState new_state = download->GetState(); |
| 141 if (last_state_ == DownloadItem::IN_PROGRESS && | 169 if (last_state_ == DownloadItem::IN_PROGRESS && |
| 142 new_state == DownloadItem::INTERRUPTED) { | 170 new_state == DownloadItem::INTERRUPTED) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 164 | 192 |
| 165 DownloadItem* item_; | 193 DownloadItem* item_; |
| 166 DownloadItem::DownloadState last_state_; | 194 DownloadItem::DownloadState last_state_; |
| 167 bool removed_; | 195 bool removed_; |
| 168 bool destroyed_; | 196 bool destroyed_; |
| 169 bool updated_; | 197 bool updated_; |
| 170 int interrupt_count_; | 198 int interrupt_count_; |
| 171 int resume_count_; | 199 int resume_count_; |
| 172 }; | 200 }; |
| 173 | 201 |
| 174 // Schedules a task to invoke the RenameCompletionCallback with |new_path| on | |
| 175 // the UI thread. Should only be used as the action for | |
| 176 // MockDownloadFile::Rename as follows: | |
| 177 // EXPECT_CALL(download_file, Rename*(_,_)) | |
| 178 // .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | |
| 179 // new_path)); | |
| 180 ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) { | |
| 181 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
| 182 base::Bind(arg1, interrupt_reason, new_path)); | |
| 183 } | |
| 184 | |
| 185 } // namespace | 202 } // namespace |
| 186 | 203 |
| 187 class DownloadItemTest : public testing::Test { | 204 class DownloadItemTest : public testing::Test { |
| 188 public: | 205 public: |
| 189 DownloadItemTest() | 206 DownloadItemTest() |
| 190 : ui_thread_(BrowserThread::UI, &loop_), | 207 : delegate_(), next_download_id_(DownloadItem::kInvalidId + 1) { |
| 191 file_thread_(BrowserThread::FILE, &loop_), | 208 create_info_.reset(new DownloadCreateInfo()); |
| 192 delegate_() { | 209 create_info_->save_info = |
| 210 scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); |
| 211 create_info_->save_info->prompt_for_save_location = false; |
| 212 create_info_->url_chain.push_back(GURL()); |
| 213 create_info_->etag = "SomethingToSatisfyResumption"; |
| 193 } | 214 } |
| 194 | 215 |
| 195 ~DownloadItemTest() { | 216 ~DownloadItemTest() { |
| 196 } | 217 } |
| 197 | 218 |
| 198 virtual void SetUp() { | 219 virtual void SetUp() { |
| 199 base::FeatureList::ClearInstanceForTesting(); | 220 base::FeatureList::ClearInstanceForTesting(); |
| 200 scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); | 221 scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); |
| 201 feature_list->InitializeFromCommandLine(features::kDownloadResumption.name, | 222 feature_list->InitializeFromCommandLine(features::kDownloadResumption.name, |
| 202 std::string()); | 223 std::string()); |
| 203 base::FeatureList::SetInstance(std::move(feature_list)); | 224 base::FeatureList::SetInstance(std::move(feature_list)); |
| 204 } | 225 } |
| 205 | 226 |
| 206 virtual void TearDown() { | 227 virtual void TearDown() { |
| 207 ui_thread_.DeprecatedGetThreadObject()->message_loop()->RunUntilIdle(); | 228 base::RunLoop run_loop; |
| 229 run_loop.RunUntilIdle(); |
| 208 STLDeleteElements(&allocated_downloads_); | 230 STLDeleteElements(&allocated_downloads_); |
| 209 } | 231 } |
| 210 | 232 |
| 211 // This class keeps ownership of the created download item; it will | 233 // This class keeps ownership of the created download item; it will |
| 212 // be torn down at the end of the test unless DestroyDownloadItem is | 234 // be torn down at the end of the test unless DestroyDownloadItem is |
| 213 // called. | 235 // called. |
| 214 DownloadItemImpl* CreateDownloadItem() { | 236 DownloadItemImpl* CreateDownloadItem() { |
| 215 scoped_ptr<DownloadCreateInfo> info; | 237 create_info_->download_id = ++next_download_id_; |
| 216 | 238 DownloadItemImpl* download = |
| 217 info.reset(new DownloadCreateInfo()); | 239 new DownloadItemImpl(&delegate_, create_info_->download_id, |
| 218 info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); | 240 *create_info_, net::BoundNetLog()); |
| 219 info->save_info->prompt_for_save_location = false; | |
| 220 info->url_chain.push_back(GURL()); | |
| 221 info->etag = "SomethingToSatisfyResumption"; | |
| 222 | |
| 223 return CreateDownloadItemWithCreateInfo(std::move(info)); | |
| 224 } | |
| 225 | |
| 226 DownloadItemImpl* CreateDownloadItemWithCreateInfo( | |
| 227 scoped_ptr<DownloadCreateInfo> info) { | |
| 228 DownloadItemImpl* download = new DownloadItemImpl( | |
| 229 &delegate_, next_download_id_++, *(info.get()), net::BoundNetLog()); | |
| 230 allocated_downloads_.insert(download); | 241 allocated_downloads_.insert(download); |
| 231 return download; | 242 return download; |
| 232 } | 243 } |
| 233 | 244 |
| 234 // Add DownloadFile to DownloadItem | 245 // Add DownloadFile to DownloadItem |
| 235 MockDownloadFile* AddDownloadFileToDownloadItem( | 246 MockDownloadFile* AddDownloadFileToDownloadItem( |
| 236 DownloadItemImpl* item, | 247 DownloadItemImpl* item, |
| 237 DownloadItemImplDelegate::DownloadTargetCallback *callback) { | 248 DownloadItemImplDelegate::DownloadTargetCallback *callback) { |
| 238 MockDownloadFile* mock_download_file(new StrictMock<MockDownloadFile>); | 249 MockDownloadFile* mock_download_file = nullptr; |
| 239 scoped_ptr<DownloadFile> download_file(mock_download_file); | 250 scoped_ptr<DownloadFile> download_file; |
| 240 EXPECT_CALL(*mock_download_file, Initialize(_)); | |
| 241 if (callback) { | 251 if (callback) { |
| 242 // Save the callback. | 252 // Save the callback. |
| 243 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) | 253 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) |
| 244 .WillOnce(SaveArg<1>(callback)); | 254 .WillOnce(SaveArg<1>(callback)); |
| 245 } else { | 255 } else { |
| 246 // Drop it on the floor. | 256 // Drop it on the floor. |
| 247 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); | 257 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); |
| 248 } | 258 } |
| 249 | 259 |
| 250 scoped_ptr<DownloadRequestHandleInterface> request_handle( | 260 // Only create a DownloadFile if the request was successful. |
| 261 if (create_info_->result == DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 262 mock_download_file = new StrictMock<MockDownloadFile>; |
| 263 download_file.reset(mock_download_file); |
| 264 EXPECT_CALL(*mock_download_file, Initialize(_)) |
| 265 .WillOnce(ScheduleInitializeCallback(DOWNLOAD_INTERRUPT_REASON_NONE)); |
| 266 EXPECT_CALL(*mock_download_file, FullPath()) |
| 267 .WillRepeatedly(Return(base::FilePath())); |
| 268 } |
| 269 |
| 270 scoped_ptr<MockRequestHandle> request_handle( |
| 251 new NiceMock<MockRequestHandle>); | 271 new NiceMock<MockRequestHandle>); |
| 252 item->Start(std::move(download_file), std::move(request_handle)); | 272 EXPECT_CALL(*request_handle, GetWebContents()) |
| 253 loop_.RunUntilIdle(); | 273 .WillRepeatedly(Return(GetWebContents())); |
| 274 item->Start(std::move(download_file), std::move(request_handle), |
| 275 *create_info_); |
| 276 base::RunLoop().RunUntilIdle(); |
| 254 | 277 |
| 255 // So that we don't have a function writing to a stack variable | 278 // So that we don't have a function writing to a stack variable |
| 256 // lying around if the above failed. | 279 // lying around if the above failed. |
| 257 mock_delegate()->VerifyAndClearExpectations(); | 280 mock_delegate()->VerifyAndClearExpectations(); |
| 258 EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_)) | 281 EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_)) |
| 259 .WillRepeatedly(Return()); | 282 .WillRepeatedly(Return()); |
| 260 EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_)) | 283 EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_)) |
| 261 .WillRepeatedly(Return(false)); | 284 .WillRepeatedly(Return(false)); |
| 262 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _)) | 285 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _)) |
| 263 .WillRepeatedly(Return(true)); | 286 .WillRepeatedly(Return(true)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 291 // The item must be in the expected state. | 314 // The item must be in the expected state. |
| 292 void CleanupItem(DownloadItemImpl* item, | 315 void CleanupItem(DownloadItemImpl* item, |
| 293 MockDownloadFile* download_file, | 316 MockDownloadFile* download_file, |
| 294 DownloadItem::DownloadState expected_state) { | 317 DownloadItem::DownloadState expected_state) { |
| 295 EXPECT_EQ(expected_state, item->GetState()); | 318 EXPECT_EQ(expected_state, item->GetState()); |
| 296 | 319 |
| 297 if (expected_state == DownloadItem::IN_PROGRESS) { | 320 if (expected_state == DownloadItem::IN_PROGRESS) { |
| 298 if (download_file) | 321 if (download_file) |
| 299 EXPECT_CALL(*download_file, Cancel()); | 322 EXPECT_CALL(*download_file, Cancel()); |
| 300 item->Cancel(true); | 323 item->Cancel(true); |
| 301 loop_.RunUntilIdle(); | 324 base::RunLoop().RunUntilIdle(); |
| 302 } | 325 } |
| 303 } | 326 } |
| 304 | 327 |
| 305 // Destroy a previously created download item. | 328 // Destroy a previously created download item. |
| 306 void DestroyDownloadItem(DownloadItem* item) { | 329 void DestroyDownloadItem(DownloadItem* item) { |
| 307 allocated_downloads_.erase(item); | 330 allocated_downloads_.erase(item); |
| 308 delete item; | 331 delete item; |
| 309 } | 332 } |
| 310 | 333 |
| 311 void RunAllPendingInMessageLoops() { | 334 void RunAllPendingInMessageLoops() { base::RunLoop().RunUntilIdle(); } |
| 312 loop_.RunUntilIdle(); | |
| 313 } | |
| 314 | 335 |
| 315 MockDelegate* mock_delegate() { | 336 MockDelegate* mock_delegate() { |
| 316 return &delegate_; | 337 return &delegate_; |
| 317 } | 338 } |
| 318 | 339 |
| 319 void OnDownloadFileAcquired(base::FilePath* return_path, | 340 void OnDownloadFileAcquired(base::FilePath* return_path, |
| 320 const base::FilePath& path) { | 341 const base::FilePath& path) { |
| 321 *return_path = path; | 342 *return_path = path; |
| 322 } | 343 } |
| 323 | 344 |
| 345 DownloadCreateInfo* create_info() { return create_info_.get(); } |
| 346 |
| 347 virtual WebContents* GetWebContents() { return nullptr; } |
| 348 |
| 324 private: | 349 private: |
| 325 int next_download_id_ = DownloadItem::kInvalidId + 1; | |
| 326 base::MessageLoopForUI loop_; | |
| 327 TestBrowserThread ui_thread_; // UI thread | |
| 328 TestBrowserThread file_thread_; // FILE thread | |
| 329 StrictMock<MockDelegate> delegate_; | 350 StrictMock<MockDelegate> delegate_; |
| 330 std::set<DownloadItem*> allocated_downloads_; | 351 std::set<DownloadItem*> allocated_downloads_; |
| 352 scoped_ptr<DownloadCreateInfo> create_info_; |
| 353 uint32_t next_download_id_; |
| 354 TestBrowserThreadBundle thread_bundle_; |
| 331 }; | 355 }; |
| 332 | 356 |
| 357 // Test fixture for resumption tests. The fixture takes a GTest parameter of |
| 358 // type 'bool'. If the parameter is true, then the DownloadItem has a valid |
| 359 // WebContents. It would have a null WebContents otherwise. Whether or not a |
| 360 // WebContents exists has a bearing on the code path used for resumption. Hence |
| 361 // it's important to exercise both possibilities for these tests. |
| 362 class DownloadItemTestWithResumption |
| 363 : public DownloadItemTest, |
| 364 public ::testing::WithParamInterface<bool> { |
| 365 public: |
| 366 void SetUp() override { |
| 367 browser_context_.reset(new TestBrowserContext); |
| 368 if (GetParam()) { |
| 369 scoped_refptr<SiteInstance> site_instance( |
| 370 SiteInstance::Create(browser_context_.get())); |
| 371 web_contents_.reset(WebContentsTester::CreateTestWebContents( |
| 372 browser_context_.get(), site_instance.get())); |
| 373 } |
| 374 DownloadItemTest::SetUp(); |
| 375 } |
| 376 |
| 377 void TearDown() override { |
| 378 DownloadItemTest::TearDown(); |
| 379 web_contents_.reset(); |
| 380 browser_context_.reset(); |
| 381 } |
| 382 |
| 383 WebContents* GetWebContents() override { return web_contents_.get(); } |
| 384 |
| 385 BrowserContext* GetBrowserContext() { return browser_context_.get(); } |
| 386 |
| 387 private: |
| 388 scoped_ptr<TestBrowserContext> browser_context_; |
| 389 scoped_ptr<WebContents> web_contents_; |
| 390 }; |
| 391 |
| 392 INSTANTIATE_TEST_CASE_P(WithAndWithoutWebContents, |
| 393 DownloadItemTestWithResumption, |
| 394 ::testing::Bool()); |
| 395 |
| 333 // Tests to ensure calls that change a DownloadItem generate an update to | 396 // Tests to ensure calls that change a DownloadItem generate an update to |
| 334 // observers. | 397 // observers. |
| 335 // State changing functions not tested: | 398 // State changing functions not tested: |
| 336 // void OpenDownload(); | 399 // void OpenDownload(); |
| 337 // void ShowDownloadInShell(); | 400 // void ShowDownloadInShell(); |
| 338 // void CompleteDelayedDownload(); | 401 // void CompleteDelayedDownload(); |
| 339 // set_* mutators | 402 // set_* mutators |
| 340 | 403 |
| 341 TEST_F(DownloadItemTest, NotificationAfterUpdate) { | 404 TEST_F(DownloadItemTest, NotificationAfterUpdate) { |
| 342 DownloadItemImpl* item = CreateDownloadItem(); | 405 DownloadItemImpl* item = CreateDownloadItem(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 } | 464 } |
| 402 | 465 |
| 403 TEST_F(DownloadItemTest, NotificationAfterDestroyed) { | 466 TEST_F(DownloadItemTest, NotificationAfterDestroyed) { |
| 404 DownloadItemImpl* item = CreateDownloadItem(); | 467 DownloadItemImpl* item = CreateDownloadItem(); |
| 405 TestDownloadItemObserver observer(item); | 468 TestDownloadItemObserver observer(item); |
| 406 | 469 |
| 407 DestroyDownloadItem(item); | 470 DestroyDownloadItem(item); |
| 408 ASSERT_TRUE(observer.download_destroyed()); | 471 ASSERT_TRUE(observer.download_destroyed()); |
| 409 } | 472 } |
| 410 | 473 |
| 411 TEST_F(DownloadItemTest, ContinueAfterInterrupted) { | 474 // Test that a download is resumed automatcially after a continuable interrupt. |
| 412 TestBrowserContext test_browser_context; | 475 TEST_P(DownloadItemTestWithResumption, ContinueAfterInterrupted) { |
| 413 DownloadItemImpl* item = CreateDownloadItem(); | 476 DownloadItemImpl* item = CreateDownloadItem(); |
| 414 TestDownloadItemObserver observer(item); | 477 TestDownloadItemObserver observer(item); |
| 415 MockDownloadFile* download_file = | 478 MockDownloadFile* download_file = |
| 416 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 479 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 417 | 480 |
| 418 // Interrupt the download, using a continuable interrupt. | 481 // Interrupt the download, using a continuable interrupt. |
| 419 EXPECT_CALL(*download_file, FullPath()) | 482 EXPECT_CALL(*download_file, FullPath()) |
| 420 .WillOnce(Return(base::FilePath())); | 483 .WillOnce(Return(base::FilePath())); |
| 421 EXPECT_CALL(*download_file, Detach()); | 484 EXPECT_CALL(*download_file, Detach()); |
| 422 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | 485 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
| 423 .WillRepeatedly(Return(&test_browser_context)); | 486 .WillRepeatedly(Return(GetBrowserContext())); |
| 424 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1); | 487 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1); |
| 425 item->DestinationObserverAsWeakPtr()->DestinationError( | 488 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 426 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 489 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
| 427 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 490 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 428 // Since the download is resumed automatically, the interrupt count doesn't | 491 // Since the download is resumed automatically, the interrupt count doesn't |
| 429 // increase. | 492 // increase. |
| 430 ASSERT_EQ(0, observer.interrupt_count()); | 493 ASSERT_EQ(0, observer.interrupt_count()); |
| 431 | 494 |
| 432 // Test expectations verify that ResumeInterruptedDownload() is called (by way | 495 // Test expectations verify that ResumeInterruptedDownload() is called (by way |
| 433 // of MockResumeInterruptedDownload) after the download is interrupted. But | 496 // of MockResumeInterruptedDownload) after the download is interrupted. But |
| 434 // the mock doesn't follow through with the resumption. | 497 // the mock doesn't follow through with the resumption. |
| 435 // ResumeInterruptedDownload() being called is sufficient for verifying that | 498 // ResumeInterruptedDownload() being called is sufficient for verifying that |
| 436 // the automatic resumption was triggered. | 499 // the automatic resumption was triggered. |
| 437 RunAllPendingInMessageLoops(); | 500 RunAllPendingInMessageLoops(); |
| 438 | 501 |
| 439 // The download item is currently in RESUMING_INTERNAL state, which maps to | 502 // The download item is currently in RESUMING_INTERNAL state, which maps to |
| 440 // IN_PROGRESS. | 503 // IN_PROGRESS. |
| 441 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); | 504 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); |
| 442 } | 505 } |
| 443 | 506 |
| 444 // Same as above, but with a non-continuable interrupt. | 507 // Test that automatic resumption doesn't happen after a non-continuable |
| 445 TEST_F(DownloadItemTest, RestartAfterInterrupted) { | 508 // interrupt. |
| 509 TEST_P(DownloadItemTestWithResumption, RestartAfterInterrupted) { |
| 446 DownloadItemImpl* item = CreateDownloadItem(); | 510 DownloadItemImpl* item = CreateDownloadItem(); |
| 447 TestDownloadItemObserver observer(item); | 511 TestDownloadItemObserver observer(item); |
| 448 MockDownloadFile* download_file = | 512 MockDownloadFile* download_file = |
| 449 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 513 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 450 | 514 |
| 451 // Interrupt the download, using a restartable interrupt. | 515 // Interrupt the download, using a restartable interrupt. |
| 452 EXPECT_CALL(*download_file, Cancel()); | 516 EXPECT_CALL(*download_file, Cancel()); |
| 453 item->DestinationObserverAsWeakPtr()->DestinationError( | 517 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 454 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 518 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
| 455 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 519 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 481 RunAllPendingInMessageLoops(); | 545 RunAllPendingInMessageLoops(); |
| 482 | 546 |
| 483 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 547 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 484 // Should not try to auto-resume. | 548 // Should not try to auto-resume. |
| 485 ASSERT_EQ(1, observer.interrupt_count()); | 549 ASSERT_EQ(1, observer.interrupt_count()); |
| 486 ASSERT_EQ(0, observer.resume_count()); | 550 ASSERT_EQ(0, observer.resume_count()); |
| 487 | 551 |
| 488 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); | 552 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); |
| 489 } | 553 } |
| 490 | 554 |
| 491 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) { | 555 TEST_P(DownloadItemTestWithResumption, LimitRestartsAfterInterrupted) { |
| 492 TestBrowserContext test_browser_context; | |
| 493 DownloadItemImpl* item = CreateDownloadItem(); | 556 DownloadItemImpl* item = CreateDownloadItem(); |
| 494 base::WeakPtr<DownloadDestinationObserver> as_observer( | 557 base::WeakPtr<DownloadDestinationObserver> as_observer( |
| 495 item->DestinationObserverAsWeakPtr()); | 558 item->DestinationObserverAsWeakPtr()); |
| 496 TestDownloadItemObserver observer(item); | 559 TestDownloadItemObserver observer(item); |
| 497 MockDownloadFile* mock_download_file(NULL); | 560 MockDownloadFile* mock_download_file(NULL); |
| 498 scoped_ptr<DownloadFile> download_file; | 561 scoped_ptr<DownloadFile> download_file; |
| 499 MockRequestHandle* mock_request_handle(NULL); | 562 MockRequestHandle* mock_request_handle(NULL); |
| 500 scoped_ptr<DownloadRequestHandleInterface> request_handle; | 563 scoped_ptr<DownloadRequestHandleInterface> request_handle; |
| 501 DownloadItemImplDelegate::DownloadTargetCallback callback; | 564 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 502 | 565 |
| 503 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) | 566 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) |
| 504 .WillRepeatedly(SaveArg<1>(&callback)); | 567 .WillRepeatedly(SaveArg<1>(&callback)); |
| 505 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | 568 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
| 506 .WillRepeatedly(Return(&test_browser_context)); | 569 .WillRepeatedly(Return(GetBrowserContext())); |
| 507 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)) | 570 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)) |
| 508 .Times(DownloadItemImpl::kMaxAutoResumeAttempts); | 571 .Times(DownloadItemImpl::kMaxAutoResumeAttempts); |
| 509 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { | 572 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { |
| 510 DVLOG(20) << "Loop iteration " << i; | 573 SCOPED_TRACE(::testing::Message() << "Iteration " << i); |
| 511 | 574 |
| 512 mock_download_file = new NiceMock<MockDownloadFile>; | 575 mock_download_file = new NiceMock<MockDownloadFile>; |
| 513 download_file.reset(mock_download_file); | 576 download_file.reset(mock_download_file); |
| 514 mock_request_handle = new NiceMock<MockRequestHandle>; | 577 mock_request_handle = new NiceMock<MockRequestHandle>; |
| 515 request_handle.reset(mock_request_handle); | 578 request_handle.reset(mock_request_handle); |
| 516 | 579 |
| 517 ON_CALL(*mock_download_file, FullPath()) | 580 ON_CALL(*mock_download_file, FullPath()) |
| 518 .WillByDefault(Return(base::FilePath())); | 581 .WillByDefault(Return(base::FilePath())); |
| 519 | 582 |
| 520 // Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem | 583 // Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem |
| 521 // to allow for holding onto the request handle. | 584 // to allow for holding onto the request handle. |
| 522 item->Start(std::move(download_file), std::move(request_handle)); | 585 item->Start(std::move(download_file), std::move(request_handle), |
| 586 *create_info()); |
| 523 RunAllPendingInMessageLoops(); | 587 RunAllPendingInMessageLoops(); |
| 524 if (i == 0) { | 588 if (i == 0) { |
| 525 // Target determination is only done the first time through. | 589 // Target determination is only done the first time through. |
| 526 base::FilePath target_path(kDummyPath); | 590 base::FilePath target_path(kDummyPath); |
| 527 base::FilePath intermediate_path( | 591 base::FilePath intermediate_path( |
| 528 target_path.InsertBeforeExtensionASCII("x")); | 592 target_path.InsertBeforeExtensionASCII("x")); |
| 529 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) | 593 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) |
| 530 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 594 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 531 intermediate_path)); | 595 intermediate_path)); |
| 532 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 596 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 533 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); | 597 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); |
| 534 RunAllPendingInMessageLoops(); | 598 RunAllPendingInMessageLoops(); |
| 535 } | 599 } |
| 536 | 600 |
| 537 // Use a continuable interrupt. | 601 // Use a continuable interrupt. |
| 538 item->DestinationObserverAsWeakPtr()->DestinationError( | 602 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 539 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 603 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
| 540 | 604 |
| 605 RunAllPendingInMessageLoops(); |
| 541 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); | 606 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); |
| 542 } | 607 } |
| 543 | 608 |
| 544 EXPECT_EQ(1, observer.interrupt_count()); | 609 EXPECT_EQ(1, observer.interrupt_count()); |
| 545 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); | 610 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); |
| 546 } | 611 } |
| 547 | 612 |
| 613 // If the download attempts to resume and the resumption request fails, the |
| 614 // subsequent Start() call shouldn't update the origin state (URL redirect |
| 615 // chains, Content-Disposition, download URL, etc..) |
| 616 TEST_P(DownloadItemTestWithResumption, |
| 617 FailedResumptionDoesntUpdateOriginState) { |
| 618 const char kContentDisposition[] = "attachment; filename=foo"; |
| 619 const char kFirstETag[] = "ABC"; |
| 620 const char kFirstLastModified[] = "Yesterday"; |
| 621 const char kFirstURL[] = "http://www.example.com/download"; |
| 622 create_info()->content_disposition = kContentDisposition; |
| 623 create_info()->etag = kFirstETag; |
| 624 create_info()->last_modified = kFirstLastModified; |
| 625 create_info()->url_chain.push_back(GURL(kFirstURL)); |
| 626 |
| 627 DownloadItemImpl* item = CreateDownloadItem(); |
| 628 MockDownloadFile* download_file = |
| 629 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 630 EXPECT_EQ(kContentDisposition, item->GetContentDisposition()); |
| 631 EXPECT_EQ(kFirstETag, item->GetETag()); |
| 632 EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime()); |
| 633 EXPECT_EQ(kFirstURL, item->GetURL().spec()); |
| 634 |
| 635 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)); |
| 636 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
| 637 .WillRepeatedly(Return(GetBrowserContext())); |
| 638 EXPECT_CALL(*download_file, Detach()); |
| 639 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 640 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
| 641 RunAllPendingInMessageLoops(); |
| 642 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 643 |
| 644 // Now change the create info. The changes should not cause the DownloadItem |
| 645 // to be updated. |
| 646 const char kSecondContentDisposition[] = "attachment; filename=bar"; |
| 647 const char kSecondETag[] = "123"; |
| 648 const char kSecondLastModified[] = "Today"; |
| 649 const char kSecondURL[] = "http://example.com/another-download"; |
| 650 create_info()->content_disposition = kSecondContentDisposition; |
| 651 create_info()->etag = kSecondETag; |
| 652 create_info()->last_modified = kSecondLastModified; |
| 653 create_info()->url_chain.clear(); |
| 654 create_info()->url_chain.push_back(GURL(kSecondURL)); |
| 655 create_info()->result = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED; |
| 656 |
| 657 // The following ends up calling DownloadItem::Start(), but shouldn't result |
| 658 // in an origin update. |
| 659 DownloadItemImplDelegate::DownloadTargetCallback download_target_callback; |
| 660 download_file = |
| 661 AddDownloadFileToDownloadItem(item, &download_target_callback); |
| 662 |
| 663 EXPECT_EQ(kContentDisposition, item->GetContentDisposition()); |
| 664 EXPECT_EQ(kFirstETag, item->GetETag()); |
| 665 EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime()); |
| 666 EXPECT_EQ(kFirstURL, item->GetURL().spec()); |
| 667 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 668 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason()); |
| 669 } |
| 670 |
| 548 // Test that resumption uses the final URL in a URL chain when resuming. | 671 // Test that resumption uses the final URL in a URL chain when resuming. |
| 549 TEST_F(DownloadItemTest, ResumeUsingFinalURL) { | 672 TEST_P(DownloadItemTestWithResumption, ResumeUsingFinalURL) { |
| 550 TestBrowserContext test_browser_context; | 673 create_info()->save_info->prompt_for_save_location = false; |
| 551 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo); | 674 create_info()->url_chain.clear(); |
| 552 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); | 675 create_info()->url_chain.push_back(GURL("http://example.com/a")); |
| 553 create_info->save_info->prompt_for_save_location = false; | 676 create_info()->url_chain.push_back(GURL("http://example.com/b")); |
| 554 create_info->etag = "SomethingToSatisfyResumption"; | 677 create_info()->url_chain.push_back(GURL("http://example.com/c")); |
| 555 create_info->url_chain.push_back(GURL("http://example.com/a")); | |
| 556 create_info->url_chain.push_back(GURL("http://example.com/b")); | |
| 557 create_info->url_chain.push_back(GURL("http://example.com/c")); | |
| 558 | 678 |
| 559 DownloadItemImpl* item = | 679 DownloadItemImpl* item = CreateDownloadItem(); |
| 560 CreateDownloadItemWithCreateInfo(std::move(create_info)); | |
| 561 TestDownloadItemObserver observer(item); | 680 TestDownloadItemObserver observer(item); |
| 562 MockDownloadFile* download_file = | 681 MockDownloadFile* download_file = |
| 563 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 682 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 564 | 683 |
| 565 // Interrupt the download, using a continuable interrupt. | 684 // Interrupt the download, using a continuable interrupt. |
| 566 EXPECT_CALL(*download_file, FullPath()).WillOnce(Return(base::FilePath())); | 685 EXPECT_CALL(*download_file, FullPath()).WillOnce(Return(base::FilePath())); |
| 567 EXPECT_CALL(*download_file, Detach()); | 686 EXPECT_CALL(*download_file, Detach()); |
| 568 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | 687 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
| 569 .WillRepeatedly(Return(&test_browser_context)); | 688 .WillRepeatedly(Return(GetBrowserContext())); |
| 570 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( | 689 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( |
| 571 Property(&DownloadUrlParameters::url, | 690 Property(&DownloadUrlParameters::url, |
| 572 GURL("http://example.com/c")), | 691 GURL("http://example.com/c")), |
| 573 _)) | 692 _)) |
| 574 .Times(1); | 693 .Times(1); |
| 575 item->DestinationObserverAsWeakPtr()->DestinationError( | 694 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 576 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 695 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
| 577 | 696 |
| 578 // Test expectations verify that ResumeInterruptedDownload() is called (by way | 697 // Test expectations verify that ResumeInterruptedDownload() is called (by way |
| 579 // of MockResumeInterruptedDownload) after the download is interrupted. But | 698 // of MockResumeInterruptedDownload) after the download is interrupted. But |
| (...skipping 22 matching lines...) Expand all Loading... |
| 602 // Setting to NOT_DANGEROUS does not trigger a notification. | 721 // Setting to NOT_DANGEROUS does not trigger a notification. |
| 603 DownloadItemImpl* safe_item = CreateDownloadItem(); | 722 DownloadItemImpl* safe_item = CreateDownloadItem(); |
| 604 TestDownloadItemObserver safe_observer(safe_item); | 723 TestDownloadItemObserver safe_observer(safe_item); |
| 605 | 724 |
| 606 safe_item->OnAllDataSaved(std::string()); | 725 safe_item->OnAllDataSaved(std::string()); |
| 607 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); | 726 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); |
| 608 safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 727 safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 609 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); | 728 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); |
| 610 | 729 |
| 611 // Setting to unsafe url or unsafe file should trigger a notification. | 730 // Setting to unsafe url or unsafe file should trigger a notification. |
| 612 DownloadItemImpl* unsafeurl_item = | 731 DownloadItemImpl* unsafeurl_item = CreateDownloadItem(); |
| 613 CreateDownloadItem(); | |
| 614 TestDownloadItemObserver unsafeurl_observer(unsafeurl_item); | 732 TestDownloadItemObserver unsafeurl_observer(unsafeurl_item); |
| 615 | 733 |
| 616 unsafeurl_item->OnAllDataSaved(std::string()); | 734 unsafeurl_item->OnAllDataSaved(std::string()); |
| 617 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); | 735 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); |
| 618 unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL); | 736 unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL); |
| 619 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); | 737 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); |
| 620 | 738 |
| 621 unsafeurl_item->ValidateDangerousDownload(); | 739 unsafeurl_item->ValidateDangerousDownload(); |
| 622 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); | 740 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); |
| 623 | 741 |
| 624 DownloadItemImpl* unsafefile_item = | 742 DownloadItemImpl* unsafefile_item = CreateDownloadItem(); |
| 625 CreateDownloadItem(); | |
| 626 TestDownloadItemObserver unsafefile_observer(unsafefile_item); | 743 TestDownloadItemObserver unsafefile_observer(unsafefile_item); |
| 627 | 744 |
| 628 unsafefile_item->OnAllDataSaved(std::string()); | 745 unsafefile_item->OnAllDataSaved(std::string()); |
| 629 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); | 746 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); |
| 630 unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | 747 unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); |
| 631 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); | 748 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); |
| 632 | 749 |
| 633 unsafefile_item->ValidateDangerousDownload(); | 750 unsafefile_item->ValidateDangerousDownload(); |
| 634 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); | 751 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); |
| 635 } | 752 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 TEST_F(DownloadItemTest, NotificationAfterTogglePause) { | 785 TEST_F(DownloadItemTest, NotificationAfterTogglePause) { |
| 669 DownloadItemImpl* item = CreateDownloadItem(); | 786 DownloadItemImpl* item = CreateDownloadItem(); |
| 670 TestDownloadItemObserver observer(item); | 787 TestDownloadItemObserver observer(item); |
| 671 MockDownloadFile* mock_download_file(new MockDownloadFile); | 788 MockDownloadFile* mock_download_file(new MockDownloadFile); |
| 672 scoped_ptr<DownloadFile> download_file(mock_download_file); | 789 scoped_ptr<DownloadFile> download_file(mock_download_file); |
| 673 scoped_ptr<DownloadRequestHandleInterface> request_handle( | 790 scoped_ptr<DownloadRequestHandleInterface> request_handle( |
| 674 new NiceMock<MockRequestHandle>); | 791 new NiceMock<MockRequestHandle>); |
| 675 | 792 |
| 676 EXPECT_CALL(*mock_download_file, Initialize(_)); | 793 EXPECT_CALL(*mock_download_file, Initialize(_)); |
| 677 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)); | 794 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)); |
| 678 item->Start(std::move(download_file), std::move(request_handle)); | 795 item->Start(std::move(download_file), std::move(request_handle), |
| 796 *create_info()); |
| 679 | 797 |
| 680 item->Pause(); | 798 item->Pause(); |
| 681 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 799 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 682 | 800 |
| 683 ASSERT_TRUE(item->IsPaused()); | 801 ASSERT_TRUE(item->IsPaused()); |
| 684 | 802 |
| 685 item->Resume(); | 803 item->Resume(); |
| 686 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 804 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 687 | 805 |
| 688 RunAllPendingInMessageLoops(); | 806 RunAllPendingInMessageLoops(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 715 | 833 |
| 716 // Test to make sure that Start method calls DF initialize properly. | 834 // Test to make sure that Start method calls DF initialize properly. |
| 717 TEST_F(DownloadItemTest, Start) { | 835 TEST_F(DownloadItemTest, Start) { |
| 718 MockDownloadFile* mock_download_file(new MockDownloadFile); | 836 MockDownloadFile* mock_download_file(new MockDownloadFile); |
| 719 scoped_ptr<DownloadFile> download_file(mock_download_file); | 837 scoped_ptr<DownloadFile> download_file(mock_download_file); |
| 720 DownloadItemImpl* item = CreateDownloadItem(); | 838 DownloadItemImpl* item = CreateDownloadItem(); |
| 721 EXPECT_CALL(*mock_download_file, Initialize(_)); | 839 EXPECT_CALL(*mock_download_file, Initialize(_)); |
| 722 scoped_ptr<DownloadRequestHandleInterface> request_handle( | 840 scoped_ptr<DownloadRequestHandleInterface> request_handle( |
| 723 new NiceMock<MockRequestHandle>); | 841 new NiceMock<MockRequestHandle>); |
| 724 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); | 842 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); |
| 725 item->Start(std::move(download_file), std::move(request_handle)); | 843 item->Start(std::move(download_file), std::move(request_handle), |
| 844 *create_info()); |
| 726 RunAllPendingInMessageLoops(); | 845 RunAllPendingInMessageLoops(); |
| 727 | 846 |
| 728 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); | 847 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); |
| 729 } | 848 } |
| 730 | 849 |
| 850 // Handling of downloads initiated via a failed request. In this case, Start() |
| 851 // will get called with a DownloadCreateInfo with a non-zero interrupt_reason. |
| 852 TEST_F(DownloadItemTest, StartFailedDownload) { |
| 853 create_info()->result = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED; |
| 854 DownloadItemImpl* item = CreateDownloadItem(); |
| 855 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 856 |
| 857 // DownloadFile and DownloadRequestHandleInterface objects aren't created for |
| 858 // failed downloads. |
| 859 scoped_ptr<DownloadFile> null_download_file; |
| 860 scoped_ptr<DownloadRequestHandleInterface> null_request_handle; |
| 861 DownloadItemImplDelegate::DownloadTargetCallback download_target_callback; |
| 862 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) |
| 863 .WillOnce(SaveArg<1>(&download_target_callback)); |
| 864 item->Start(std::move(null_download_file), std::move(null_request_handle), |
| 865 *create_info()); |
| 866 RunAllPendingInMessageLoops(); |
| 867 |
| 868 // The DownloadItemImpl should attempt to determine a target path even if the |
| 869 // download was interrupted. |
| 870 ASSERT_FALSE(download_target_callback.is_null()); |
| 871 ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 872 base::FilePath target_path(FILE_PATH_LITERAL("foo")); |
| 873 download_target_callback.Run(target_path, |
| 874 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 875 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, target_path); |
| 876 RunAllPendingInMessageLoops(); |
| 877 |
| 878 EXPECT_EQ(target_path, item->GetTargetFilePath()); |
| 879 CleanupItem(item, NULL, DownloadItem::INTERRUPTED); |
| 880 } |
| 881 |
| 731 // Test that the delegate is invoked after the download file is renamed. | 882 // Test that the delegate is invoked after the download file is renamed. |
| 732 TEST_F(DownloadItemTest, CallbackAfterRename) { | 883 TEST_F(DownloadItemTest, CallbackAfterRename) { |
| 733 DownloadItemImpl* item = CreateDownloadItem(); | 884 DownloadItemImpl* item = CreateDownloadItem(); |
| 734 DownloadItemImplDelegate::DownloadTargetCallback callback; | 885 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 735 MockDownloadFile* download_file = | 886 MockDownloadFile* download_file = |
| 736 AddDownloadFileToDownloadItem(item, &callback); | 887 AddDownloadFileToDownloadItem(item, &callback); |
| 737 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); | 888 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); |
| 738 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 889 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
| 739 base::FilePath new_intermediate_path( | 890 base::FilePath new_intermediate_path( |
| 740 final_path.InsertBeforeExtensionASCII("y")); | 891 final_path.InsertBeforeExtensionASCII("y")); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 ::testing::Mock::VerifyAndClearExpectations(download_file); | 988 ::testing::Mock::VerifyAndClearExpectations(download_file); |
| 838 mock_delegate()->VerifyAndClearExpectations(); | 989 mock_delegate()->VerifyAndClearExpectations(); |
| 839 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 990 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 840 EXPECT_TRUE(item->GetFullPath().empty()); | 991 EXPECT_TRUE(item->GetFullPath().empty()); |
| 841 EXPECT_EQ(final_path, item->GetTargetFilePath()); | 992 EXPECT_EQ(final_path, item->GetTargetFilePath()); |
| 842 } | 993 } |
| 843 | 994 |
| 844 // As above. But if the download can be resumed by continuing, then the | 995 // As above. But if the download can be resumed by continuing, then the |
| 845 // intermediate path should be retained when the download is interrupted after | 996 // intermediate path should be retained when the download is interrupted after |
| 846 // the intermediate rename succeeds. | 997 // the intermediate rename succeeds. |
| 847 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) { | 998 TEST_P(DownloadItemTestWithResumption, |
| 999 InterruptedBeforeIntermediateRename_Continue) { |
| 848 DownloadItemImpl* item = CreateDownloadItem(); | 1000 DownloadItemImpl* item = CreateDownloadItem(); |
| 849 DownloadItemImplDelegate::DownloadTargetCallback callback; | 1001 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 850 MockDownloadFile* download_file = | 1002 MockDownloadFile* download_file = |
| 851 AddDownloadFileToDownloadItem(item, &callback); | 1003 AddDownloadFileToDownloadItem(item, &callback); |
| 852 item->DestinationObserverAsWeakPtr()->DestinationError( | 1004 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 853 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); | 1005 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); |
| 854 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1006 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 855 | 1007 |
| 856 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); | 1008 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); |
| 857 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 1009 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 870 // All the callbacks should have happened by now. | 1022 // All the callbacks should have happened by now. |
| 871 ::testing::Mock::VerifyAndClearExpectations(download_file); | 1023 ::testing::Mock::VerifyAndClearExpectations(download_file); |
| 872 mock_delegate()->VerifyAndClearExpectations(); | 1024 mock_delegate()->VerifyAndClearExpectations(); |
| 873 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 1025 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 874 EXPECT_EQ(new_intermediate_path, item->GetFullPath()); | 1026 EXPECT_EQ(new_intermediate_path, item->GetFullPath()); |
| 875 EXPECT_EQ(final_path, item->GetTargetFilePath()); | 1027 EXPECT_EQ(final_path, item->GetTargetFilePath()); |
| 876 } | 1028 } |
| 877 | 1029 |
| 878 // As above. If the intermediate rename fails, then the interrupt reason should | 1030 // As above. If the intermediate rename fails, then the interrupt reason should |
| 879 // be set to the destination error and the intermediate path should be empty. | 1031 // be set to the destination error and the intermediate path should be empty. |
| 880 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) { | 1032 TEST_P(DownloadItemTestWithResumption, |
| 1033 InterruptedBeforeIntermediateRename_Failed) { |
| 881 DownloadItemImpl* item = CreateDownloadItem(); | 1034 DownloadItemImpl* item = CreateDownloadItem(); |
| 882 DownloadItemImplDelegate::DownloadTargetCallback callback; | 1035 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 883 MockDownloadFile* download_file = | 1036 MockDownloadFile* download_file = |
| 884 AddDownloadFileToDownloadItem(item, &callback); | 1037 AddDownloadFileToDownloadItem(item, &callback); |
| 885 item->DestinationObserverAsWeakPtr()->DestinationError( | 1038 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 886 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); | 1039 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); |
| 887 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1040 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 888 | 1041 |
| 889 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); | 1042 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); |
| 890 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 1043 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); | 1421 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); |
| 1269 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); | 1422 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); |
| 1270 item->StealDangerousDownload( | 1423 item->StealDangerousDownload( |
| 1271 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, | 1424 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, |
| 1272 weak_ptr_factory.GetWeakPtr(), | 1425 weak_ptr_factory.GetWeakPtr(), |
| 1273 base::Unretained(&returned_path))); | 1426 base::Unretained(&returned_path))); |
| 1274 RunAllPendingInMessageLoops(); | 1427 RunAllPendingInMessageLoops(); |
| 1275 EXPECT_EQ(full_path, returned_path); | 1428 EXPECT_EQ(full_path, returned_path); |
| 1276 } | 1429 } |
| 1277 | 1430 |
| 1278 TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) { | 1431 TEST_P(DownloadItemTestWithResumption, StealInterruptedDangerousDownload) { |
| 1279 base::FilePath returned_path; | 1432 base::FilePath returned_path; |
| 1280 DownloadItemImpl* item = CreateDownloadItem(); | 1433 DownloadItemImpl* item = CreateDownloadItem(); |
| 1281 MockDownloadFile* download_file = | 1434 MockDownloadFile* download_file = |
| 1282 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | 1435 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); |
| 1283 base::FilePath full_path = item->GetFullPath(); | 1436 base::FilePath full_path = item->GetFullPath(); |
| 1284 EXPECT_FALSE(full_path.empty()); | 1437 EXPECT_FALSE(full_path.empty()); |
| 1285 EXPECT_CALL(*download_file, FullPath()) | 1438 EXPECT_CALL(*download_file, FullPath()) |
| 1286 .WillOnce(Return(full_path)); | 1439 .WillOnce(Return(full_path)); |
| 1287 EXPECT_CALL(*download_file, Detach()); | 1440 EXPECT_CALL(*download_file, Detach()); |
| 1288 item->DestinationObserverAsWeakPtr()->DestinationError( | 1441 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 1289 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); | 1442 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); |
| 1290 ASSERT_TRUE(item->IsDangerous()); | 1443 ASSERT_TRUE(item->IsDangerous()); |
| 1291 | 1444 |
| 1292 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); | 1445 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); |
| 1293 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); | 1446 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); |
| 1294 item->StealDangerousDownload( | 1447 item->StealDangerousDownload( |
| 1295 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, | 1448 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, |
| 1296 weak_ptr_factory.GetWeakPtr(), | 1449 weak_ptr_factory.GetWeakPtr(), |
| 1297 base::Unretained(&returned_path))); | 1450 base::Unretained(&returned_path))); |
| 1298 RunAllPendingInMessageLoops(); | 1451 RunAllPendingInMessageLoops(); |
| 1299 EXPECT_EQ(full_path, returned_path); | 1452 EXPECT_EQ(full_path, returned_path); |
| 1300 } | 1453 } |
| 1301 | 1454 |
| 1302 TEST_F(DownloadItemTest, StealInterruptedNonResumableDangerousDownload) { | 1455 TEST_P(DownloadItemTestWithResumption, |
| 1456 StealInterruptedNonResumableDangerousDownload) { |
| 1303 base::FilePath returned_path; | 1457 base::FilePath returned_path; |
| 1304 DownloadItemImpl* item = CreateDownloadItem(); | 1458 DownloadItemImpl* item = CreateDownloadItem(); |
| 1305 MockDownloadFile* download_file = | 1459 MockDownloadFile* download_file = |
| 1306 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | 1460 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); |
| 1307 EXPECT_CALL(*download_file, Cancel()); | 1461 EXPECT_CALL(*download_file, Cancel()); |
| 1308 item->DestinationObserverAsWeakPtr()->DestinationError( | 1462 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 1309 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 1463 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
| 1310 ASSERT_TRUE(item->IsDangerous()); | 1464 ASSERT_TRUE(item->IsDangerous()); |
| 1311 | 1465 |
| 1312 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); | 1466 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); |
| 1313 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); | 1467 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); |
| 1314 item->StealDangerousDownload( | 1468 item->StealDangerousDownload( |
| 1315 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, | 1469 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, |
| 1316 weak_ptr_factory.GetWeakPtr(), | 1470 weak_ptr_factory.GetWeakPtr(), |
| 1317 base::Unretained(&returned_path))); | 1471 base::Unretained(&returned_path))); |
| 1318 RunAllPendingInMessageLoops(); | 1472 RunAllPendingInMessageLoops(); |
| 1319 EXPECT_TRUE(returned_path.empty()); | 1473 EXPECT_TRUE(returned_path.empty()); |
| 1320 } | 1474 } |
| 1321 | 1475 |
| 1322 TEST(MockDownloadItem, Compiles) { | 1476 TEST(MockDownloadItem, Compiles) { |
| 1323 MockDownloadItem mock_item; | 1477 MockDownloadItem mock_item; |
| 1324 } | 1478 } |
| 1325 | 1479 |
| 1326 } // namespace content | 1480 } // namespace content |
| OLD | NEW |