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 |