1// Copyright 2014 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 "components/suggestions/blacklist_store.h"
6
7#include <set>
8#include <string>
9
10#include "base/memory/scoped_ptr.h"
11
12#include "base/test/histogram_tester.h"
13#include "components/pref_registry/testing_pref_service_syncable.h"
14#include "components/suggestions/proto/suggestions.pb.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17using user_prefs::TestingPrefServiceSyncable;
18
19namespace suggestions {
20
21namespace {
22
23const char kTestUrlA[] = "http://aaa.com/";
24const char kTestUrlB[] = "http://bbb.com/";
25const char kTestUrlC[] = "http://ccc.com/";
26const char kTestUrlD[] = "http://ddd.com/";
27
28SuggestionsProfile CreateSuggestions(std::set<std::string> urls) {
29  SuggestionsProfile suggestions;
30  for (std::set<std::string>::iterator it = urls.begin(); it != urls.end();
31       ++it) {
32    ChromeSuggestion* suggestion = suggestions.add_suggestions();
33    suggestion->set_url(*it);
34  }
35  return suggestions;
36}
37
38void ValidateSuggestions(const SuggestionsProfile& expected,
39                         const SuggestionsProfile& actual) {
40  ASSERT_EQ(expected.suggestions_size(), actual.suggestions_size());
41  for (int i = 0; i < expected.suggestions_size(); ++i) {
42    EXPECT_EQ(expected.suggestions(i).url(), actual.suggestions(i).url());
43    EXPECT_EQ(expected.suggestions(i).title(), actual.suggestions(i).title());
44    EXPECT_EQ(expected.suggestions(i).favicon_url(),
45              actual.suggestions(i).favicon_url());
46    EXPECT_EQ(expected.suggestions(i).thumbnail(),
47              actual.suggestions(i).thumbnail());
48  }
49}
50
51}  // namespace
52
53class BlacklistStoreTest : public testing::Test {
54 public:
55  BlacklistStoreTest()
56    : pref_service_(new user_prefs::TestingPrefServiceSyncable) {}
57
58  virtual void SetUp() OVERRIDE {
59    BlacklistStore::RegisterProfilePrefs(pref_service()->registry());
60  }
61
62  user_prefs::TestingPrefServiceSyncable* pref_service() {
63    return pref_service_.get();
64  }
65
66 private:
67  scoped_ptr<user_prefs::TestingPrefServiceSyncable> pref_service_;
68
69  DISALLOW_COPY_AND_ASSIGN(BlacklistStoreTest);
70};
71
72TEST_F(BlacklistStoreTest, BasicInteractions) {
73  BlacklistStore blacklist_store(pref_service());
74
75  // Create suggestions with A, B and C. C and D will be added to the blacklist.
76  std::set<std::string> suggested_urls;
77  suggested_urls.insert(kTestUrlA);
78  suggested_urls.insert(kTestUrlB);
79  const SuggestionsProfile suggestions_filtered =
80      CreateSuggestions(suggested_urls);
81  suggested_urls.insert(kTestUrlC);
82  const SuggestionsProfile original_suggestions =
83      CreateSuggestions(suggested_urls);
84  SuggestionsProfile suggestions;
85
86  // Filter with an empty blacklist.
87  suggestions.CopyFrom(original_suggestions);
88  blacklist_store.FilterSuggestions(&suggestions);
89  ValidateSuggestions(original_suggestions, suggestions);
90
91  // Add C and D to the blacklist and filter.
92  suggestions.CopyFrom(original_suggestions);
93  EXPECT_TRUE(blacklist_store.BlacklistUrl(GURL(kTestUrlC)));
94  EXPECT_TRUE(blacklist_store.BlacklistUrl(GURL(kTestUrlD)));
95  blacklist_store.FilterSuggestions(&suggestions);
96  ValidateSuggestions(suggestions_filtered, suggestions);
97
98  // Remove C from the blacklist and filter.
99  suggestions.CopyFrom(original_suggestions);
100  EXPECT_TRUE(blacklist_store.RemoveUrl(GURL(kTestUrlC)));
101  blacklist_store.FilterSuggestions(&suggestions);
102  ValidateSuggestions(original_suggestions, suggestions);
103}
104
105TEST_F(BlacklistStoreTest, BlacklistTwiceSuceeds) {
106  BlacklistStore blacklist_store(pref_service());
107  EXPECT_TRUE(blacklist_store.BlacklistUrl(GURL(kTestUrlA)));
108  EXPECT_TRUE(blacklist_store.BlacklistUrl(GURL(kTestUrlA)));
109}
110
111TEST_F(BlacklistStoreTest, RemoveUnknownUrlSucceeds) {
112  BlacklistStore blacklist_store(pref_service());
113  EXPECT_TRUE(blacklist_store.RemoveUrl(GURL(kTestUrlA)));
114}
115
116TEST_F(BlacklistStoreTest, GetFirstUrlFromBlacklist) {
117  BlacklistStore blacklist_store(pref_service());
118
119  // Expect GetFirstUrlFromBlacklist fails when blacklist empty.
120  GURL retrieved;
121  EXPECT_FALSE(blacklist_store.GetFirstUrlFromBlacklist(&retrieved));
122
123  // Blacklist A and B.
124  EXPECT_TRUE(blacklist_store.BlacklistUrl(GURL(kTestUrlA)));
125  EXPECT_TRUE(blacklist_store.BlacklistUrl(GURL(kTestUrlB)));
126
127  // Expect to retrieve A or B.
128  EXPECT_TRUE(blacklist_store.GetFirstUrlFromBlacklist(&retrieved));
129  std::string retrieved_string = retrieved.spec();
130  EXPECT_TRUE(retrieved_string == std::string(kTestUrlA) ||
131              retrieved_string == std::string(kTestUrlB));
132}
133
134TEST_F(BlacklistStoreTest, LogsBlacklistSize) {
135  base::HistogramTester histogram_tester;
136
137  // Create a first store - blacklist is empty at this point.
138  scoped_ptr<BlacklistStore> blacklist_store(
139      new BlacklistStore(pref_service()));
140
141  histogram_tester.ExpectTotalCount("Suggestions.LocalBlacklistSize", 1);
142  histogram_tester.ExpectUniqueSample("Suggestions.LocalBlacklistSize", 0, 1);
143
144  // Add some content to the blacklist.
145  EXPECT_TRUE(blacklist_store->BlacklistUrl(GURL(kTestUrlA)));
146  EXPECT_TRUE(blacklist_store->BlacklistUrl(GURL(kTestUrlB)));
147
148  // Create a new BlacklistStore and verify the counts.
149  blacklist_store.reset(new BlacklistStore(pref_service()));
150
151  histogram_tester.ExpectTotalCount("Suggestions.LocalBlacklistSize", 2);
152  histogram_tester.ExpectBucketCount("Suggestions.LocalBlacklistSize", 0, 1);
153  histogram_tester.ExpectBucketCount("Suggestions.LocalBlacklistSize", 2, 1);
154}
155
156}  // namespace suggestions
157