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