15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the history service for querying functionality.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace history {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TestEntry {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* url;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* title;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int days_ago;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time time;  // Filled by SetUp.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} test_entries[] = {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This one is visited super long ago so it will be in a different database
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the next appearance of it at the end.
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {"http://example.com/", "Other", 180},
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These are deliberately added out of chronological order. The history
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // service should sort them by visit time when returning query results.
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The correct index sort order is 4 2 3 1 7 6 5 0.
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {"http://www.google.com/1", "Title PAGEONE FOO some text", 10},
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {"http://www.google.com/3", "Title PAGETHREE BAR some hello world", 8},
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {"http://www.google.com/2", "Title PAGETWO FOO some more blah blah blah", 9},
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A more recent visit of the first one.
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {"http://example.com/", "Other", 6},
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {"http://www.google.com/6", "Title I'm the second oldest", 13},
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {"http://www.google.com/4", "Title four", 12},
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {"http://www.google.com/5", "Title five", 11},
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the nth result in the given results set matches. It will
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return false on a non-match or if there aren't enough results.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NthResultIs(const QueryResults& results,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 int n,  // Result index to check.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 int test_entry_index) {  // Index of test_entries to compare.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (static_cast<int>(results.size()) <= n)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const URLResult& result = results[n];
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the visit time.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result.visit_time() != test_entries[test_entry_index].time)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now check the URL & title.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result.url() == GURL(test_entries[test_entry_index].url) &&
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         result.title() == UTF8ToUTF16(test_entries[test_entry_index].title);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryQueryTest : public testing::Test {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistoryQueryTest() : page_id_(0) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Acts like a synchronous call to history's QueryHistory.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void QueryHistory(const std::string& text_query,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const QueryOptions& options,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    QueryResults* results) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_->QueryHistory(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UTF8ToUTF16(text_query), options, &consumer_,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryQueryTest::QueryHistoryComplete,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Will go until ...Complete calls Quit.
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results->Swap(&last_query_results_);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test paging through results, with a fixed number of results per page.
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Defined here so code can be shared for the text search and the non-text
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // seach versions.
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void TestPaging(const std::string& query_text,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  const int* expected_results,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  int results_length) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(history_.get());
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QueryOptions options;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QueryResults results;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    options.max_count = 1;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < results_length; i++) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SCOPED_TRACE(testing::Message() << "i = " << i);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      QueryHistory(query_text, options, &results);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_EQ(1U, results.size());
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(NthResultIs(results, 0, expected_results[i]));
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      options.end_time = results.back().visit_time();
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QueryHistory(query_text, options, &results);
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0U, results.size());
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Try with a max_count > 1.
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    options.max_count = 2;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    options.end_time = base::Time();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < results_length / 2; i++) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SCOPED_TRACE(testing::Message() << "i = " << i);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      QueryHistory(query_text, options, &results);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_EQ(2U, results.size());
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(NthResultIs(results, 0, expected_results[i * 2]));
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(NthResultIs(results, 1, expected_results[i * 2 + 1]));
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      options.end_time = results.back().visit_time();
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Add a couple of entries with duplicate timestamps. Use |query_text| as
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // the title of both entries so that they match a text query.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestEntry duplicates[] = {
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      { "http://www.google.com/x",  query_text.c_str(), 1, },
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      { "http://www.google.com/y",  query_text.c_str(), 1, }
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddEntryToHistory(duplicates[0]);
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddEntryToHistory(duplicates[1]);
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Make sure that paging proceeds even if there are duplicate timestamps.
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    options.end_time = base::Time();
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    do {
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      QueryHistory(query_text, options, &results);
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_NE(options.end_time, results.back().visit_time());
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      options.end_time = results.back().visit_time();
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } while (!results.reached_beginning());
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HistoryService> history_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Counter used to generate a unique ID for each page added to the history.
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int32 page_id_;
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddEntryToHistory(const TestEntry& entry) {
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We need the ID scope and page ID so that the visit tracker can find it.
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const void* id_scope = reinterpret_cast<void*>(1);
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GURL url(entry.url);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    history_->AddPage(url, entry.time, id_scope, page_id_++, GURL(),
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      history::RedirectList(), content::PAGE_TRANSITION_LINK,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      history::SOURCE_BROWSED, false);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    history_->SetPageTitle(url, UTF8ToUTF16(entry.title));
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_dir_ = temp_dir_.path().AppendASCII("HistoryTest");
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(file_util::CreateDirectory(history_dir_));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_.reset(new HistoryService);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!history_->Init(history_dir_, NULL)) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history_.reset();  // Tests should notice this NULL ptr & fail.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fill the test data.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Time now = Time::Now().LocalMidnight();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(test_entries); i++) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_entries[i].time =
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          now - (test_entries[i].days_ago * TimeDelta::FromDays(1));
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddEntryToHistory(test_entries[i]);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
180b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (history_) {
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      history_->SetOnBackendDestroyTask(base::MessageLoop::QuitClosure());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history_->Cleanup();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history_.reset();
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoop::current()->Run();  // Wait for the other thread.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void QueryHistoryComplete(HistoryService::Handle, QueryResults* results) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results->Swap(&last_query_results_);
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();  // Will return out to QueryHistory.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop message_loop_;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath history_dir_;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelableRequestConsumer consumer_;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The QueryHistoryComplete callback will put the results here so QueryHistory
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can return them.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryResults last_query_results_;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HistoryQueryTest);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryQueryTest, Basic) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_.get());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryOptions options;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryResults results;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test duplicate collapsing. 0 is an older duplicate of 4, and should not
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // appear in the result set.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory(std::string(), options, &results);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(7U, results.size());
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 0, 4));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 1, 2));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 2, 3));
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 3, 1));
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 4, 7));
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 5, 6));
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 6, 5));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Next query a time range. The beginning should be inclusive, the ending
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be exclusive.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.begin_time = test_entries[3].time;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.end_time = test_entries[2].time;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory(std::string(), options, &results);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, results.size());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 0, 3));
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests max_count feature for basic (non-Full Text Search) queries.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryQueryTest, BasicCount) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_.get());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryOptions options;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryResults results;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Query all time but with a limit on the number of entries. We should
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get the N most recent entries.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.max_count = 2;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory(std::string(), options, &results);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, results.size());
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 0, 4));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 1, 2));
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistoryQueryTest, ReachedBeginning) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_.get());
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryOptions options;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryResults results;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory(std::string(), options, &results);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(results.reached_beginning());
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory("some", options, &results);
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(results.reached_beginning());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.begin_time = test_entries[1].time;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory(std::string(), options, &results);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(results.reached_beginning());
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory("some", options, &results);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(results.reached_beginning());
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try |begin_time| just later than the oldest visit.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.begin_time = test_entries[0].time + TimeDelta::FromMicroseconds(1);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory(std::string(), options, &results);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(results.reached_beginning());
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory("some", options, &results);
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(results.reached_beginning());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try |begin_time| equal to the oldest visit.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.begin_time = test_entries[0].time;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory(std::string(), options, &results);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(results.reached_beginning());
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory("some", options, &results);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(results.reached_beginning());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try |begin_time| just earlier than the oldest visit.
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.begin_time = test_entries[0].time - TimeDelta::FromMicroseconds(1);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory(std::string(), options, &results);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(results.reached_beginning());
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory("some", options, &results);
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(results.reached_beginning());
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test with |max_count| specified.
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  options.max_count = 1;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory(std::string(), options, &results);
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(results.reached_beginning());
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory("some", options, &results);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(results.reached_beginning());
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test with |max_count| greater than the number of results,
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and exactly equal to the number of results.
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  options.max_count = 100;
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory(std::string(), options, &results);
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(results.reached_beginning());
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  options.max_count = results.size();
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory(std::string(), options, &results);
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(results.reached_beginning());
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  options.max_count = 100;
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory("some", options, &results);
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(results.reached_beginning());
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  options.max_count = results.size();
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QueryHistory("some", options, &results);
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(results.reached_beginning());
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// This does most of the same tests above, but performs a text searches for a
315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// string that will match the pages in question. This will trigger a
316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// different code path.
317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(HistoryQueryTest, TextSearch) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_.get());
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryOptions options;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryResults results;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Query all of them to make sure they are there and in order. Note that
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this query will return the starred item twice since we requested all
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // starred entries and no de-duping.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory("some", options, &results);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, results.size());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 0, 2));
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 1, 3));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 2, 1));
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do a query that should only match one of them.
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory("PAGETWO", options, &results);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, results.size());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 0, 3));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Next query a time range. The beginning should be inclusive, the ending
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be exclusive.
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.begin_time = test_entries[1].time;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.end_time = test_entries[3].time;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory("some", options, &results);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, results.size());
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 0, 1));
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tests prefix searching for text search queries.
347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(HistoryQueryTest, TextSearchPrefix) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_.get());
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryOptions options;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryResults results;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Query with a prefix search.  Should return matches for "PAGETWO" and
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "PAGETHREE".
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory("PAGET", options, &results);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, results.size());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 0, 2));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 1, 3));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tests max_count feature for text search queries.
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(HistoryQueryTest, TextSearchCount) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_.get());
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryOptions options;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryResults results;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Query all time but with a limit on the number of entries. We should
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get the N most recent entries.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.max_count = 2;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory("some", options, &results);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, results.size());
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 0, 2));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 1, 3));
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now query a subset of the pages and limit by N items. "FOO" should match
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the 2nd & 3rd pages, but we should only get the 3rd one because of the one
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // page max restriction.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.max_count = 1;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory("FOO", options, &results);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, results.size());
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 0, 3));
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tests that text search queries can find URLs when they exist only in the
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// archived database. This also tests that imported URLs can be found, since
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// we use AddPageWithDetails just like the importer.
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(HistoryQueryTest, TextSearchArchived) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_.get());
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRows urls_to_add;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row1(GURL("http://foo.bar/"));
394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  row1.set_title(UTF8ToUTF16("archived title same"));
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row1.set_last_visit(Time::Now() - TimeDelta::FromDays(365));
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls_to_add.push_back(row1);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRow row2(GURL("http://foo.bar/"));
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  row2.set_title(UTF8ToUTF16("nonarchived title same"));
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row2.set_last_visit(Time::Now());
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls_to_add.push_back(row2);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_->AddPagesWithDetails(urls_to_add, history::SOURCE_BROWSED);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryOptions options;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryResults results;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Query all time. The title we get should be the one in the archived and
409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // not the most current title (since otherwise highlighting in
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the title might be wrong).
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory("archived", options, &results);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, results.size());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(row1.url() == results[0].url());
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(row1.title() == results[0].title());
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check query is ordered correctly when split between archived and
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // non-archived database.
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  QueryHistory("same", options, &results);
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(2U, results.size());
420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(row2.url() == results[0].url());
421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(row2.title() == results[0].title());
422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(row1.url() == results[1].url());
423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(row1.title() == results[1].title());
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* TODO(brettw) re-enable this. It is commented out because the current history
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   code prohibits adding more than one indexed page with the same URL. When we
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   have tiered history, there could be a dupe in the archived history which
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   won't get picked up by the deletor and it can happen again. When this is the
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case, we should fix this test to duplicate that situation.
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tests duplicate collapsing and not in text search situations.
433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(HistoryQueryTest, TextSearchDupes) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(history_.get());
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryOptions options;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryResults results;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryHistory("Other", options, &results);
440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(1U, results.size());
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NthResultIs(results, 0, 4));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test iterating over pages of results.
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistoryQueryTest, Paging) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since results are fetched 1 and 2 at a time, entry #0 and #6 will not
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // be de-duplicated.
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int expected_results[] = { 4, 2, 3, 1, 7, 6, 5, 0 };
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPaging(std::string(), expected_results, arraysize(expected_results));
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(HistoryQueryTest, TextSearchPaging) {
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since results are fetched 1 and 2 at a time, entry #0 and #6 will not
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // be de-duplicated. Entry #4 does not contain the text "title", so it
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // shouldn't appear.
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int expected_results[] = { 2, 3, 1, 7, 6, 5 };
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestPaging("title", expected_results, arraysize(expected_results));
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace history
462