Home | History | Annotate | Download | only in download
      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.
      4 
      5 #include <string>
      6 
      7 #include "base/bind.h"
      8 #include "base/files/file_path.h"
      9 #include "base/logging.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/stl_util.h"
     12 #include "base/strings/string16.h"
     13 #include "base/time/time.h"
     14 #include "base/values.h"
     15 #include "chrome/browser/download/download_query.h"
     16 #include "content/public/test/mock_download_item.h"
     17 #include "testing/gmock/include/gmock/gmock.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 using ::testing::Return;
     21 using ::testing::ReturnRef;
     22 using ::testing::_;
     23 using base::Time;
     24 using base::Value;
     25 using content::DownloadItem;
     26 typedef DownloadQuery::DownloadVector DownloadVector;
     27 
     28 namespace {
     29 
     30 static const int kSomeKnownTime = 1355864160;
     31 static const char kSomeKnownTime8601[] = "2012-12-18T20:56:0";
     32 static const char k8601Suffix[] = ".000Z";
     33 
     34 bool IdNotEqual(uint32 not_id, const DownloadItem& item) {
     35   return item.GetId() != not_id;
     36 }
     37 
     38 bool AlwaysReturn(bool result, const DownloadItem& item) {
     39   return result;
     40 }
     41 
     42 }  // anonymous namespace
     43 
     44 class DownloadQueryTest : public testing::Test {
     45  public:
     46   DownloadQueryTest() {}
     47 
     48   virtual ~DownloadQueryTest() {}
     49 
     50   virtual void TearDown() {
     51     STLDeleteElements(&mocks_);
     52   }
     53 
     54   void CreateMocks(int count) {
     55     for (int i = 0; i < count; ++i) {
     56       mocks_.push_back(new content::MockDownloadItem());
     57       EXPECT_CALL(mock(mocks_.size() - 1), GetId()).WillRepeatedly(Return(
     58           mocks_.size() - 1));
     59     }
     60   }
     61 
     62   content::MockDownloadItem& mock(int index) { return *mocks_[index]; }
     63 
     64   DownloadQuery* query() { return &query_; }
     65 
     66   template<typename ValueType> void AddFilter(
     67       DownloadQuery::FilterType name, ValueType value);
     68 
     69   void Search() {
     70     query_.Search(mocks_.begin(), mocks_.end(), &results_);
     71   }
     72 
     73   DownloadVector* results() { return &results_; }
     74 
     75   // Filter tests generally contain 2 items. mock(0) matches the filter, mock(1)
     76   // does not.
     77   void ExpectStandardFilterResults() {
     78     Search();
     79     ASSERT_EQ(1U, results()->size());
     80     ASSERT_EQ(0U, results()->at(0)->GetId());
     81   }
     82 
     83   // If no sorters distinguish between two items, then DownloadQuery sorts by ID
     84   // ascending. In order to test that a sorter distinguishes between two items,
     85   // the sorter must sort them by ID descending.
     86   void ExpectSortInverted() {
     87     Search();
     88     ASSERT_EQ(2U, results()->size());
     89     ASSERT_EQ(1U, results()->at(0)->GetId());
     90     ASSERT_EQ(0U, results()->at(1)->GetId());
     91   }
     92 
     93  private:
     94   std::vector<content::MockDownloadItem*> mocks_;
     95   DownloadQuery query_;
     96   DownloadVector results_;
     97 
     98   DISALLOW_COPY_AND_ASSIGN(DownloadQueryTest);
     99 };
    100 
    101 template<> void DownloadQueryTest::AddFilter(
    102     DownloadQuery::FilterType name, bool cpp_value) {
    103   scoped_ptr<base::Value> value(Value::CreateBooleanValue(cpp_value));
    104   CHECK(query_.AddFilter(name, *value.get()));
    105 }
    106 
    107 template<> void DownloadQueryTest::AddFilter(
    108     DownloadQuery::FilterType name, int cpp_value) {
    109   scoped_ptr<base::Value> value(Value::CreateIntegerValue(cpp_value));
    110   CHECK(query_.AddFilter(name, *value.get()));
    111 }
    112 
    113 template<> void DownloadQueryTest::AddFilter(
    114     DownloadQuery::FilterType name, const char* cpp_value) {
    115   scoped_ptr<base::Value> value(Value::CreateStringValue(cpp_value));
    116   CHECK(query_.AddFilter(name, *value.get()));
    117 }
    118 
    119 template<> void DownloadQueryTest::AddFilter(
    120     DownloadQuery::FilterType name, std::string cpp_value) {
    121   scoped_ptr<base::Value> value(Value::CreateStringValue(cpp_value));
    122   CHECK(query_.AddFilter(name, *value.get()));
    123 }
    124 
    125 template<> void DownloadQueryTest::AddFilter(
    126     DownloadQuery::FilterType name, const char16* cpp_value) {
    127   scoped_ptr<base::Value> value(Value::CreateStringValue(string16(cpp_value)));
    128   CHECK(query_.AddFilter(name, *value.get()));
    129 }
    130 
    131 template<> void DownloadQueryTest::AddFilter(
    132     DownloadQuery::FilterType name, std::vector<string16> cpp_value) {
    133   scoped_ptr<base::ListValue> list(new base::ListValue());
    134   for (std::vector<string16>::const_iterator it = cpp_value.begin();
    135        it != cpp_value.end(); ++it) {
    136     list->Append(Value::CreateStringValue(*it));
    137   }
    138   CHECK(query_.AddFilter(name, *list.get()));
    139 }
    140 
    141 template<> void DownloadQueryTest::AddFilter(
    142     DownloadQuery::FilterType name, std::vector<std::string> cpp_value) {
    143   scoped_ptr<base::ListValue> list(new base::ListValue());
    144   for (std::vector<std::string>::const_iterator it = cpp_value.begin();
    145        it != cpp_value.end(); ++it) {
    146     list->Append(Value::CreateStringValue(*it));
    147   }
    148   CHECK(query_.AddFilter(name, *list.get()));
    149 }
    150 
    151 #if defined(OS_WIN)
    152 template<> void DownloadQueryTest::AddFilter(
    153     DownloadQuery::FilterType name, std::wstring cpp_value) {
    154   scoped_ptr<base::Value> value(Value::CreateStringValue(cpp_value));
    155   CHECK(query_.AddFilter(name, *value.get()));
    156 }
    157 #endif
    158 
    159 TEST_F(DownloadQueryTest, DownloadQueryTest_ZeroItems) {
    160   Search();
    161   EXPECT_EQ(0U, results()->size());
    162 }
    163 
    164 TEST_F(DownloadQueryTest, DownloadQueryTest_InvalidFilter) {
    165   scoped_ptr<base::Value> value(Value::CreateIntegerValue(0));
    166   EXPECT_FALSE(query()->AddFilter(
    167       static_cast<DownloadQuery::FilterType>(kint32max),
    168       *value.get()));
    169 }
    170 
    171 TEST_F(DownloadQueryTest, DownloadQueryTest_EmptyQuery) {
    172   CreateMocks(2);
    173   Search();
    174   ASSERT_EQ(2U, results()->size());
    175   ASSERT_EQ(0U, results()->at(0)->GetId());
    176   ASSERT_EQ(1U, results()->at(1)->GetId());
    177 }
    178 
    179 TEST_F(DownloadQueryTest, DownloadQueryTest_Limit) {
    180   CreateMocks(2);
    181   query()->Limit(1);
    182   ExpectStandardFilterResults();
    183 }
    184 
    185 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterGenericQueryFilename) {
    186   CreateMocks(2);
    187   EXPECT_CALL(mock(0), GetBrowserContext()).WillRepeatedly(Return(
    188       static_cast<content::BrowserContext*>(NULL)));
    189   EXPECT_CALL(mock(1), GetBrowserContext()).WillRepeatedly(Return(
    190       static_cast<content::BrowserContext*>(NULL)));
    191   base::FilePath match_filename(FILE_PATH_LITERAL("query"));
    192   EXPECT_CALL(mock(0), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    193       match_filename));
    194   base::FilePath fail_filename(FILE_PATH_LITERAL("fail"));
    195   EXPECT_CALL(mock(1), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    196       fail_filename));
    197   GURL fail_url("http://example.com/fail");
    198   EXPECT_CALL(mock(0), GetOriginalUrl()).WillRepeatedly(ReturnRef(fail_url));
    199   EXPECT_CALL(mock(1), GetOriginalUrl()).WillRepeatedly(ReturnRef(fail_url));
    200   std::vector<std::string> query_terms;
    201   query_terms.push_back("query");
    202   AddFilter(DownloadQuery::FILTER_QUERY, query_terms);
    203   ExpectStandardFilterResults();
    204 }
    205 
    206 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterGenericQueryUrl) {
    207   CreateMocks(2);
    208   EXPECT_CALL(mock(0), GetBrowserContext()).WillRepeatedly(Return(
    209       static_cast<content::BrowserContext*>(NULL)));
    210   EXPECT_CALL(mock(1), GetBrowserContext()).WillRepeatedly(Return(
    211       static_cast<content::BrowserContext*>(NULL)));
    212   base::FilePath fail_filename(FILE_PATH_LITERAL("fail"));
    213   EXPECT_CALL(mock(0), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    214       fail_filename));
    215   EXPECT_CALL(mock(1), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    216       fail_filename));
    217   GURL match_url("http://query.com/query");
    218   EXPECT_CALL(mock(0), GetOriginalUrl()).WillRepeatedly(ReturnRef(match_url));
    219   GURL fail_url("http://example.com/fail");
    220   EXPECT_CALL(mock(1), GetOriginalUrl()).WillRepeatedly(ReturnRef(fail_url));
    221   std::vector<std::string> query_terms;
    222   query_terms.push_back("query");
    223   AddFilter(DownloadQuery::FILTER_QUERY, query_terms);
    224   ExpectStandardFilterResults();
    225 }
    226 
    227 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterGenericQueryFilenameI18N) {
    228   CreateMocks(2);
    229   EXPECT_CALL(mock(0), GetBrowserContext()).WillRepeatedly(Return(
    230       static_cast<content::BrowserContext*>(NULL)));
    231   EXPECT_CALL(mock(1), GetBrowserContext()).WillRepeatedly(Return(
    232       static_cast<content::BrowserContext*>(NULL)));
    233   const base::FilePath::StringType kTestString(
    234 #if defined(OS_POSIX)
    235       "/\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xbd\xa0\xe5\xa5\xbd"
    236 #elif defined(OS_WIN)
    237       L"/\x4f60\x597d\x4f60\x597d"
    238 #endif
    239       );
    240   base::FilePath match_filename(kTestString);
    241   EXPECT_CALL(mock(0), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    242       match_filename));
    243   base::FilePath fail_filename(FILE_PATH_LITERAL("fail"));
    244   EXPECT_CALL(mock(1), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    245       fail_filename));
    246   GURL fail_url("http://example.com/fail");
    247   EXPECT_CALL(mock(0), GetOriginalUrl()).WillRepeatedly(ReturnRef(fail_url));
    248   EXPECT_CALL(mock(1), GetOriginalUrl()).WillRepeatedly(ReturnRef(fail_url));
    249   std::vector<base::FilePath::StringType> query_terms;
    250   query_terms.push_back(kTestString);
    251   AddFilter(DownloadQuery::FILTER_QUERY, query_terms);
    252   ExpectStandardFilterResults();
    253 }
    254 
    255 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterFilenameRegex) {
    256   CreateMocks(2);
    257   base::FilePath match_filename(FILE_PATH_LITERAL("query"));
    258   EXPECT_CALL(mock(0), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    259       match_filename));
    260   base::FilePath fail_filename(FILE_PATH_LITERAL("fail"));
    261   EXPECT_CALL(mock(1), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    262       fail_filename));
    263   AddFilter(DownloadQuery::FILTER_FILENAME_REGEX, "y");
    264   ExpectStandardFilterResults();
    265 }
    266 
    267 TEST_F(DownloadQueryTest, DownloadQueryTest_SortFilename) {
    268   CreateMocks(2);
    269   base::FilePath b_filename(FILE_PATH_LITERAL("b"));
    270   EXPECT_CALL(mock(0), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    271       b_filename));
    272   base::FilePath a_filename(FILE_PATH_LITERAL("a"));
    273   EXPECT_CALL(mock(1), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    274       a_filename));
    275   query()->AddSorter(DownloadQuery::SORT_FILENAME, DownloadQuery::ASCENDING);
    276   ExpectSortInverted();
    277 }
    278 
    279 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterFilename) {
    280   CreateMocks(2);
    281   base::FilePath match_filename(FILE_PATH_LITERAL("query"));
    282   EXPECT_CALL(mock(0), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    283       match_filename));
    284   base::FilePath fail_filename(FILE_PATH_LITERAL("fail"));
    285   EXPECT_CALL(mock(1), GetTargetFilePath()).WillRepeatedly(ReturnRef(
    286       fail_filename));
    287   AddFilter(DownloadQuery::FILTER_FILENAME, match_filename.value().c_str());
    288   ExpectStandardFilterResults();
    289 }
    290 
    291 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterUrlRegex) {
    292   CreateMocks(2);
    293   GURL match_url("http://query.com/query");
    294   EXPECT_CALL(mock(0), GetOriginalUrl()).WillRepeatedly(ReturnRef(match_url));
    295   GURL fail_url("http://example.com/fail");
    296   EXPECT_CALL(mock(1), GetOriginalUrl()).WillRepeatedly(ReturnRef(fail_url));
    297   AddFilter(DownloadQuery::FILTER_URL_REGEX, "query");
    298   ExpectStandardFilterResults();
    299 }
    300 
    301 TEST_F(DownloadQueryTest, DownloadQueryTest_SortUrl) {
    302   CreateMocks(2);
    303   GURL b_url("http://example.com/b");
    304   EXPECT_CALL(mock(0), GetOriginalUrl()).WillRepeatedly(ReturnRef(b_url));
    305   GURL a_url("http://example.com/a");
    306   EXPECT_CALL(mock(1), GetOriginalUrl()).WillRepeatedly(ReturnRef(a_url));
    307   query()->AddSorter(DownloadQuery::SORT_URL, DownloadQuery::ASCENDING);
    308   ExpectSortInverted();
    309 }
    310 
    311 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterUrl) {
    312   CreateMocks(2);
    313   GURL match_url("http://query.com/query");
    314   EXPECT_CALL(mock(0), GetOriginalUrl()).WillRepeatedly(ReturnRef(match_url));
    315   GURL fail_url("http://example.com/fail");
    316   EXPECT_CALL(mock(1), GetOriginalUrl()).WillRepeatedly(ReturnRef(fail_url));
    317   AddFilter(DownloadQuery::FILTER_URL, match_url.spec().c_str());
    318   ExpectStandardFilterResults();
    319 }
    320 
    321 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterCallback) {
    322   CreateMocks(2);
    323   CHECK(query()->AddFilter(base::Bind(&IdNotEqual, 1)));
    324   ExpectStandardFilterResults();
    325 }
    326 
    327 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterBytesReceived) {
    328   CreateMocks(2);
    329   EXPECT_CALL(mock(0), GetReceivedBytes()).WillRepeatedly(Return(0));
    330   EXPECT_CALL(mock(1), GetReceivedBytes()).WillRepeatedly(Return(1));
    331   AddFilter(DownloadQuery::FILTER_BYTES_RECEIVED, 0);
    332   ExpectStandardFilterResults();
    333 }
    334 
    335 TEST_F(DownloadQueryTest, DownloadQueryTest_SortBytesReceived) {
    336   CreateMocks(2);
    337   EXPECT_CALL(mock(0), GetReceivedBytes()).WillRepeatedly(Return(0));
    338   EXPECT_CALL(mock(1), GetReceivedBytes()).WillRepeatedly(Return(1));
    339   query()->AddSorter(DownloadQuery::SORT_BYTES_RECEIVED,
    340                      DownloadQuery::DESCENDING);
    341   ExpectSortInverted();
    342 }
    343 
    344 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterDangerAccepted) {
    345   CreateMocks(2);
    346   EXPECT_CALL(mock(0), GetDangerType()).WillRepeatedly(Return(
    347       content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED));
    348   EXPECT_CALL(mock(1), GetDangerType()).WillRepeatedly(Return(
    349       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE));
    350   AddFilter(DownloadQuery::FILTER_DANGER_ACCEPTED, true);
    351   ExpectStandardFilterResults();
    352 }
    353 
    354 TEST_F(DownloadQueryTest, DownloadQueryTest_SortDangerAccepted) {
    355   CreateMocks(2);
    356   EXPECT_CALL(mock(0), GetDangerType()).WillRepeatedly(Return(
    357       content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED));
    358   EXPECT_CALL(mock(1), GetDangerType()).WillRepeatedly(Return(
    359       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE));
    360   query()->AddSorter(DownloadQuery::SORT_DANGER_ACCEPTED,
    361                      DownloadQuery::ASCENDING);
    362   ExpectSortInverted();
    363 }
    364 
    365 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterExists) {
    366   CreateMocks(2);
    367   EXPECT_CALL(mock(0), GetFileExternallyRemoved()).WillRepeatedly(Return(
    368       false));
    369   EXPECT_CALL(mock(1), GetFileExternallyRemoved()).WillRepeatedly(Return(
    370       true));
    371   AddFilter(DownloadQuery::FILTER_EXISTS, true);
    372   ExpectStandardFilterResults();
    373 }
    374 
    375 TEST_F(DownloadQueryTest, DownloadQueryTest_SortExists) {
    376   CreateMocks(2);
    377   EXPECT_CALL(mock(0), GetFileExternallyRemoved()).WillRepeatedly(Return(
    378       false));
    379   EXPECT_CALL(mock(1), GetFileExternallyRemoved()).WillRepeatedly(Return(
    380       true));
    381   query()->AddSorter(DownloadQuery::SORT_EXISTS,
    382                      DownloadQuery::ASCENDING);
    383   ExpectSortInverted();
    384 }
    385 
    386 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterMime) {
    387   CreateMocks(2);
    388   EXPECT_CALL(mock(0), GetMimeType()).WillRepeatedly(Return("text"));
    389   EXPECT_CALL(mock(1), GetMimeType()).WillRepeatedly(Return("image"));
    390   AddFilter(DownloadQuery::FILTER_MIME, "text");
    391   ExpectStandardFilterResults();
    392 }
    393 
    394 TEST_F(DownloadQueryTest, DownloadQueryTest_SortMime) {
    395   CreateMocks(2);
    396   EXPECT_CALL(mock(0), GetMimeType()).WillRepeatedly(Return("b"));
    397   EXPECT_CALL(mock(1), GetMimeType()).WillRepeatedly(Return("a"));
    398   query()->AddSorter(DownloadQuery::SORT_MIME, DownloadQuery::ASCENDING);
    399   ExpectSortInverted();
    400 }
    401 
    402 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterPaused) {
    403   CreateMocks(2);
    404   EXPECT_CALL(mock(0), IsPaused()).WillRepeatedly(Return(true));
    405   EXPECT_CALL(mock(1), IsPaused()).WillRepeatedly(Return(false));
    406   AddFilter(DownloadQuery::FILTER_PAUSED, true);
    407   ExpectStandardFilterResults();
    408 }
    409 
    410 TEST_F(DownloadQueryTest, DownloadQueryTest_SortPaused) {
    411   CreateMocks(2);
    412   EXPECT_CALL(mock(0), IsPaused()).WillRepeatedly(Return(true));
    413   EXPECT_CALL(mock(1), IsPaused()).WillRepeatedly(Return(false));
    414   query()->AddSorter(DownloadQuery::SORT_PAUSED, DownloadQuery::ASCENDING);
    415   ExpectSortInverted();
    416 }
    417 
    418 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterStartedAfter) {
    419   CreateMocks(2);
    420   EXPECT_CALL(mock(0), GetStartTime()).WillRepeatedly(Return(
    421       base::Time::FromTimeT(kSomeKnownTime + 2)));
    422   EXPECT_CALL(mock(1), GetStartTime()).WillRepeatedly(Return(
    423       base::Time::FromTimeT(kSomeKnownTime + 1)));
    424   AddFilter(DownloadQuery::FILTER_STARTED_AFTER,
    425             std::string(kSomeKnownTime8601) + "1" + std::string(k8601Suffix));
    426   ExpectStandardFilterResults();
    427 }
    428 
    429 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterStartedBefore) {
    430   CreateMocks(2);
    431   EXPECT_CALL(mock(0), GetStartTime()).WillRepeatedly(Return(
    432       base::Time::FromTimeT(kSomeKnownTime + 2)));
    433   EXPECT_CALL(mock(1), GetStartTime()).WillRepeatedly(Return(
    434       base::Time::FromTimeT(kSomeKnownTime + 4)));
    435   AddFilter(DownloadQuery::FILTER_STARTED_BEFORE,
    436             std::string(kSomeKnownTime8601) + "4" + std::string(k8601Suffix));
    437   ExpectStandardFilterResults();
    438 }
    439 
    440 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterStartTime) {
    441   CreateMocks(2);
    442   EXPECT_CALL(mock(0), GetStartTime()).WillRepeatedly(Return(
    443       base::Time::FromTimeT(kSomeKnownTime + 2)));
    444   EXPECT_CALL(mock(1), GetStartTime()).WillRepeatedly(Return(
    445       base::Time::FromTimeT(kSomeKnownTime + 4)));
    446   AddFilter(DownloadQuery::FILTER_START_TIME,
    447             std::string(kSomeKnownTime8601) + "2" + std::string(k8601Suffix));
    448   ExpectStandardFilterResults();
    449 }
    450 
    451 TEST_F(DownloadQueryTest, DownloadQueryTest_SortStartTime) {
    452   CreateMocks(2);
    453   EXPECT_CALL(mock(0), GetStartTime()).WillRepeatedly(Return(
    454       base::Time::FromTimeT(kSomeKnownTime + 2)));
    455   EXPECT_CALL(mock(1), GetStartTime()).WillRepeatedly(Return(
    456       base::Time::FromTimeT(kSomeKnownTime + 4)));
    457   query()->AddSorter(DownloadQuery::SORT_START_TIME, DownloadQuery::DESCENDING);
    458   ExpectSortInverted();
    459 }
    460 
    461 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterEndedAfter) {
    462   CreateMocks(2);
    463   EXPECT_CALL(mock(0), GetEndTime()).WillRepeatedly(Return(
    464       base::Time::FromTimeT(kSomeKnownTime + 2)));
    465   EXPECT_CALL(mock(1), GetEndTime()).WillRepeatedly(Return(
    466       base::Time::FromTimeT(kSomeKnownTime + 1)));
    467   AddFilter(DownloadQuery::FILTER_ENDED_AFTER,
    468             std::string(kSomeKnownTime8601) + "1" + std::string(k8601Suffix));
    469   ExpectStandardFilterResults();
    470 }
    471 
    472 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterEndedBefore) {
    473   CreateMocks(2);
    474   EXPECT_CALL(mock(0), GetEndTime()).WillRepeatedly(Return(
    475       base::Time::FromTimeT(kSomeKnownTime + 2)));
    476   EXPECT_CALL(mock(1), GetEndTime()).WillRepeatedly(Return(
    477       base::Time::FromTimeT(kSomeKnownTime + 4)));
    478   AddFilter(DownloadQuery::FILTER_ENDED_BEFORE,
    479             std::string(kSomeKnownTime8601) + "4" + std::string(k8601Suffix));
    480   ExpectStandardFilterResults();
    481 }
    482 
    483 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterEndTime) {
    484   CreateMocks(2);
    485   EXPECT_CALL(mock(0), GetEndTime()).WillRepeatedly(Return(
    486       base::Time::FromTimeT(kSomeKnownTime + 2)));
    487   EXPECT_CALL(mock(1), GetEndTime()).WillRepeatedly(Return(
    488       base::Time::FromTimeT(kSomeKnownTime + 4)));
    489   AddFilter(DownloadQuery::FILTER_END_TIME,
    490             std::string(kSomeKnownTime8601) + "2" + std::string(k8601Suffix));
    491   ExpectStandardFilterResults();
    492 }
    493 
    494 TEST_F(DownloadQueryTest, DownloadQueryTest_SortEndTime) {
    495   CreateMocks(2);
    496   EXPECT_CALL(mock(0), GetEndTime()).WillRepeatedly(Return(
    497       base::Time::FromTimeT(kSomeKnownTime + 2)));
    498   EXPECT_CALL(mock(1), GetEndTime()).WillRepeatedly(Return(
    499       base::Time::FromTimeT(kSomeKnownTime + 4)));
    500   query()->AddSorter(DownloadQuery::SORT_END_TIME, DownloadQuery::DESCENDING);
    501   ExpectSortInverted();
    502 }
    503 
    504 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterTotalBytesGreater) {
    505   CreateMocks(2);
    506   EXPECT_CALL(mock(0), GetTotalBytes()).WillRepeatedly(Return(2));
    507   EXPECT_CALL(mock(1), GetTotalBytes()).WillRepeatedly(Return(1));
    508   AddFilter(DownloadQuery::FILTER_TOTAL_BYTES_GREATER, 1);
    509   ExpectStandardFilterResults();
    510 }
    511 
    512 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterTotalBytesLess) {
    513   CreateMocks(2);
    514   EXPECT_CALL(mock(0), GetTotalBytes()).WillRepeatedly(Return(2));
    515   EXPECT_CALL(mock(1), GetTotalBytes()).WillRepeatedly(Return(4));
    516   AddFilter(DownloadQuery::FILTER_TOTAL_BYTES_LESS, 4);
    517   ExpectStandardFilterResults();
    518 }
    519 
    520 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterTotalBytes) {
    521   CreateMocks(2);
    522   EXPECT_CALL(mock(0), GetTotalBytes()).WillRepeatedly(Return(2));
    523   EXPECT_CALL(mock(1), GetTotalBytes()).WillRepeatedly(Return(4));
    524   AddFilter(DownloadQuery::FILTER_TOTAL_BYTES, 2);
    525   ExpectStandardFilterResults();
    526 }
    527 
    528 TEST_F(DownloadQueryTest, DownloadQueryTest_SortTotalBytes) {
    529   CreateMocks(2);
    530   EXPECT_CALL(mock(0), GetTotalBytes()).WillRepeatedly(Return(2));
    531   EXPECT_CALL(mock(1), GetTotalBytes()).WillRepeatedly(Return(4));
    532   query()->AddSorter(DownloadQuery::SORT_TOTAL_BYTES,
    533                      DownloadQuery::DESCENDING);
    534   ExpectSortInverted();
    535 }
    536 
    537 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterState) {
    538   CreateMocks(2);
    539   EXPECT_CALL(mock(0), GetState()).WillRepeatedly(Return(
    540       DownloadItem::IN_PROGRESS));
    541   EXPECT_CALL(mock(1), GetState()).WillRepeatedly(Return(
    542       DownloadItem::CANCELLED));
    543   query()->AddFilter(DownloadItem::IN_PROGRESS);
    544   ExpectStandardFilterResults();
    545 }
    546 
    547 TEST_F(DownloadQueryTest, DownloadQueryTest_SortState) {
    548   CreateMocks(2);
    549   EXPECT_CALL(mock(0), GetState()).WillRepeatedly(Return(
    550       DownloadItem::IN_PROGRESS));
    551   EXPECT_CALL(mock(1), GetState()).WillRepeatedly(Return(
    552       DownloadItem::CANCELLED));
    553   query()->AddSorter(DownloadQuery::SORT_STATE, DownloadQuery::DESCENDING);
    554   ExpectSortInverted();
    555 }
    556 
    557 TEST_F(DownloadQueryTest, DownloadQueryTest_FilterDanger) {
    558   CreateMocks(2);
    559   EXPECT_CALL(mock(0), GetDangerType()).WillRepeatedly(Return(
    560       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
    561   EXPECT_CALL(mock(1), GetDangerType()).WillRepeatedly(Return(
    562       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE));
    563   query()->AddFilter(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
    564   ExpectStandardFilterResults();
    565 }
    566 
    567 TEST_F(DownloadQueryTest, DownloadQueryTest_SortDanger) {
    568   CreateMocks(2);
    569   EXPECT_CALL(mock(0), GetDangerType()).WillRepeatedly(Return(
    570       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
    571   EXPECT_CALL(mock(1), GetDangerType()).WillRepeatedly(Return(
    572       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE));
    573   query()->AddSorter(DownloadQuery::SORT_DANGER, DownloadQuery::DESCENDING);
    574   ExpectSortInverted();
    575 }
    576 
    577 TEST_F(DownloadQueryTest, DownloadQueryTest_DefaultSortById1) {
    578   CreateMocks(2);
    579   EXPECT_CALL(mock(0), GetReceivedBytes()).WillRepeatedly(Return(0));
    580   EXPECT_CALL(mock(1), GetReceivedBytes()).WillRepeatedly(Return(0));
    581   query()->AddSorter(DownloadQuery::SORT_BYTES_RECEIVED,
    582                      DownloadQuery::ASCENDING);
    583   Search();
    584   ASSERT_EQ(2U, results()->size());
    585   EXPECT_EQ(0U, results()->at(0)->GetId());
    586   EXPECT_EQ(1U, results()->at(1)->GetId());
    587 }
    588 
    589 TEST_F(DownloadQueryTest, DownloadQueryTest_DefaultSortById2) {
    590   CreateMocks(2);
    591   EXPECT_CALL(mock(0), GetReceivedBytes()).WillRepeatedly(Return(0));
    592   EXPECT_CALL(mock(1), GetReceivedBytes()).WillRepeatedly(Return(0));
    593   query()->AddSorter(DownloadQuery::SORT_BYTES_RECEIVED,
    594                      DownloadQuery::DESCENDING);
    595   Search();
    596   ASSERT_EQ(2U, results()->size());
    597   EXPECT_EQ(0U, results()->at(0)->GetId());
    598   EXPECT_EQ(1U, results()->at(1)->GetId());
    599 }
    600 
    601 TEST_F(DownloadQueryTest, DownloadQueryFilterPerformance) {
    602   static const int kNumItems = 100;
    603   static const int kNumFilters = 100;
    604   CreateMocks(kNumItems);
    605   for (size_t i = 0; i < (kNumFilters - 1); ++i) {
    606     query()->AddFilter(base::Bind(&AlwaysReturn, true));
    607   }
    608   query()->AddFilter(base::Bind(&AlwaysReturn, false));
    609   base::Time start = base::Time::Now();
    610   Search();
    611   base::Time end = base::Time::Now();
    612   double nanos = (end - start).InMillisecondsF() * 1000.0 * 1000.0;
    613   double nanos_per_item = nanos / static_cast<double>(kNumItems);
    614   double nanos_per_item_per_filter = nanos_per_item
    615     / static_cast<double>(kNumFilters);
    616   std::cout << "Search took " << nanos_per_item_per_filter
    617             << " nanoseconds per item per filter.\n";
    618 }
    619