This source file includes following definitions.
- SetupDownloadItemDefaults
- SetupInterruptedDownloadItem
- item
- model
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "chrome/browser/download/download_item_model.h"
#include <vector>
#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/test/mock_download_item.h"
#include "extensions/common/extension.h"
#include "grit/generated_resources.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/text/bytes_formatting.h"
#include "ui/gfx/font_list.h"
#include "ui/gfx/text_utils.h"
using content::DownloadItem;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnRefOfCopy;
using ::testing::SetArgPointee;
using ::testing::_;
namespace {
char kInterruptReasonCounter[] = {
0,
#define INTERRUPT_REASON(name,value) 0,
#include "content/public/browser/download_interrupt_reason_values.h"
#undef INTERRUPT_REASON
};
const size_t kInterruptReasonCount = ARRAYSIZE_UNSAFE(kInterruptReasonCounter);
const base::FilePath::CharType kDefaultTargetFilePath[] =
FILE_PATH_LITERAL("/foo/bar/foo.bar");
const base::FilePath::CharType kDefaultDisplayFileName[] =
FILE_PATH_LITERAL("foo.bar");
const char kDefaultURL[] = "http://example.com/foo.bar";
class DownloadItemModelTest : public testing::Test {
public:
DownloadItemModelTest()
: model_(&item_) {}
virtual ~DownloadItemModelTest() {
}
protected:
void SetupDownloadItemDefaults() {
ON_CALL(item_, GetReceivedBytes()).WillByDefault(Return(1));
ON_CALL(item_, GetTotalBytes()).WillByDefault(Return(2));
ON_CALL(item_, TimeRemaining(_)).WillByDefault(Return(false));
ON_CALL(item_, GetMimeType()).WillByDefault(Return("text/html"));
ON_CALL(item_, AllDataSaved()).WillByDefault(Return(false));
ON_CALL(item_, GetOpenWhenComplete()).WillByDefault(Return(false));
ON_CALL(item_, GetFileExternallyRemoved()).WillByDefault(Return(false));
ON_CALL(item_, GetState())
.WillByDefault(Return(DownloadItem::IN_PROGRESS));
ON_CALL(item_, GetURL())
.WillByDefault(ReturnRefOfCopy(GURL(kDefaultURL)));
ON_CALL(item_, GetFileNameToReportUser())
.WillByDefault(Return(base::FilePath(kDefaultDisplayFileName)));
ON_CALL(item_, GetTargetFilePath())
.WillByDefault(ReturnRefOfCopy(base::FilePath(kDefaultTargetFilePath)));
ON_CALL(item_, GetTargetDisposition())
.WillByDefault(
Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE));
ON_CALL(item_, IsPaused()).WillByDefault(Return(false));
}
void SetupInterruptedDownloadItem(content::DownloadInterruptReason reason) {
EXPECT_CALL(item_, GetLastReason()).WillRepeatedly(Return(reason));
EXPECT_CALL(item_, GetState())
.WillRepeatedly(Return(
(reason == content::DOWNLOAD_INTERRUPT_REASON_NONE) ?
DownloadItem::IN_PROGRESS :
DownloadItem::INTERRUPTED));
}
content::MockDownloadItem& item() {
return item_;
}
DownloadItemModel& model() {
return model_;
}
private:
NiceMock<content::MockDownloadItem> item_;
DownloadItemModel model_;
};
}
TEST_F(DownloadItemModelTest, InterruptedStatus) {
const struct TestCase {
content::DownloadInterruptReason reason;
const char* expected_status;
} kTestCases[] = {
{ content::DOWNLOAD_INTERRUPT_REASON_NONE,
"1/2 B" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
"Failed - Download error" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
"Failed - Insufficient permissions" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
"Failed - Disk full" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG,
"Failed - Path too long" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE,
"Failed - File too large" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_VIRUS_INFECTED,
"Failed - Virus detected" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED,
"Failed - Blocked" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED,
"Failed - Virus scan failed" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT,
"Failed - File truncated" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR,
"Failed - System busy" },
{ content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED,
"Failed - Network error" },
{ content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT,
"Failed - Network timeout" },
{ content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
"Failed - Network disconnected" },
{ content::DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN,
"Failed - Server unavailable" },
{ content::DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST,
"Failed - Network error" },
{ content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED,
"Failed - Server problem" },
{ content::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE,
"Failed - Download error" },
{ content::DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION,
"Failed - Download error" },
{ content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
"Failed - No file" },
{ content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED,
"Cancelled" },
{ content::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN,
"Failed - Shutdown" },
{ content::DOWNLOAD_INTERRUPT_REASON_CRASH,
"Failed - Crash" },
};
COMPILE_ASSERT(kInterruptReasonCount == ARRAYSIZE_UNSAFE(kTestCases),
interrupt_reason_mismatch);
SetupDownloadItemDefaults();
for (unsigned i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
const TestCase& test_case = kTestCases[i];
SetupInterruptedDownloadItem(test_case.reason);
EXPECT_STREQ(test_case.expected_status,
base::UTF16ToUTF8(model().GetStatusText()).c_str());
}
}
TEST_F(DownloadItemModelTest, InterruptTooltip) {
const struct TestCase {
content::DownloadInterruptReason reason;
const char* expected_tooltip;
} kTestCases[] = {
{ content::DOWNLOAD_INTERRUPT_REASON_NONE,
"foo.bar" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
"foo.bar\nDownload error" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
"foo.bar\nInsufficient permissions" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
"foo.bar\nDisk full" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG,
"foo.bar\nPath too long" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE,
"foo.bar\nFile too large" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_VIRUS_INFECTED,
"foo.bar\nVirus detected" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED,
"foo.bar\nBlocked" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED,
"foo.bar\nVirus scan failed" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT,
"foo.bar\nFile truncated" },
{ content::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR,
"foo.bar\nSystem busy" },
{ content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED,
"foo.bar\nNetwork error" },
{ content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT,
"foo.bar\nNetwork timeout" },
{ content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
"foo.bar\nNetwork disconnected" },
{ content::DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN,
"foo.bar\nServer unavailable" },
{ content::DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST,
"foo.bar\nNetwork error" },
{ content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED,
"foo.bar\nServer problem" },
{ content::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE,
"foo.bar\nDownload error" },
{ content::DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION,
"foo.bar\nDownload error" },
{ content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
"foo.bar\nNo file" },
{ content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED,
"foo.bar" },
{ content::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN,
"foo.bar\nShutdown" },
{ content::DOWNLOAD_INTERRUPT_REASON_CRASH,
"foo.bar\nCrash" },
};
COMPILE_ASSERT(kInterruptReasonCount == ARRAYSIZE_UNSAFE(kTestCases),
interrupt_reason_mismatch);
const int kLargeTooltipWidth = 1000;
const int kSmallTooltipWidth = 40;
const gfx::FontList& font_list =
ui::ResourceBundle::GetSharedInstance().GetFontList(
ui::ResourceBundle::BaseFont);
SetupDownloadItemDefaults();
for (unsigned i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
const TestCase& test_case = kTestCases[i];
SetupInterruptedDownloadItem(test_case.reason);
EXPECT_STREQ(
test_case.expected_tooltip,
base::UTF16ToUTF8(model().GetTooltipText(font_list,
kLargeTooltipWidth)).c_str());
std::vector<base::string16> lines;
base::string16 truncated_tooltip =
model().GetTooltipText(font_list, kSmallTooltipWidth);
Tokenize(truncated_tooltip, base::ASCIIToUTF16("\n"), &lines);
for (unsigned i = 0; i < lines.size(); ++i)
EXPECT_GE(kSmallTooltipWidth, gfx::GetStringWidth(lines[i], font_list));
}
}
TEST_F(DownloadItemModelTest, InProgressStatus) {
const struct TestCase {
int64 received_bytes;
int64 total_bytes;
bool time_remaining_known;
bool open_when_complete;
bool is_paused;
const char* expected_status;
} kTestCases[] = {
{ 0, 0, false, false, false, "Starting..." },
{ 1, 0, false, false, false, "1 B" },
{ 0, 2, false, false, false, "Starting..." },
{ 1, 2, false, false, false, "1/2 B" },
{ 0, 2, true, false, false, "0/2 B, 10 secs left" },
{ 1, 2, true, false, false, "1/2 B, 10 secs left" },
{ 0, 0, false, true, false, "Opening when complete" },
{ 1, 0, false, true, false, "Opening when complete" },
{ 0, 2, false, true, false, "Opening when complete" },
{ 1, 2, false, true, false, "Opening when complete" },
{ 0, 2, true, true, false, "Opening in 10 secs..." },
{ 1, 2, true, true, false, "Opening in 10 secs..." },
{ 0, 0, false, false, true, "0 B, Paused" },
{ 1, 0, false, false, true, "1 B, Paused" },
{ 0, 2, false, false, true, "0/2 B, Paused" },
{ 1, 2, false, false, true, "1/2 B, Paused" },
{ 0, 2, true, false, true, "0/2 B, Paused" },
{ 1, 2, true, false, true, "1/2 B, Paused" },
{ 0, 0, false, true, true, "0 B, Paused" },
{ 1, 0, false, true, true, "1 B, Paused" },
{ 0, 2, false, true, true, "0/2 B, Paused" },
{ 1, 2, false, true, true, "1/2 B, Paused" },
{ 0, 2, true, true, true, "0/2 B, Paused" },
{ 1, 2, true, true, true, "1/2 B, Paused" },
};
SetupDownloadItemDefaults();
for (unsigned i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); i++) {
const TestCase& test_case = kTestCases[i];
Mock::VerifyAndClearExpectations(&item());
Mock::VerifyAndClearExpectations(&model());
EXPECT_CALL(item(), GetReceivedBytes())
.WillRepeatedly(Return(test_case.received_bytes));
EXPECT_CALL(item(), GetTotalBytes())
.WillRepeatedly(Return(test_case.total_bytes));
EXPECT_CALL(item(), TimeRemaining(_))
.WillRepeatedly(testing::DoAll(
testing::SetArgPointee<0>(base::TimeDelta::FromSeconds(10)),
Return(test_case.time_remaining_known)));
EXPECT_CALL(item(), GetOpenWhenComplete())
.WillRepeatedly(Return(test_case.open_when_complete));
EXPECT_CALL(item(), IsPaused())
.WillRepeatedly(Return(test_case.is_paused));
EXPECT_STREQ(test_case.expected_status,
base::UTF16ToUTF8(model().GetStatusText()).c_str());
}
}
TEST_F(DownloadItemModelTest, ShouldShowInShelf) {
SetupDownloadItemDefaults();
EXPECT_TRUE(model().ShouldShowInShelf());
model().SetShouldShowInShelf(false);
EXPECT_FALSE(model().ShouldShowInShelf());
model().SetShouldShowInShelf(true);
EXPECT_TRUE(model().ShouldShowInShelf());
}
TEST_F(DownloadItemModelTest, ShouldRemoveFromShelfWhenComplete) {
const struct TestCase {
DownloadItem::DownloadState state;
bool is_dangerous;
bool is_auto_open;
bool auto_opened;
bool expected_result;
} kTestCases[] = {
{ DownloadItem::IN_PROGRESS, false, false, false, false},
{ DownloadItem::IN_PROGRESS, false, true , false, true },
{ DownloadItem::IN_PROGRESS, true , false, false, false},
{ DownloadItem::IN_PROGRESS, true , true , false, false},
{ DownloadItem::COMPLETE, false, false, false, false},
{ DownloadItem::COMPLETE, false, true , false, false},
{ DownloadItem::COMPLETE, false, false, true , true },
{ DownloadItem::COMPLETE, false, true , true , true },
{ DownloadItem::CANCELLED, false, false, false, false},
{ DownloadItem::CANCELLED, false, true , false, false},
{ DownloadItem::CANCELLED, true , false, false, false},
{ DownloadItem::CANCELLED, true , true , false, false},
{ DownloadItem::INTERRUPTED, false, false, false, false},
{ DownloadItem::INTERRUPTED, false, true , false, false},
{ DownloadItem::INTERRUPTED, true , false, false, false},
{ DownloadItem::INTERRUPTED, true , true , false, false}
};
SetupDownloadItemDefaults();
for (unsigned i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); i++) {
const TestCase& test_case = kTestCases[i];
EXPECT_CALL(item(), GetOpenWhenComplete())
.WillRepeatedly(Return(test_case.is_auto_open));
EXPECT_CALL(item(), GetState())
.WillRepeatedly(Return(test_case.state));
EXPECT_CALL(item(), IsDangerous())
.WillRepeatedly(Return(test_case.is_dangerous));
EXPECT_CALL(item(), GetAutoOpened())
.WillRepeatedly(Return(test_case.auto_opened));
EXPECT_EQ(test_case.expected_result,
model().ShouldRemoveFromShelfWhenComplete())
<< "Test case: " << i;
Mock::VerifyAndClearExpectations(&item());
Mock::VerifyAndClearExpectations(&model());
}
}