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(Value::CreateStringValue(string16(cpp_value)));
128  CHECK(query_.AddFilter(name, *value.get()));
129}
130
131template<> 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
141template<> 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)
152template<> 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
159TEST_F(DownloadQueryTest, DownloadQueryTest_ZeroItems) {
160  Search();
161  EXPECT_EQ(0U, results()->size());
162}
163
164TEST_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
171TEST_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
179TEST_F(DownloadQueryTest, DownloadQueryTest_Limit) {
180  CreateMocks(2);
181  query()->Limit(1);
182  ExpectStandardFilterResults();
183}
184
185TEST_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
206TEST_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
227TEST_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
255TEST_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
267TEST_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
279TEST_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
291TEST_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
301TEST_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
311TEST_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
321TEST_F(DownloadQueryTest, DownloadQueryTest_FilterCallback) {
322  CreateMocks(2);
323  CHECK(query()->AddFilter(base::Bind(&IdNotEqual, 1)));
324  ExpectStandardFilterResults();
325}
326
327TEST_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
335TEST_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
344TEST_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
354TEST_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
365TEST_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
375TEST_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
386TEST_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
394TEST_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
402TEST_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
410TEST_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
418TEST_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
429TEST_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
440TEST_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
451TEST_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
461TEST_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
472TEST_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
483TEST_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
494TEST_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
504TEST_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
512TEST_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
520TEST_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
528TEST_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
537TEST_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
547TEST_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
557TEST_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
567TEST_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
577TEST_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
589TEST_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
601TEST_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