Chromium Code Reviews| Index: chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc |
| diff --git a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e9ae9a9e89f9b0e2cdd477a7077154c2acefcae9 |
| --- /dev/null |
| +++ b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc |
| @@ -0,0 +1,277 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/ui/webui/md_downloads/downloads_list_tracker.h" |
| + |
| +#include <vector> |
| + |
| +#include "base/files/file_path.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/stl_util.h" |
| +#include "base/time/time.h" |
| +#include "chrome/browser/download/download_item_model.h" |
| +#include "chrome/test/base/testing_profile.h" |
| +#include "content/public/test/mock_download_item.h" |
| +#include "content/public/test/mock_download_manager.h" |
| +#include "content/public/test/test_browser_thread.h" |
| +#include "content/public/test/test_web_ui.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +using content::DownloadItem; |
| +using content::MockDownloadItem; |
| +using DownloadVector = std::vector<DownloadItem*>; |
| +using testing::_; |
| +using testing::Return; |
| + |
| +namespace { |
| + |
| +uint64 GetId(const base::Value* value) { |
| + const base::DictionaryValue* dict; |
| + CHECK(value->GetAsDictionary(&dict)); |
| + |
| + int id; |
| + CHECK(dict->GetInteger("id", &id)); |
| + CHECK_GE(id, 0); |
| + return static_cast<uint64>(id); |
| +} |
| + |
| +std::vector<uint64> GetIds(const base::Value* value) { |
| + CHECK(value); |
| + |
| + std::vector<uint64> ids; |
| + |
| + if (value->GetType() == base::Value::TYPE_LIST) { |
| + const base::ListValue* list; |
| + value->GetAsList(&list); |
| + |
| + for (auto* list_item : *list) { |
|
asanka
2015/11/24 22:08:22
Nit: No braces
Dan Beam
2015/11/25 04:06:36
"In general, curly braces are not required for sin
asanka
2015/11/25 20:49:06
Hehe.
|
| + ids.push_back(GetId(list_item)); |
| + } |
| + } else { |
| + ids.push_back(GetId(value)); |
| + } |
| + |
| + return ids; |
| +} |
| + |
| +int GetIndex(const base::Value* value) { |
| + CHECK(value); |
| + int index; |
| + CHECK(value->GetAsInteger(&index)); |
| + return index; |
| +} |
| + |
| +bool ShouldShowItem(const DownloadItem& item) { |
| + DownloadItemModel model(const_cast<DownloadItem*>(&item)); |
| + return model.ShouldShowInShelf(); |
| +} |
| + |
| +} // namespace |
| + |
| +// A test version of DownloadsListTracker. |
| +class TestDownloadsListTracker : public DownloadsListTracker { |
| + public: |
| + TestDownloadsListTracker(content::DownloadManager* manager, |
| + content::WebUI* web_ui) |
| + : DownloadsListTracker(manager, web_ui, base::Bind(&ShouldShowItem)) {} |
| + ~TestDownloadsListTracker() override {} |
| + |
| + using DownloadsListTracker::GetItemForTesting; |
| + |
| + protected: |
| + scoped_ptr<base::DictionaryValue> CreateDownloadItemValue( |
| + content::DownloadItem* item) const override { |
|
asanka
2015/11/24 22:08:22
Take a const DownloadItem& or const DownloadItem*
Dan Beam
2015/11/25 04:06:36
this is overriding the method in DownloadsListTrac
|
| + scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); |
| + CHECK_LE(item->GetId(), static_cast<uint64>(INT_MAX)); |
| + dict->SetInteger("id", item->GetId()); |
| + return dict.Pass(); |
| + } |
| +}; |
| + |
| +// A fixture to test DownloadsListTracker. |
| +class DownloadsListTrackerTest : public testing::Test { |
| + public: |
| + DownloadsListTrackerTest() |
| + : ui_thread_(content::BrowserThread::UI, &message_loop_) {} |
| + ~DownloadsListTrackerTest() override { |
| + for (auto* mock_item : mock_items_) |
| + testing::Mock::VerifyAndClear(mock_item); |
|
asanka
2015/11/24 22:08:22
Expectations are verified when the mock items are
Dan Beam
2015/11/25 04:06:36
when a base::Time() is created via mock_item->GetS
|
| + STLDeleteElements(&mock_items_); |
| + } |
| + |
| + // testing::Test: |
| + void SetUp() override { |
| + ON_CALL(manager_, GetBrowserContext()).WillByDefault(Return(&profile_)); |
| + ON_CALL(manager_, GetAllDownloads(_)).WillByDefault( |
| + testing::Invoke(this, &DownloadsListTrackerTest::GetAllDownloads)); |
| + } |
| + |
| + MockDownloadItem* CreateMock(uint64 id, double started) { |
| + MockDownloadItem* new_item = new testing::NiceMock<MockDownloadItem>(); |
| + mock_items_.push_back(new_item); |
| + |
| + ON_CALL(*new_item, GetId()).WillByDefault(Return(id)); |
| + ON_CALL(*new_item, GetStartTime()).WillByDefault( |
| + Return(base::Time::FromDoubleT(started))); |
| + |
| + return new_item; |
| + } |
| + |
| + MockDownloadItem* CreateNextItem() { |
| + return CreateMock(mock_items_.size(), mock_items_.size()); |
|
asanka
2015/11/24 22:08:22
Nit: GetStartTime() is Time::FromDoubleT(static_ca
Dan Beam
2015/11/25 04:06:36
Done.
asanka
2015/11/25 20:49:06
Better, but something like :
CreateMock(mock_it
Dan Beam
2015/11/26 01:40:08
Done.
|
| + } |
| + |
| + void CreateTracker() { |
| + tracker_.reset(new TestDownloadsListTracker(manager(), web_ui())); |
| + } |
| + |
| + content::DownloadManager* manager() { return &manager_; } |
| + content::TestWebUI* web_ui() { return &web_ui_; } |
| + TestDownloadsListTracker* tracker() { return tracker_.get(); } |
| + |
| + private: |
| + void GetAllDownloads(DownloadVector* result) { |
| + for (auto* mock_item : mock_items_) |
| + result->push_back(mock_item); |
| + } |
| + |
| + // NOTE: The initialization order of these members matters. |
| + base::MessageLoopForUI message_loop_; |
| + content::TestBrowserThread ui_thread_; |
| + TestingProfile profile_; |
| + |
| + testing::NiceMock<content::MockDownloadManager> manager_; |
| + content::TestWebUI web_ui_; |
| + scoped_ptr<TestDownloadsListTracker> tracker_; |
| + |
| + std::vector<MockDownloadItem*> mock_items_; |
| +}; |
| + |
| +TEST_F(DownloadsListTrackerTest, SetSearchTerms) { |
| + CreateTracker(); |
| + |
| + const base::ListValue empty_terms; |
| + EXPECT_FALSE(tracker()->SetSearchTerms(empty_terms)); |
| + |
| + base::ListValue search_terms; |
| + search_terms.AppendString("search"); |
| + EXPECT_TRUE(tracker()->SetSearchTerms(search_terms)); |
| + |
| + EXPECT_FALSE(tracker()->SetSearchTerms(search_terms)); |
| + |
| + EXPECT_TRUE(tracker()->SetSearchTerms(empty_terms)); |
| + |
| + // Notifying the page is left up to the handler in this case. |
| + EXPECT_TRUE(web_ui()->call_data().empty()); |
| +} |
| + |
| +TEST_F(DownloadsListTrackerTest, StartCallsInsertItems) { |
| + DownloadItem* first_item = CreateNextItem(); |
| + |
| + CreateTracker(); |
| + ASSERT_TRUE(tracker()->GetItemForTesting(0)); |
| + EXPECT_TRUE(web_ui()->call_data().empty()); |
| + |
| + tracker()->Start(); |
| + ASSERT_FALSE(web_ui()->call_data().empty()); |
| + |
| + EXPECT_EQ("downloads.Manager.insertItems", |
| + web_ui()->call_data()[0]->function_name()); |
| + EXPECT_EQ(0, GetIndex(web_ui()->call_data()[0]->arg1())); |
| + |
| + std::vector<uint64> ids = GetIds(web_ui()->call_data()[0]->arg2()); |
| + ASSERT_FALSE(ids.empty()); |
| + EXPECT_EQ(first_item->GetId(), ids[0]); |
| +} |
| + |
| +// The page is in a loading state until it gets an insertItems call. Ensure that |
| +// happens even without downloads. |
| +TEST_F(DownloadsListTrackerTest, EmptyGetAllItemsStillCallsInsertItems) { |
| + CreateTracker(); |
| + |
| + ASSERT_FALSE(tracker()->GetItemForTesting(0)); |
| + ASSERT_TRUE(web_ui()->call_data().empty()); |
| + |
| + tracker()->Start(); |
| + |
| + ASSERT_FALSE(web_ui()->call_data().empty()); |
| + EXPECT_EQ("downloads.Manager.insertItems", |
| + web_ui()->call_data()[0]->function_name()); |
| + ASSERT_TRUE(web_ui()->call_data()[0]->arg2()); |
| + EXPECT_TRUE(GetIds(web_ui()->call_data()[0]->arg2()).empty()); |
| +} |
| + |
| +TEST_F(DownloadsListTrackerTest, OnDownloadCreatedCallsInsertItems) { |
| + CreateTracker(); |
| + tracker()->Start(); |
| + web_ui()->ClearTrackedCalls(); |
| + |
| + ASSERT_FALSE(tracker()->GetItemForTesting(0)); |
| + DownloadItem* first_item = CreateNextItem(); |
| + tracker()->OnDownloadCreated(manager(), first_item); |
| + |
| + ASSERT_FALSE(web_ui()->call_data().empty()); |
| + EXPECT_EQ("downloads.Manager.insertItems", |
| + web_ui()->call_data()[0]->function_name()); |
| + EXPECT_EQ(0, GetIndex(web_ui()->call_data()[0]->arg1())); |
| + |
| + std::vector<uint64> ids = GetIds(web_ui()->call_data()[0]->arg2()); |
| + ASSERT_FALSE(ids.empty()); |
| + EXPECT_EQ(first_item->GetId(), ids[0]); |
| +} |
| + |
| +TEST_F(DownloadsListTrackerTest, OnDownloadRemovedCallsRemoveItem) { |
| + DownloadItem* first_item = CreateNextItem(); |
| + |
| + CreateTracker(); |
| + tracker()->Start(); |
| + web_ui()->ClearTrackedCalls(); |
| + |
| + EXPECT_TRUE(tracker()->GetItemForTesting(0)); |
| + tracker()->OnDownloadRemoved(manager(), first_item); |
| + EXPECT_FALSE(tracker()->GetItemForTesting(0)); |
| + |
| + ASSERT_FALSE(web_ui()->call_data().empty()); |
| + |
| + EXPECT_EQ("downloads.Manager.removeItem", |
| + web_ui()->call_data()[0]->function_name()); |
| + EXPECT_EQ(0, GetIndex(web_ui()->call_data()[0]->arg1())); |
| +} |
| + |
| +TEST_F(DownloadsListTrackerTest, OnDownloadUpdatedCallsRemoveItem) { |
| + DownloadItem* first_item = CreateNextItem(); |
| + |
| + CreateTracker(); |
| + tracker()->Start(); |
| + web_ui()->ClearTrackedCalls(); |
| + |
| + EXPECT_TRUE(tracker()->GetItemForTesting(0)); |
| + |
| + DownloadItemModel(first_item).SetShouldShowInShelf(false); |
| + tracker()->OnDownloadUpdated(manager(), first_item); |
| + |
| + EXPECT_FALSE(tracker()->GetItemForTesting(0)); |
| + |
| + ASSERT_FALSE(web_ui()->call_data().empty()); |
| + |
| + EXPECT_EQ("downloads.Manager.removeItem", |
| + web_ui()->call_data()[0]->function_name()); |
| + EXPECT_EQ(0, GetIndex(web_ui()->call_data()[0]->arg1())); |
| +} |
| + |
| +TEST_F(DownloadsListTrackerTest, StartExcludesHiddenItems) { |
| + DownloadItem* first_item = CreateNextItem(); |
| + DownloadItemModel(first_item).SetShouldShowInShelf(false); |
| + |
| + CreateTracker(); |
| + tracker()->Start(); |
| + |
| + ASSERT_FALSE(web_ui()->call_data().empty()); |
| + |
| + EXPECT_EQ("downloads.Manager.insertItems", |
| + web_ui()->call_data()[0]->function_name()); |
| + EXPECT_TRUE(GetIds(web_ui()->call_data()[0]->arg2()).empty()); |
| +} |
|
asanka
2015/11/24 22:08:22
Tests for incognito?
Dan Beam
2015/11/25 04:06:36
will get to these soon
Dan Beam
2015/11/28 20:59:23
... in a follow-up CL. there's a pretty decent ch
|