1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/webui/history_ui.h"
6
7#include "base/strings/utf_string_conversions.h"
8#include "testing/gtest/include/gtest/gtest.h"
9
10namespace {
11
12struct TestResult {
13  std::string url;
14  int64 hour_offset;  // Visit time in hours past the baseline time.
15};
16
17// Duplicates on the same day in the local timezone are removed, so set a
18// baseline time in local time.
19const base::Time baseline_time = base::Time::UnixEpoch().LocalMidnight();
20
21// For each item in |results|, create a new Value representing the visit, and
22// insert it into |list_value|.
23void AddQueryResults(
24    TestResult* test_results,
25    int test_results_size,
26    std::vector<BrowsingHistoryHandler::HistoryEntry>* results) {
27  for (int i = 0; i < test_results_size; ++i) {
28    BrowsingHistoryHandler::HistoryEntry entry;
29    entry.time = baseline_time +
30                 base::TimeDelta::FromHours(test_results[i].hour_offset);
31    entry.url = GURL(test_results[i].url);
32    entry.all_timestamps.insert(entry.time.ToInternalValue());
33    results->push_back(entry);
34  }
35}
36
37// Returns true if |result| matches the test data given by |correct_result|,
38// otherwise returns false.
39bool ResultEquals(
40    const BrowsingHistoryHandler::HistoryEntry& result,
41    const TestResult& correct_result) {
42  base::Time correct_time =
43      baseline_time + base::TimeDelta::FromHours(correct_result.hour_offset);
44
45  return result.time == correct_time && result.url == GURL(correct_result.url);
46}
47
48}  // namespace
49
50// Tests that the MergeDuplicateResults method correctly removes duplicate
51// visits to the same URL on the same day.
52TEST(HistoryUITest, MergeDuplicateResults) {
53  {
54    // Basic test that duplicates on the same day are removed.
55    TestResult test_data[] = {
56      { "http://google.com", 0 },
57      { "http://google.de", 1 },
58      { "http://google.com", 2 },
59      { "http://google.com", 3 }  // Most recent.
60    };
61    std::vector<BrowsingHistoryHandler::HistoryEntry> results;
62    AddQueryResults(test_data, arraysize(test_data), &results);
63    BrowsingHistoryHandler::MergeDuplicateResults(&results);
64
65    ASSERT_EQ(2U, results.size());
66    EXPECT_TRUE(ResultEquals(results[0], test_data[3]));
67    EXPECT_TRUE(ResultEquals(results[1], test_data[1]));
68  }
69
70  {
71    // Test that a duplicate URL on the next day is not removed.
72    TestResult test_data[] = {
73      { "http://google.com", 0 },
74      { "http://google.com", 23 },
75      { "http://google.com", 24 },  // Most recent.
76    };
77    std::vector<BrowsingHistoryHandler::HistoryEntry> results;
78    AddQueryResults(test_data, arraysize(test_data), &results);
79    BrowsingHistoryHandler::MergeDuplicateResults(&results);
80
81    ASSERT_EQ(2U, results.size());
82    EXPECT_TRUE(ResultEquals(results[0], test_data[2]));
83    EXPECT_TRUE(ResultEquals(results[1], test_data[1]));
84  }
85
86  {
87    // Test multiple duplicates across multiple days.
88    TestResult test_data[] = {
89      // First day.
90      { "http://google.de", 0 },
91      { "http://google.com", 1 },
92      { "http://google.de", 2 },
93      { "http://google.com", 3 },
94
95      // Second day.
96      { "http://google.de", 24 },
97      { "http://google.com", 25 },
98      { "http://google.de", 26 },
99      { "http://google.com", 27 },  // Most recent.
100    };
101    std::vector<BrowsingHistoryHandler::HistoryEntry> results;
102    AddQueryResults(test_data, arraysize(test_data), &results);
103    BrowsingHistoryHandler::MergeDuplicateResults(&results);
104
105    ASSERT_EQ(4U, results.size());
106    EXPECT_TRUE(ResultEquals(results[0], test_data[7]));
107    EXPECT_TRUE(ResultEquals(results[1], test_data[6]));
108    EXPECT_TRUE(ResultEquals(results[2], test_data[3]));
109    EXPECT_TRUE(ResultEquals(results[3], test_data[2]));
110  }
111
112  {
113    // Test that timestamps for duplicates are properly saved.
114    TestResult test_data[] = {
115      { "http://google.com", 0 },
116      { "http://google.de", 1 },
117      { "http://google.com", 2 },
118      { "http://google.com", 3 }  // Most recent.
119    };
120    std::vector<BrowsingHistoryHandler::HistoryEntry> results;
121    AddQueryResults(test_data, arraysize(test_data), &results);
122    BrowsingHistoryHandler::MergeDuplicateResults(&results);
123
124    ASSERT_EQ(2U, results.size());
125    EXPECT_TRUE(ResultEquals(results[0], test_data[3]));
126    EXPECT_TRUE(ResultEquals(results[1], test_data[1]));
127    EXPECT_EQ(3u, results[0].all_timestamps.size());
128    EXPECT_EQ(1u, results[1].all_timestamps.size());
129  }
130}
131