search_engines_helper.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1// Copyright (c) 2012 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/sync/test/integration/search_engines_helper.h"
6
7#include <vector>
8
9#include "base/strings/string_util.h"
10#include "base/strings/stringprintf.h"
11#include "base/strings/utf_string_conversions.h"
12#include "base/time.h"
13#include "chrome/browser/profiles/profile.h"
14#include "chrome/browser/search_engines/template_url.h"
15#include "chrome/browser/search_engines/template_url_service.h"
16#include "chrome/browser/search_engines/template_url_service_factory.h"
17#include "chrome/browser/sync/profile_sync_service_harness.h"
18#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
19#include "chrome/browser/sync/test/integration/sync_test.h"
20
21using sync_datatype_helper::test;
22
23namespace {
24
25GUIDToTURLMap CreateGUIDToTURLMap(TemplateURLService* service) {
26  CHECK(service);
27
28  GUIDToTURLMap map;
29  TemplateURLService::TemplateURLVector turls = service->GetTemplateURLs();
30  for (TemplateURLService::TemplateURLVector::iterator it = turls.begin();
31       it != turls.end(); ++it) {
32    CHECK(*it);
33    CHECK(map.find((*it)->sync_guid()) == map.end());
34    map[(*it)->sync_guid()] = *it;
35  }
36
37  return map;
38}
39
40std::string GetTURLInfoString(const TemplateURL* turl) {
41  DCHECK(turl);
42  return "TemplateURL: shortname: " + UTF16ToASCII(turl->short_name()) +
43      " keyword: " + UTF16ToASCII(turl->keyword()) + " url: " + turl->url();
44}
45
46bool TURLsMatch(const TemplateURL* turl1, const TemplateURL* turl2) {
47  CHECK(turl1);
48  CHECK(turl2);
49  bool result = (turl1->url() == turl2->url()) &&
50      (turl1->keyword() == turl2->keyword()) &&
51      (turl1->short_name() == turl2->short_name());
52
53  // Print some useful debug info.
54  if (!result) {
55    LOG(ERROR) << "TemplateURLs did not match: " << GetTURLInfoString(turl1)
56               << " vs " << GetTURLInfoString(turl2);
57  }
58
59  return result;
60}
61
62bool ServicesMatch(int profile_a, int profile_b) {
63  TemplateURLService* service_a =
64      search_engines_helper::GetServiceForBrowserContext(profile_a);
65  TemplateURLService* service_b =
66      search_engines_helper::GetServiceForBrowserContext(profile_b);
67  CHECK(service_a);
68  CHECK(service_b);
69
70  // Services that have synced should have identical TURLs, including the GUIDs.
71  // Make sure we compare those fields in addition to the user-visible fields.
72  GUIDToTURLMap a_turls = CreateGUIDToTURLMap(service_a);
73  GUIDToTURLMap b_turls = CreateGUIDToTURLMap(service_b);
74
75  if (a_turls.size() != b_turls.size()) {
76    LOG(ERROR) << "Service a and b do not match in size: " << a_turls.size()
77               << " vs " << b_turls.size() << " respectively.";
78    return false;
79  }
80
81  for (GUIDToTURLMap::iterator it = a_turls.begin();
82       it != a_turls.end(); ++it) {
83    if (b_turls.find(it->first) == b_turls.end()) {
84      LOG(ERROR) << "TURL GUID from a not found in b's TURLs: " << it->first;
85      return false;
86    }
87    if (!TURLsMatch(b_turls[it->first], it->second))
88      return false;
89  }
90
91  const TemplateURL* default_a = service_a->GetDefaultSearchProvider();
92  const TemplateURL* default_b = service_b->GetDefaultSearchProvider();
93  CHECK(default_a);
94  CHECK(default_b);
95  if (!TURLsMatch(default_a, default_b)) {
96    LOG(ERROR) << "Default search providers do not match: A's default: "
97               << default_a->keyword() << " B's default: "
98               << default_b->keyword();
99    return false;
100  } else {
101    LOG(INFO) << "A had default with URL: " << default_a->url()
102              << " and keyword: " << default_a->keyword();
103  }
104
105  return true;
106}
107
108// Convenience helper for consistently generating the same keyword for a given
109// seed.
110string16 CreateKeyword(int seed) {
111  return ASCIIToUTF16(base::StringPrintf("test%d", seed));
112}
113
114}  // namespace
115
116namespace search_engines_helper {
117
118TemplateURLService* GetServiceForBrowserContext(int profile_index) {
119  return TemplateURLServiceFactory::GetForProfile(
120      test()->GetProfile(profile_index));
121}
122
123TemplateURLService* GetVerifierService() {
124  return TemplateURLServiceFactory::GetForProfile(test()->verifier());
125}
126
127bool ServiceMatchesVerifier(int profile_index) {
128  TemplateURLService* verifier = GetVerifierService();
129  TemplateURLService* other = GetServiceForBrowserContext(profile_index);
130
131  CHECK(verifier);
132  CHECK(other);
133
134  TemplateURLService::TemplateURLVector verifier_turls =
135      verifier->GetTemplateURLs();
136  if (verifier_turls.size() != other->GetTemplateURLs().size()) {
137    LOG(ERROR) << "Verifier and other service have a different count of TURLs: "
138               << verifier_turls.size() << " vs "
139               << other->GetTemplateURLs().size() << " respectively.";
140    return false;
141  }
142
143  for (size_t i = 0; i < verifier_turls.size(); ++i) {
144    const TemplateURL* verifier_turl = verifier_turls.at(i);
145    CHECK(verifier_turl);
146    const TemplateURL* other_turl = other->GetTemplateURLForKeyword(
147        verifier_turl->keyword());
148
149    if (!other_turl) {
150      LOG(ERROR) << "The other service did not contain a TURL with keyword: "
151                 << verifier_turl->keyword();
152      return false;
153    }
154    if (!TURLsMatch(verifier_turl, other_turl))
155      return false;
156  }
157
158  return true;
159}
160
161bool AllServicesMatch() {
162  // Use 0 as the baseline.
163  if (test()->use_verifier() && !ServiceMatchesVerifier(0)) {
164    LOG(ERROR) << "TemplateURLService 0 does not match verifier.";
165    return false;
166  }
167
168  for (int it = 1; it < test()->num_clients(); ++it) {
169    if (!ServicesMatch(0, it)) {
170      LOG(ERROR) << "TemplateURLService " << it << " does not match with "
171                 << "service 0.";
172      return false;
173    }
174  }
175  return true;
176}
177
178TemplateURL* CreateTestTemplateURL(Profile* profile, int seed) {
179  return CreateTestTemplateURL(profile, seed, CreateKeyword(seed),
180                               base::StringPrintf("0000-0000-0000-%04d", seed));
181}
182
183TemplateURL* CreateTestTemplateURL(Profile* profile,
184                                   int seed,
185                                   const string16& keyword,
186                                   const std::string& sync_guid) {
187  return CreateTestTemplateURL(profile, seed, keyword,
188      base::StringPrintf("http://www.test%d.com/", seed), sync_guid);
189}
190
191TemplateURL* CreateTestTemplateURL(Profile* profile,
192                                   int seed,
193                                   const string16& keyword,
194                                   const std::string& url,
195                                   const std::string& sync_guid) {
196  TemplateURLData data;
197  data.short_name = CreateKeyword(seed);
198  data.SetKeyword(keyword);
199  data.SetURL(url);
200  data.favicon_url = GURL("http://favicon.url");
201  data.safe_for_autoreplace = true;
202  data.date_created = base::Time::FromTimeT(100);
203  data.last_modified = base::Time::FromTimeT(100);
204  data.prepopulate_id = 999999;
205  data.sync_guid = sync_guid;
206  return new TemplateURL(profile, data);
207}
208
209void AddSearchEngine(int profile_index, int seed) {
210  Profile* profile = test()->GetProfile(profile_index);
211  TemplateURLServiceFactory::GetForProfile(profile)->Add(
212      CreateTestTemplateURL(profile, seed));
213  if (test()->use_verifier())
214    GetVerifierService()->Add(CreateTestTemplateURL(profile, seed));
215}
216
217void EditSearchEngine(int profile_index,
218                      const string16& keyword,
219                      const string16& short_name,
220                      const string16& new_keyword,
221                      const std::string& url) {
222  DCHECK(!url.empty());
223  TemplateURLService* service = GetServiceForBrowserContext(profile_index);
224  TemplateURL* turl = service->GetTemplateURLForKeyword(keyword);
225  EXPECT_TRUE(turl);
226  ASSERT_FALSE(new_keyword.empty());
227  service->ResetTemplateURL(turl, short_name, new_keyword, url);
228  // Make sure we do the same on the verifier.
229  if (test()->use_verifier()) {
230    TemplateURL* verifier_turl =
231        GetVerifierService()->GetTemplateURLForKeyword(keyword);
232    EXPECT_TRUE(verifier_turl);
233    GetVerifierService()->ResetTemplateURL(verifier_turl, short_name,
234                                           new_keyword, url);
235  }
236}
237
238void DeleteSearchEngineBySeed(int profile_index, int seed) {
239  TemplateURLService* service = GetServiceForBrowserContext(profile_index);
240  string16 keyword(CreateKeyword(seed));
241  TemplateURL* turl = service->GetTemplateURLForKeyword(keyword);
242  EXPECT_TRUE(turl);
243  service->Remove(turl);
244  // Make sure we do the same on the verifier.
245  if (test()->use_verifier()) {
246    TemplateURL* verifier_turl =
247        GetVerifierService()->GetTemplateURLForKeyword(keyword);
248    EXPECT_TRUE(verifier_turl);
249    GetVerifierService()->Remove(verifier_turl);
250  }
251}
252
253void ChangeDefaultSearchProvider(int profile_index, int seed) {
254  TemplateURLService* service = GetServiceForBrowserContext(profile_index);
255  ASSERT_TRUE(service);
256  TemplateURL* turl = service->GetTemplateURLForKeyword(CreateKeyword(seed));
257  ASSERT_TRUE(turl);
258  service->SetDefaultSearchProvider(turl);
259  if (test()->use_verifier()) {
260    TemplateURL* verifier_turl =
261        GetVerifierService()->GetTemplateURLForKeyword(CreateKeyword(seed));
262    ASSERT_TRUE(verifier_turl);
263    GetVerifierService()->SetDefaultSearchProvider(verifier_turl);
264  }
265}
266
267}  // namespace search_engines_helper
268