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