Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / download / download_history_unittest.cc
blob0316883af53315d071c2e778266ce085da25f2e0
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <set>
6 #include <vector>
8 #include "base/rand_util.h"
9 #include "base/stl_util.h"
10 #include "chrome/browser/download/download_history.h"
11 #include "chrome/browser/history/download_database.h"
12 #include "chrome/browser/history/download_row.h"
13 #include "chrome/browser/history/history_service.h"
14 #include "content/public/test/mock_download_item.h"
15 #include "content/public/test/mock_download_manager.h"
16 #include "content/public/test/test_browser_thread.h"
17 #include "content/public/test/test_utils.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 #if !defined(OS_ANDROID)
21 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
22 #endif
24 using testing::DoAll;
25 using testing::Invoke;
26 using testing::Return;
27 using testing::ReturnRefOfCopy;
28 using testing::SetArgPointee;
29 using testing::WithArg;
30 using testing::_;
32 namespace {
34 void CheckInfoEqual(const history::DownloadRow& left,
35 const history::DownloadRow& right) {
36 EXPECT_EQ(left.current_path.value(), right.current_path.value());
37 EXPECT_EQ(left.target_path.value(), right.target_path.value());
38 EXPECT_EQ(left.url_chain.size(), right.url_chain.size());
39 for (unsigned int i = 0;
40 i < left.url_chain.size() && i < right.url_chain.size();
41 ++i) {
42 EXPECT_EQ(left.url_chain[i].spec(), right.url_chain[i].spec());
44 EXPECT_EQ(left.referrer_url.spec(), right.referrer_url.spec());
45 EXPECT_EQ(left.start_time.ToTimeT(), right.start_time.ToTimeT());
46 EXPECT_EQ(left.end_time.ToTimeT(), right.end_time.ToTimeT());
47 EXPECT_EQ(left.etag, right.etag);
48 EXPECT_EQ(left.last_modified, right.last_modified);
49 EXPECT_EQ(left.received_bytes, right.received_bytes);
50 EXPECT_EQ(left.total_bytes, right.total_bytes);
51 EXPECT_EQ(left.state, right.state);
52 EXPECT_EQ(left.danger_type, right.danger_type);
53 EXPECT_EQ(left.id, right.id);
54 EXPECT_EQ(left.opened, right.opened);
55 EXPECT_EQ(left.by_ext_id, right.by_ext_id);
56 EXPECT_EQ(left.by_ext_name, right.by_ext_name);
59 typedef DownloadHistory::IdSet IdSet;
60 typedef std::vector<history::DownloadRow> InfoVector;
61 typedef testing::StrictMock<content::MockDownloadItem> StrictMockDownloadItem;
63 class FakeHistoryAdapter : public DownloadHistory::HistoryAdapter {
64 public:
65 FakeHistoryAdapter()
66 : DownloadHistory::HistoryAdapter(NULL),
67 slow_create_download_(false),
68 fail_create_download_(false) {
71 virtual ~FakeHistoryAdapter() {}
73 virtual void QueryDownloads(
74 const HistoryService::DownloadQueryCallback& callback) OVERRIDE {
75 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
76 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
77 base::Bind(&FakeHistoryAdapter::QueryDownloadsDone,
78 base::Unretained(this), callback));
81 void QueryDownloadsDone(
82 const HistoryService::DownloadQueryCallback& callback) {
83 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
84 CHECK(expect_query_downloads_.get());
85 callback.Run(expect_query_downloads_.Pass());
88 void set_slow_create_download(bool slow) { slow_create_download_ = slow; }
90 virtual void CreateDownload(
91 const history::DownloadRow& info,
92 const HistoryService::DownloadCreateCallback& callback) OVERRIDE {
93 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
94 create_download_info_ = info;
95 // Must not call CreateDownload() again before FinishCreateDownload()!
96 DCHECK(create_download_callback_.is_null());
97 create_download_callback_ = base::Bind(callback, !fail_create_download_);
98 fail_create_download_ = false;
99 if (!slow_create_download_)
100 FinishCreateDownload();
103 void FinishCreateDownload() {
104 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
105 create_download_callback_.Run();
106 create_download_callback_.Reset();
109 virtual void UpdateDownload(
110 const history::DownloadRow& info) OVERRIDE {
111 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
112 update_download_ = info;
115 virtual void RemoveDownloads(const IdSet& ids) OVERRIDE {
116 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
117 for (IdSet::const_iterator it = ids.begin();
118 it != ids.end(); ++it) {
119 remove_downloads_.insert(*it);
123 void ExpectWillQueryDownloads(scoped_ptr<InfoVector> infos) {
124 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
125 expect_query_downloads_ = infos.Pass();
128 void ExpectQueryDownloadsDone() {
129 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
130 EXPECT_TRUE(NULL == expect_query_downloads_.get());
133 void FailCreateDownload() {
134 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
135 fail_create_download_ = true;
138 void ExpectDownloadCreated(
139 const history::DownloadRow& info) {
140 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
141 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
142 CheckInfoEqual(info, create_download_info_);
143 create_download_info_ = history::DownloadRow();
146 void ExpectNoDownloadCreated() {
147 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
148 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
149 CheckInfoEqual(history::DownloadRow(), create_download_info_);
152 void ExpectDownloadUpdated(const history::DownloadRow& info) {
153 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
154 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
155 CheckInfoEqual(update_download_, info);
156 update_download_ = history::DownloadRow();
159 void ExpectNoDownloadUpdated() {
160 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
161 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
162 CheckInfoEqual(history::DownloadRow(), update_download_);
165 void ExpectNoDownloadsRemoved() {
166 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
167 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
168 EXPECT_EQ(0, static_cast<int>(remove_downloads_.size()));
171 void ExpectDownloadsRemoved(const IdSet& ids) {
172 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
173 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
174 IdSet differences = base::STLSetDifference<IdSet>(ids, remove_downloads_);
175 for (IdSet::const_iterator different = differences.begin();
176 different != differences.end(); ++different) {
177 EXPECT_TRUE(false) << *different;
179 remove_downloads_.clear();
182 private:
183 bool slow_create_download_;
184 bool fail_create_download_;
185 base::Closure create_download_callback_;
186 history::DownloadRow update_download_;
187 scoped_ptr<InfoVector> expect_query_downloads_;
188 IdSet remove_downloads_;
189 history::DownloadRow create_download_info_;
191 DISALLOW_COPY_AND_ASSIGN(FakeHistoryAdapter);
194 class DownloadHistoryTest : public testing::Test {
195 public:
196 DownloadHistoryTest()
197 : ui_thread_(content::BrowserThread::UI, &loop_),
198 manager_(new content::MockDownloadManager()),
199 history_(NULL),
200 manager_observer_(NULL),
201 item_observer_(NULL),
202 download_created_index_(0) {}
203 virtual ~DownloadHistoryTest() {
204 STLDeleteElements(&items_);
207 protected:
208 virtual void TearDown() OVERRIDE {
209 download_history_.reset();
212 content::MockDownloadManager& manager() { return *manager_.get(); }
213 content::MockDownloadItem& item(size_t index) { return *items_[index]; }
215 void SetManagerObserver(
216 content::DownloadManager::Observer* manager_observer) {
217 manager_observer_ = manager_observer;
219 content::DownloadManager::Observer* manager_observer() {
220 return manager_observer_;
223 // Relies on the same object observing all download items.
224 void SetItemObserver(
225 content::DownloadItem::Observer* item_observer) {
226 item_observer_ = item_observer;
228 content::DownloadItem::Observer* item_observer() {
229 return item_observer_;
232 void ExpectWillQueryDownloads(scoped_ptr<InfoVector> infos) {
233 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
234 CHECK(infos.get());
235 EXPECT_CALL(manager(), AddObserver(_)).WillOnce(WithArg<0>(Invoke(
236 this, &DownloadHistoryTest::SetManagerObserver)));
237 EXPECT_CALL(manager(), RemoveObserver(_));
238 download_created_index_ = 0;
239 for (size_t index = 0; index < infos->size(); ++index) {
240 content::MockDownloadManager::CreateDownloadItemAdapter adapter(
241 infos->at(index).id,
242 infos->at(index).current_path,
243 infos->at(index).target_path,
244 infos->at(index).url_chain,
245 infos->at(index).referrer_url,
246 infos->at(index).start_time,
247 infos->at(index).end_time,
248 infos->at(index).etag,
249 infos->at(index).last_modified,
250 infos->at(index).received_bytes,
251 infos->at(index).total_bytes,
252 infos->at(index).state,
253 infos->at(index).danger_type,
254 infos->at(index).interrupt_reason,
255 infos->at(index).opened);
256 EXPECT_CALL(manager(), MockCreateDownloadItem(adapter))
257 .WillOnce(DoAll(
258 InvokeWithoutArgs(
259 this, &DownloadHistoryTest::CallOnDownloadCreatedInOrder),
260 Return(&item(index))));
262 EXPECT_CALL(manager(), CheckForHistoryFilesRemoval());
263 history_ = new FakeHistoryAdapter();
264 history_->ExpectWillQueryDownloads(infos.Pass());
265 EXPECT_CALL(*manager_.get(), GetAllDownloads(_)).WillRepeatedly(Return());
266 download_history_.reset(new DownloadHistory(
267 &manager(), scoped_ptr<DownloadHistory::HistoryAdapter>(history_)));
268 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
269 history_->ExpectQueryDownloadsDone();
272 void CallOnDownloadCreated(size_t index) {
273 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
274 manager_observer()->OnDownloadCreated(&manager(), &item(index));
277 void CallOnDownloadCreatedInOrder() {
278 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
279 // Gmock doesn't appear to support something like InvokeWithTheseArgs. Maybe
280 // gmock needs to learn about base::Callback.
281 CallOnDownloadCreated(download_created_index_++);
284 void set_slow_create_download(bool slow) {
285 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
286 history_->set_slow_create_download(slow);
289 void FinishCreateDownload() {
290 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
291 history_->FinishCreateDownload();
294 void FailCreateDownload() {
295 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
296 history_->FailCreateDownload();
299 void ExpectDownloadCreated(
300 const history::DownloadRow& info) {
301 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
302 history_->ExpectDownloadCreated(info);
305 void ExpectNoDownloadCreated() {
306 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
307 history_->ExpectNoDownloadCreated();
310 void ExpectDownloadUpdated(const history::DownloadRow& info) {
311 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
312 history_->ExpectDownloadUpdated(info);
315 void ExpectNoDownloadUpdated() {
316 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
317 history_->ExpectNoDownloadUpdated();
320 void ExpectNoDownloadsRemoved() {
321 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
322 history_->ExpectNoDownloadsRemoved();
325 void ExpectDownloadsRemoved(const IdSet& ids) {
326 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
327 history_->ExpectDownloadsRemoved(ids);
330 void InitBasicItem(const base::FilePath::CharType* path,
331 const char* url_string,
332 const char* referrer_string,
333 history::DownloadRow* info) {
334 GURL url(url_string);
335 GURL referrer(referrer_string);
336 std::vector<GURL> url_chain;
337 url_chain.push_back(url);
338 InitItem(static_cast<uint32>(items_.size() + 1),
339 base::FilePath(path),
340 base::FilePath(path),
341 url_chain,
342 referrer,
343 (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
344 (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
345 "Etag",
346 "abc",
347 100,
348 100,
349 content::DownloadItem::COMPLETE,
350 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
351 content::DOWNLOAD_INTERRUPT_REASON_NONE,
352 false,
353 std::string(),
354 std::string(),
355 info);
358 void InitItem(
359 uint32 id,
360 const base::FilePath& current_path,
361 const base::FilePath& target_path,
362 const std::vector<GURL>& url_chain,
363 const GURL& referrer,
364 const base::Time& start_time,
365 const base::Time& end_time,
366 const std::string& etag,
367 const std::string& last_modified,
368 int64 received_bytes,
369 int64 total_bytes,
370 content::DownloadItem::DownloadState state,
371 content::DownloadDangerType danger_type,
372 content::DownloadInterruptReason interrupt_reason,
373 bool opened,
374 const std::string& by_extension_id,
375 const std::string& by_extension_name,
376 history::DownloadRow* info) {
377 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
379 size_t index = items_.size();
380 StrictMockDownloadItem* mock_item = new StrictMockDownloadItem();
381 items_.push_back(mock_item);
383 info->current_path = current_path;
384 info->target_path = target_path;
385 info->url_chain = url_chain;
386 info->referrer_url = referrer;
387 info->start_time = start_time;
388 info->end_time = end_time;
389 info->etag = etag;
390 info->last_modified = last_modified;
391 info->received_bytes = received_bytes;
392 info->total_bytes = total_bytes;
393 info->state = state;
394 info->danger_type = danger_type;
395 info->interrupt_reason = interrupt_reason;
396 info->id = id;
397 info->opened = opened;
398 info->by_ext_id = by_extension_id;
399 info->by_ext_name = by_extension_name;
401 EXPECT_CALL(item(index), GetId()).WillRepeatedly(Return(id));
402 EXPECT_CALL(item(index), GetFullPath())
403 .WillRepeatedly(ReturnRefOfCopy(current_path));
404 EXPECT_CALL(item(index), GetTargetFilePath())
405 .WillRepeatedly(ReturnRefOfCopy(target_path));
406 DCHECK_LE(1u, url_chain.size());
407 EXPECT_CALL(item(index), GetURL())
408 .WillRepeatedly(ReturnRefOfCopy(url_chain[0]));
409 EXPECT_CALL(item(index), GetUrlChain())
410 .WillRepeatedly(ReturnRefOfCopy(url_chain));
411 EXPECT_CALL(item(index), GetMimeType())
412 .WillRepeatedly(Return("application/octet-stream"));
413 EXPECT_CALL(item(index), GetReferrerUrl())
414 .WillRepeatedly(ReturnRefOfCopy(referrer));
415 EXPECT_CALL(item(index), GetStartTime()).WillRepeatedly(Return(start_time));
416 EXPECT_CALL(item(index), GetEndTime()).WillRepeatedly(Return(end_time));
417 EXPECT_CALL(item(index), GetETag()).WillRepeatedly(ReturnRefOfCopy(etag));
418 EXPECT_CALL(item(index), GetLastModifiedTime())
419 .WillRepeatedly(ReturnRefOfCopy(last_modified));
420 EXPECT_CALL(item(index), GetReceivedBytes())
421 .WillRepeatedly(Return(received_bytes));
422 EXPECT_CALL(item(index), GetTotalBytes())
423 .WillRepeatedly(Return(total_bytes));
424 EXPECT_CALL(item(index), GetState()).WillRepeatedly(Return(state));
425 EXPECT_CALL(item(index), GetDangerType())
426 .WillRepeatedly(Return(danger_type));
427 EXPECT_CALL(item(index), GetLastReason())
428 .WillRepeatedly(Return(interrupt_reason));
429 EXPECT_CALL(item(index), GetOpened()).WillRepeatedly(Return(opened));
430 EXPECT_CALL(item(index), GetTargetDisposition())
431 .WillRepeatedly(
432 Return(content::DownloadItem::TARGET_DISPOSITION_OVERWRITE));
433 EXPECT_CALL(manager(), GetDownload(id))
434 .WillRepeatedly(Return(&item(index)));
435 EXPECT_CALL(item(index), AddObserver(_))
436 .WillOnce(WithArg<0>(
437 Invoke(this, &DownloadHistoryTest::SetItemObserver)));
438 EXPECT_CALL(item(index), RemoveObserver(_));
439 EXPECT_CALL(item(index), IsTemporary()).WillRepeatedly(Return(false));
440 #if !defined(OS_ANDROID)
441 new DownloadedByExtension(&item(index), by_extension_id, by_extension_name);
442 #endif
444 std::vector<content::DownloadItem*> items;
445 for (size_t i = 0; i < items_.size(); ++i) {
446 items.push_back(&item(i));
448 EXPECT_CALL(*manager_.get(), GetAllDownloads(_))
449 .WillRepeatedly(SetArgPointee<0>(items));
452 private:
453 base::MessageLoopForUI loop_;
454 content::TestBrowserThread ui_thread_;
455 std::vector<StrictMockDownloadItem*> items_;
456 scoped_ptr<content::MockDownloadManager> manager_;
457 FakeHistoryAdapter* history_;
458 scoped_ptr<DownloadHistory> download_history_;
459 content::DownloadManager::Observer* manager_observer_;
460 content::DownloadItem::Observer* item_observer_;
461 size_t download_created_index_;
463 DISALLOW_COPY_AND_ASSIGN(DownloadHistoryTest);
466 } // anonymous namespace
468 // Test loading an item from the database, changing it, saving it back, removing
469 // it.
470 TEST_F(DownloadHistoryTest, DownloadHistoryTest_Load) {
471 // Load a download from history, create the item, OnDownloadCreated,
472 // OnDownloadUpdated, OnDownloadRemoved.
473 history::DownloadRow info;
474 InitBasicItem(FILE_PATH_LITERAL("/foo/bar.pdf"),
475 "http://example.com/bar.pdf",
476 "http://example.com/referrer.html",
477 &info);
479 scoped_ptr<InfoVector> infos(new InfoVector());
480 infos->push_back(info);
481 ExpectWillQueryDownloads(infos.Pass());
482 ExpectNoDownloadCreated();
484 EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
486 // Pretend that something changed on the item.
487 EXPECT_CALL(item(0), GetOpened()).WillRepeatedly(Return(true));
488 item_observer()->OnDownloadUpdated(&item(0));
489 info.opened = true;
490 ExpectDownloadUpdated(info);
492 // Pretend that the user removed the item.
493 IdSet ids;
494 ids.insert(info.id);
495 item_observer()->OnDownloadRemoved(&item(0));
496 ExpectDownloadsRemoved(ids);
499 // Test creating an item, saving it to the database, changing it, saving it
500 // back, removing it.
501 TEST_F(DownloadHistoryTest, DownloadHistoryTest_Create) {
502 // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
503 // OnDownloadRemoved.
504 ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
506 history::DownloadRow info;
507 InitBasicItem(FILE_PATH_LITERAL("/foo/bar.pdf"),
508 "http://example.com/bar.pdf",
509 "http://example.com/referrer.html",
510 &info);
512 // Pretend the manager just created |item|.
513 CallOnDownloadCreated(0);
514 ExpectDownloadCreated(info);
515 EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
517 // Pretend that something changed on the item.
518 EXPECT_CALL(item(0), GetOpened()).WillRepeatedly(Return(true));
519 item_observer()->OnDownloadUpdated(&item(0));
520 info.opened = true;
521 ExpectDownloadUpdated(info);
523 // Pretend that the user removed the item.
524 IdSet ids;
525 ids.insert(info.id);
526 item_observer()->OnDownloadRemoved(&item(0));
527 ExpectDownloadsRemoved(ids);
530 // Test that changes to persisted fields in a DownloadItem triggers database
531 // updates.
532 TEST_F(DownloadHistoryTest, DownloadHistoryTest_Update) {
533 ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
535 history::DownloadRow info;
536 InitBasicItem(FILE_PATH_LITERAL("/foo/bar.pdf"),
537 "http://example.com/bar.pdf",
538 "http://example.com/referrer.html",
539 &info);
540 CallOnDownloadCreated(0);
541 ExpectDownloadCreated(info);
542 EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
544 base::FilePath new_path(FILE_PATH_LITERAL("/foo/baz.txt"));
545 base::Time new_time(base::Time::Now());
546 std::string new_etag("new etag");
547 std::string new_last_modifed("new last modified");
549 // current_path
550 EXPECT_CALL(item(0), GetFullPath()).WillRepeatedly(ReturnRefOfCopy(new_path));
551 info.current_path = new_path;
552 item_observer()->OnDownloadUpdated(&item(0));
553 ExpectDownloadUpdated(info);
555 // target_path
556 EXPECT_CALL(item(0), GetTargetFilePath())
557 .WillRepeatedly(ReturnRefOfCopy(new_path));
558 info.target_path = new_path;
559 item_observer()->OnDownloadUpdated(&item(0));
560 ExpectDownloadUpdated(info);
562 // end_time
563 EXPECT_CALL(item(0), GetEndTime()).WillRepeatedly(Return(new_time));
564 info.end_time = new_time;
565 item_observer()->OnDownloadUpdated(&item(0));
566 ExpectDownloadUpdated(info);
568 // received_bytes
569 EXPECT_CALL(item(0), GetReceivedBytes()).WillRepeatedly(Return(101));
570 info.received_bytes = 101;
571 item_observer()->OnDownloadUpdated(&item(0));
572 ExpectDownloadUpdated(info);
574 // total_bytes
575 EXPECT_CALL(item(0), GetTotalBytes()).WillRepeatedly(Return(102));
576 info.total_bytes = 102;
577 item_observer()->OnDownloadUpdated(&item(0));
578 ExpectDownloadUpdated(info);
580 // etag
581 EXPECT_CALL(item(0), GetETag()).WillRepeatedly(ReturnRefOfCopy(new_etag));
582 info.etag = new_etag;
583 item_observer()->OnDownloadUpdated(&item(0));
584 ExpectDownloadUpdated(info);
586 // last_modified
587 EXPECT_CALL(item(0), GetLastModifiedTime())
588 .WillRepeatedly(ReturnRefOfCopy(new_last_modifed));
589 info.last_modified = new_last_modifed;
590 item_observer()->OnDownloadUpdated(&item(0));
591 ExpectDownloadUpdated(info);
593 // state
594 EXPECT_CALL(item(0), GetState())
595 .WillRepeatedly(Return(content::DownloadItem::INTERRUPTED));
596 info.state = content::DownloadItem::INTERRUPTED;
597 item_observer()->OnDownloadUpdated(&item(0));
598 ExpectDownloadUpdated(info);
600 // danger_type
601 EXPECT_CALL(item(0), GetDangerType())
602 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT));
603 info.danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT;
604 item_observer()->OnDownloadUpdated(&item(0));
605 ExpectDownloadUpdated(info);
607 // interrupt_reason
608 EXPECT_CALL(item(0), GetLastReason())
609 .WillRepeatedly(Return(content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED));
610 info.interrupt_reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED;
611 item_observer()->OnDownloadUpdated(&item(0));
612 ExpectDownloadUpdated(info);
614 // opened
615 EXPECT_CALL(item(0), GetOpened()).WillRepeatedly(Return(true));
616 info.opened = true;
617 item_observer()->OnDownloadUpdated(&item(0));
618 ExpectDownloadUpdated(info);
621 // Test creating a new item, saving it, removing it by setting it Temporary,
622 // changing it without saving it back because it's Temporary, clearing
623 // IsTemporary, saving it back, changing it, saving it back because it isn't
624 // Temporary anymore.
625 TEST_F(DownloadHistoryTest, DownloadHistoryTest_Temporary) {
626 // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
627 // OnDownloadRemoved.
628 ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
630 history::DownloadRow info;
631 InitBasicItem(FILE_PATH_LITERAL("/foo/bar.pdf"),
632 "http://example.com/bar.pdf",
633 "http://example.com/referrer.html",
634 &info);
636 // Pretend the manager just created |item|.
637 CallOnDownloadCreated(0);
638 ExpectDownloadCreated(info);
639 EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
641 // Pretend the item was marked temporary. DownloadHistory should remove it
642 // from history and start ignoring it.
643 EXPECT_CALL(item(0), IsTemporary()).WillRepeatedly(Return(true));
644 item_observer()->OnDownloadUpdated(&item(0));
645 IdSet ids;
646 ids.insert(info.id);
647 ExpectDownloadsRemoved(ids);
649 // Change something that would make DownloadHistory call UpdateDownload if the
650 // item weren't temporary.
651 EXPECT_CALL(item(0), GetReceivedBytes()).WillRepeatedly(Return(4200));
652 item_observer()->OnDownloadUpdated(&item(0));
653 ExpectNoDownloadUpdated();
655 // Changing a temporary item back to a non-temporary item should make
656 // DownloadHistory call CreateDownload.
657 EXPECT_CALL(item(0), IsTemporary()).WillRepeatedly(Return(false));
658 item_observer()->OnDownloadUpdated(&item(0));
659 info.received_bytes = 4200;
660 ExpectDownloadCreated(info);
661 EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
663 EXPECT_CALL(item(0), GetReceivedBytes()).WillRepeatedly(Return(100));
664 item_observer()->OnDownloadUpdated(&item(0));
665 info.received_bytes = 100;
666 ExpectDownloadUpdated(info);
669 // Test removing downloads while they're still being added.
670 TEST_F(DownloadHistoryTest, DownloadHistoryTest_RemoveWhileAdding) {
671 ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
673 history::DownloadRow info;
674 InitBasicItem(FILE_PATH_LITERAL("/foo/bar.pdf"),
675 "http://example.com/bar.pdf",
676 "http://example.com/referrer.html",
677 &info);
679 // Instruct CreateDownload() to not callback to DownloadHistory immediately,
680 // but to wait for FinishCreateDownload().
681 set_slow_create_download(true);
683 // Pretend the manager just created |item|.
684 CallOnDownloadCreated(0);
685 ExpectDownloadCreated(info);
686 EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
688 // Call OnDownloadRemoved before calling back to DownloadHistory::ItemAdded().
689 // Instead of calling RemoveDownloads() immediately, DownloadHistory should
690 // add the item's id to removed_while_adding_. Then, ItemAdded should
691 // immediately remove the item's record from history.
692 item_observer()->OnDownloadRemoved(&item(0));
693 EXPECT_CALL(manager(), GetDownload(item(0).GetId()))
694 .WillRepeatedly(Return(static_cast<content::DownloadItem*>(NULL)));
695 ExpectNoDownloadsRemoved();
696 EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
698 // Now callback to DownloadHistory::ItemAdded(), and expect a call to
699 // RemoveDownloads() for the item that was removed while it was being added.
700 FinishCreateDownload();
701 IdSet ids;
702 ids.insert(info.id);
703 ExpectDownloadsRemoved(ids);
704 EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
707 // Test loading multiple items from the database and removing them all.
708 TEST_F(DownloadHistoryTest, DownloadHistoryTest_Multiple) {
709 // Load a download from history, create the item, OnDownloadCreated,
710 // OnDownloadUpdated, OnDownloadRemoved.
711 history::DownloadRow info0, info1;
712 InitBasicItem(FILE_PATH_LITERAL("/foo/bar.pdf"),
713 "http://example.com/bar.pdf",
714 "http://example.com/referrer.html",
715 &info0);
716 InitBasicItem(FILE_PATH_LITERAL("/foo/qux.pdf"),
717 "http://example.com/qux.pdf",
718 "http://example.com/referrer1.html",
719 &info1);
721 scoped_ptr<InfoVector> infos(new InfoVector());
722 infos->push_back(info0);
723 infos->push_back(info1);
724 ExpectWillQueryDownloads(infos.Pass());
725 ExpectNoDownloadCreated();
728 EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
729 EXPECT_TRUE(DownloadHistory::IsPersisted(&item(1)));
731 // Pretend that the user removed both items.
732 IdSet ids;
733 ids.insert(info0.id);
734 ids.insert(info1.id);
735 item_observer()->OnDownloadRemoved(&item(0));
736 item_observer()->OnDownloadRemoved(&item(1));
737 ExpectDownloadsRemoved(ids);
740 // Test what happens when HistoryService/CreateDownload::CreateDownload() fails.
741 TEST_F(DownloadHistoryTest, DownloadHistoryTest_CreateFailed) {
742 // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
743 // OnDownloadRemoved.
744 ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
746 history::DownloadRow info;
747 InitBasicItem(FILE_PATH_LITERAL("/foo/bar.pdf"),
748 "http://example.com/bar.pdf",
749 "http://example.com/referrer.html",
750 &info);
752 FailCreateDownload();
753 // Pretend the manager just created |item|.
754 CallOnDownloadCreated(0);
755 ExpectDownloadCreated(info);
756 EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
758 EXPECT_CALL(item(0), GetReceivedBytes()).WillRepeatedly(Return(100));
759 item_observer()->OnDownloadUpdated(&item(0));
760 info.received_bytes = 100;
761 ExpectDownloadCreated(info);
762 EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
765 TEST_F(DownloadHistoryTest, DownloadHistoryTest_UpdateWhileAdding) {
766 // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
767 // OnDownloadRemoved.
768 ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
770 history::DownloadRow info;
771 InitBasicItem(FILE_PATH_LITERAL("/foo/bar.pdf"),
772 "http://example.com/bar.pdf",
773 "http://example.com/referrer.html",
774 &info);
776 // Instruct CreateDownload() to not callback to DownloadHistory immediately,
777 // but to wait for FinishCreateDownload().
778 set_slow_create_download(true);
780 // Pretend the manager just created |item|.
781 CallOnDownloadCreated(0);
782 ExpectDownloadCreated(info);
783 EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
785 // Pretend that something changed on the item.
786 EXPECT_CALL(item(0), GetOpened()).WillRepeatedly(Return(true));
787 item_observer()->OnDownloadUpdated(&item(0));
789 FinishCreateDownload();
790 EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
792 // ItemAdded should call OnDownloadUpdated, which should detect that the item
793 // changed while it was being added and call UpdateDownload immediately.
794 info.opened = true;
795 ExpectDownloadUpdated(info);