13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 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 <string>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_split.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_index.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_model.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_utils.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_database.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/in_memory_database.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/query_parser.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/test/testing_browser_process_test.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/testing_profile.h"
21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenclass BookmarkIndexTest : public TestingBrowserProcessTest {
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkIndexTest() : model_(new BookmarkModel(NULL)) {}
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void AddBookmarksWithTitles(const char** titles, size_t count) {
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<std::string> title_vector;
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < count; ++i)
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      title_vector.push_back(titles[i]);
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBookmarksWithTitles(title_vector);
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void AddBookmarksWithTitles(const std::vector<std::string>& titles) {
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url("about:blank");
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < titles.size(); ++i)
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      model_->AddURL(model_->other_node(), static_cast<int>(i),
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                     ASCIIToUTF16(titles[i]), url);
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void ExpectMatches(const std::string& query,
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                     const char** expected_titles,
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     size_t expected_count) {
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<std::string> title_vector;
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < expected_count; ++i)
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      title_vector.push_back(expected_titles[i]);
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExpectMatches(query, title_vector);
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void ExpectMatches(const std::string& query,
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                     const std::vector<std::string> expected_titles) {
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<bookmark_utils::TitleMatch> matches;
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    model_->GetBookmarksWithTitlesMatching(ASCIIToUTF16(query), 1000, &matches);
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(expected_titles.size(), matches.size());
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < expected_titles.size(); ++i) {
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bool found = false;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for (size_t j = 0; j < matches.size(); ++j) {
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (ASCIIToUTF16(expected_titles[i]) == matches[j].node->GetTitle()) {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          matches.erase(matches.begin() + j);
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          found = true;
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          break;
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(found);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ExtractMatchPositions(const std::string& string,
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             Snippet::MatchPositions* matches) {
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<std::string> match_strings;
72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    base::SplitString(string, ':', &match_strings);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < match_strings.size(); ++i) {
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::vector<std::string> chunks;
75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      base::SplitString(match_strings[i], ',', &chunks);
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_EQ(2U, chunks.size());
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      matches->push_back(Snippet::MatchPosition());
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      int chunks0, chunks1;
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      base::StringToInt(chunks[0], &chunks0);
803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      base::StringToInt(chunks[1], &chunks1);
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      matches->back().first = chunks0;
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      matches->back().second = chunks1;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void ExpectMatchPositions(const std::string& query,
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const Snippet::MatchPositions& expected_positions) {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<bookmark_utils::TitleMatch> matches;
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    model_->GetBookmarksWithTitlesMatching(ASCIIToUTF16(query), 1000, &matches);
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(1U, matches.size());
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const bookmark_utils::TitleMatch& match = matches[0];
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(expected_positions.size(), match.match_positions.size());
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < expected_positions.size(); ++i) {
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(expected_positions[i].first, match.match_positions[i].first);
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(expected_positions[i].second, match.match_positions[i].second);
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<BookmarkModel> model_;
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(BookmarkIndexTest);
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Various permutations with differing input, queries and output that exercises
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// all query paths.
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkIndexTest, Tests) {
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct TestData {
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string input;
1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string query;
1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string expected;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } data[] = {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Trivial test case of only one term, exact match.
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { "a;b",                        "A",        "a" },
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Prefix match, one term.
1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { "abcd;abc;b",                 "abc",      "abcd;abc" },
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Prefix match, multiple terms.
1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { "abcd cdef;abcd;abcd cdefg",  "abc cde",  "abcd cdef;abcd cdefg"},
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Exact and prefix match.
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { "ab cdef;abcd;abcd cdefg",    "ab cdef",  "ab cdef"},
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Exact and prefix match.
1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { "ab cdef ghij;ab;cde;cdef;ghi;cdef ab;ghij ab",
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "ab cde ghi",
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "ab cdef ghij"},
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Title with term multiple times.
1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { "ab ab",                      "ab",       "ab ab"},
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make sure quotes don't do a prefix match.
1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { "think",                      "\"thi\"",  ""},
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<std::string> titles;
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    base::SplitString(data[i].input, ';', &titles);
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBookmarksWithTitles(titles);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<std::string> expected;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!data[i].expected.empty())
144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      base::SplitString(data[i].expected, ';', &expected);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExpectMatches(data[i].query, expected);
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    model_.reset(new BookmarkModel(NULL));
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure match positions are updated appropriately.
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkIndexTest, MatchPositions) {
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct TestData {
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string title;
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string query;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string expected;
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } data[] = {
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Trivial test case of only one term, exact match.
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { "a",                        "A",        "0,1" },
1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { "foo bar",                  "bar",      "4,7" },
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { "fooey bark",               "bar foo",  "0,3:6,9"},
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<std::string> titles;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    titles.push_back(data[i].title);
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBookmarksWithTitles(titles);
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Snippet::MatchPositions expected_matches;
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtractMatchPositions(data[i].expected, &expected_matches);
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExpectMatchPositions(data[i].query, expected_matches);
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    model_.reset(new BookmarkModel(NULL));
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure index is updated when a node is removed.
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkIndexTest, Remove) {
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const char* input[] = { "a", "b" };
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddBookmarksWithTitles(input, ARRAYSIZE_UNSAFE(input));
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Remove the node and make sure we don't get back any results.
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  model_->Remove(model_->other_node(), 0);
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExpectMatches("A", NULL, 0U);
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure index is updated when a node's title is changed.
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkIndexTest, ChangeTitle) {
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const char* input[] = { "a", "b" };
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddBookmarksWithTitles(input, ARRAYSIZE_UNSAFE(input));
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Remove the node and make sure we don't get back any results.
1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const char* expected[] = { "blah" };
1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  model_->SetTitle(model_->other_node()->GetChild(0), ASCIIToUTF16("blah"));
1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExpectMatches("BlAh", expected, ARRAYSIZE_UNSAFE(expected));
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure no more than max queries is returned.
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkIndexTest, HonorMax) {
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const char* input[] = { "abcd", "abcde" };
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddBookmarksWithTitles(input, ARRAYSIZE_UNSAFE(input));
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<bookmark_utils::TitleMatch> matches;
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  model_->GetBookmarksWithTitlesMatching(ASCIIToUTF16("ABc"), 1, &matches);
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1U, matches.size());
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure if the lower case string of a bookmark title is more characters
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// than the upper case string no match positions are returned.
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkIndexTest, EmptyMatchOnMultiwideLowercaseString) {
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const BookmarkNode* n1 = model_->AddURL(model_->other_node(), 0,
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                          WideToUTF16(L"\u0130 i"),
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          GURL("http://www.google.com"));
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<bookmark_utils::TitleMatch> matches;
2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  model_->GetBookmarksWithTitlesMatching(ASCIIToUTF16("i"), 100, &matches);
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1U, matches.size());
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(matches[0].node == n1);
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(matches[0].match_positions.empty());
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkIndexTest, GetResultsSortedByTypedCount) {
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This ensures MessageLoop::current() will exist, which is needed by
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TestingProfile::BlockUntilHistoryProcessesPendingRequests().
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop loop(MessageLoop::TYPE_DEFAULT);
226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread ui_thread(BrowserThread::UI, &loop);
227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread file_thread(BrowserThread::FILE, &loop);
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestingProfile profile;
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile.CreateHistoryService(true, false);
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile.BlockUntilHistoryProcessesPendingRequests();
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile.CreateBookmarkModel(true);
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile.BlockUntilBookmarkModelLoaded();
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkModel* model = profile.GetBookmarkModel();
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HistoryService* const history_service =
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile.GetHistoryService(Profile::EXPLICIT_ACCESS);
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  history::URLDatabase* url_db = history_service->InMemoryDatabase();
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct TestData {
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL url;
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char* title;
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const int typed_count;
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } data[] = {
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { GURL("http://www.google.com/"),      "Google",           100 },
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { GURL("http://maps.google.com/"),     "Google Maps",       40 },
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { GURL("http://docs.google.com/"),     "Google Docs",       50 },
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { GURL("http://reader.google.com/"),   "Google Reader",     80 },
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    history::URLRow info(data[i].url);
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info.set_title(UTF8ToUTF16(data[i].title));
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info.set_typed_count(data[i].typed_count);
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Populate the InMemoryDatabase....
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url_db->AddURL(info);
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Populate the BookmarkIndex.
2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    model->AddURL(model->other_node(), i, UTF8ToUTF16(data[i].title),
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  data[i].url);
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the InMemoryDatabase stored the URLs properly.
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  history::URLRow result1;
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  url_db->GetRowForURL(data[0].url, &result1);
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data[0].title, UTF16ToUTF8(result1.title()));
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  history::URLRow result2;
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  url_db->GetRowForURL(data[1].url, &result2);
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data[1].title, UTF16ToUTF8(result2.title()));
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  history::URLRow result3;
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  url_db->GetRowForURL(data[2].url, &result3);
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data[2].title, UTF16ToUTF8(result3.title()));
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  history::URLRow result4;
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  url_db->GetRowForURL(data[3].url, &result4);
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data[3].title, UTF16ToUTF8(result4.title()));
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Populate match nodes.
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<bookmark_utils::TitleMatch> matches;
2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  model->GetBookmarksWithTitlesMatching(ASCIIToUTF16("google"), 4, &matches);
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The resulting order should be:
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 1. Google (google.com) 100
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 2. Google Reader (google.com/reader) 80
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 3. Google Docs (docs.google.com) 50
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 4. Google Maps (maps.google.com) 40
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(4, static_cast<int>(matches.size()));
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data[0].url, matches[0].node->GetURL());
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data[3].url, matches[1].node->GetURL());
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data[2].url, matches[2].node->GetURL());
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data[1].url, matches[3].node->GetURL());
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  matches.clear();
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Select top two matches.
2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  model->GetBookmarksWithTitlesMatching(ASCIIToUTF16("google"), 2, &matches);
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, static_cast<int>(matches.size()));
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data[0].url, matches[0].node->GetURL());
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data[3].url, matches[1].node->GetURL());
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
305