1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_temp_dir.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time;
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests the history service for querying functionality.
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace history {
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct TestEntry {
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* url;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* title;
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int days_ago;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* body;
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Time time;  // Filled by SetUp.
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} test_entries[] = {
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This one is visited super long ago so it will be in a different database
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // from the next appearance of it at the end.
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {"http://example.com/", "Other", 180, "Other"},
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These are deliberately added out of chronological order. The history
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // service should sort them by visit time when returning query results.
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The correct index sort order is 4 2 3 1 0.
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {"http://www.google.com/1", "Title 1", 10,
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   "PAGEONE FOO some body text"},
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {"http://www.google.com/3", "Title 3", 8,
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   "PAGETHREE BAR some hello world for you"},
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {"http://www.google.com/2", "Title 2", 9,
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   "PAGETWO FOO some more blah blah blah"},
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A more recent visit of the first one.
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {"http://example.com/", "Other", 6, "Other"},
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns true if the nth result in the given results set matches. It will
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// return false on a non-match or if there aren't enough results.
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NthResultIs(const QueryResults& results,
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 int n,  // Result index to check.
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 int test_entry_index) {  // Index of test_entries to compare.
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (static_cast<int>(results.size()) <= n)
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const URLResult& result = results[n];
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check the visit time.
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (result.visit_time() != test_entries[test_entry_index].time)
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now check the URL & title.
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result.url() == GURL(test_entries[test_entry_index].url) &&
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         result.title() == UTF8ToUTF16(test_entries[test_entry_index].title);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass HistoryQueryTest : public testing::Test {
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HistoryQueryTest() {
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Acts like a synchronous call to history's QueryHistory.
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void QueryHistory(const std::string& text_query,
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    const QueryOptions& options,
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    QueryResults* results) {
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    history_->QueryHistory(UTF8ToUTF16(text_query), options, &consumer_,
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewCallback(this, &HistoryQueryTest::QueryHistoryComplete));
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->Run();  // Will go until ...Complete calls Quit.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    results->Swap(&last_query_results_);
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<HistoryService> history_;
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetUp() {
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    history_dir_ = temp_dir_.path().AppendASCII("HistoryTest");
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_TRUE(file_util::CreateDirectory(history_dir_));
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    history_ = new HistoryService;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!history_->Init(history_dir_, NULL)) {
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      history_ = NULL;  // Tests should notice this NULL ptr & fail.
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Fill the test data.
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Time now = Time::Now().LocalMidnight();
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < arraysize(test_entries); i++) {
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      test_entries[i].time =
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          now - (test_entries[i].days_ago * TimeDelta::FromDays(1));
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We need the ID scope and page ID so that the visit tracker can find it.
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const void* id_scope = reinterpret_cast<void*>(1);
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int32 page_id = i;
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL url(test_entries[i].url);
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      history_->AddPage(url, test_entries[i].time, id_scope, page_id, GURL(),
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        PageTransition::LINK, history::RedirectList(),
1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        history::SOURCE_BROWSED, false);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      history_->SetPageTitle(url, UTF8ToUTF16(test_entries[i].title));
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      history_->SetPageContents(url, UTF8ToUTF16(test_entries[i].body));
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TearDown() {
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (history_.get()) {
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      history_->SetOnBackendDestroyTask(new MessageLoop::QuitTask);
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      history_->Cleanup();
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      history_ = NULL;
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MessageLoop::current()->Run();  // Wait for the other thread.
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void QueryHistoryComplete(HistoryService::Handle, QueryResults* results) {
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    results->Swap(&last_query_results_);
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->Quit();  // Will return out to QueryHistory.
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ScopedTempDir temp_dir_;
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop message_loop_;
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath history_dir_;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CancelableRequestConsumer consumer_;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The QueryHistoryComplete callback will put the results here so QueryHistory
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // can return them.
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryResults last_query_results_;
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(HistoryQueryTest);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HistoryQueryTest, Basic) {
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(history_.get());
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryOptions options;
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryResults results;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test duplicate collapsing.
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory(std::string(), options, &results);
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(4U, results.size());
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 4));
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 1, 2));
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 2, 3));
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 3, 1));
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Next query a time range. The beginning should be inclusive, the ending
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should be exclusive.
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.begin_time = test_entries[3].time;
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.end_time = test_entries[2].time;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory(std::string(), options, &results);
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1U, results.size());
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 3));
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests max_count feature for basic (non-Full Text Search) queries.
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HistoryQueryTest, BasicCount) {
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(history_.get());
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryOptions options;
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryResults results;
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Query all time but with a limit on the number of entries. We should
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // get the N most recent entries.
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.max_count = 2;
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory(std::string(), options, &results);
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2U, results.size());
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 4));
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 1, 2));
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HistoryQueryTest, ReachedBeginning) {
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(history_.get());
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryOptions options;
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryResults results;
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory(std::string(), options, &results);
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(results.reached_beginning());
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.begin_time = test_entries[1].time;
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory(std::string(), options, &results);
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(results.reached_beginning());
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.begin_time = test_entries[0].time + TimeDelta::FromMicroseconds(1);
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory(std::string(), options, &results);
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(results.reached_beginning());
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.begin_time = test_entries[0].time;
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory(std::string(), options, &results);
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(results.reached_beginning());
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.begin_time = test_entries[0].time - TimeDelta::FromMicroseconds(1);
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory(std::string(), options, &results);
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(results.reached_beginning());
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This does most of the same tests above, but searches for a FTS string that
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will match the pages in question. This will trigger a different code path.
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HistoryQueryTest, FTS) {
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(history_.get());
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryOptions options;
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryResults results;
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Query all of them to make sure they are there and in order. Note that
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // this query will return the starred item twice since we requested all
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // starred entries and no de-duping.
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory("some", options, &results);
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3U, results.size());
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 2));
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 1, 3));
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 2, 1));
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Do a query that should only match one of them.
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory("PAGETWO", options, &results);
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1U, results.size());
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 3));
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Next query a time range. The beginning should be inclusive, the ending
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should be exclusive.
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.begin_time = test_entries[1].time;
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.end_time = test_entries[3].time;
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory("some", options, &results);
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1U, results.size());
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 1));
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Searches titles.
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HistoryQueryTest, FTSTitle) {
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(history_.get());
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryOptions options;
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryResults results;
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Query all time but with a limit on the number of entries. We should
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // get the N most recent entries.
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory("title", options, &results);
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3U, results.size());
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 2));
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 1, 3));
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 2, 1));
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests prefix searching for Full Text Search queries.
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HistoryQueryTest, FTSPrefix) {
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(history_.get());
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryOptions options;
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryResults results;
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Query with a prefix search.  Should return matches for "PAGETWO" and
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // "PAGETHREE".
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory("PAGET", options, &results);
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2U, results.size());
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 2));
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 1, 3));
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests max_count feature for Full Text Search queries.
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HistoryQueryTest, FTSCount) {
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(history_.get());
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryOptions options;
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryResults results;
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Query all time but with a limit on the number of entries. We should
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // get the N most recent entries.
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.max_count = 2;
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory("some", options, &results);
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2U, results.size());
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 2));
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 1, 3));
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now query a subset of the pages and limit by N items. "FOO" should match
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the 2nd & 3rd pages, but we should only get the 3rd one because of the one
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // page max restriction.
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  options.max_count = 1;
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory("FOO", options, &results);
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1U, results.size());
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 3));
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that FTS queries can find URLs when they exist only in the archived
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// database. This also tests that imported URLs can be found, since we use
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AddPageWithDetails just like the importer.
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HistoryQueryTest, FTSArchived) {
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(history_.get());
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<URLRow> urls_to_add;
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  URLRow row1(GURL("http://foo.bar/"));
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  row1.set_title(UTF8ToUTF16("archived title"));
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  row1.set_last_visit(Time::Now() - TimeDelta::FromDays(365));
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  urls_to_add.push_back(row1);
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  URLRow row2(GURL("http://foo.bar/"));
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  row2.set_title(UTF8ToUTF16("nonarchived title"));
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  row2.set_last_visit(Time::Now());
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  urls_to_add.push_back(row2);
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  history_->AddPagesWithDetails(urls_to_add, history::SOURCE_BROWSED);
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryOptions options;
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryResults results;
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Query all time. The title we get should be the one in the full text
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // database and not the most current title (since otherwise highlighting in
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the title might be wrong).
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory("archived", options, &results);
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1U, results.size());
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(row1.url() == results[0].url());
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(row1.title() == results[0].title());
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/* TODO(brettw) re-enable this. It is commented out because the current history
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   code prohibits adding more than one indexed page with the same URL. When we
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   have tiered history, there could be a dupe in the archived history which
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   won't get picked up by the deletor and it can happen again. When this is the
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   case, we should fix this test to duplicate that situation.
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests duplicate collapsing and not in Full Text Search situations.
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(HistoryQueryTest, FTSDupes) {
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(history_.get());
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryOptions options;
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryResults results;
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  QueryHistory("Other", options, &results);
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, results.urls().size());
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(NthResultIs(results, 0, 4));
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch*/
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace history
351