15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/message_loop/message_loop.h"
8a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/run_loop.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/search_engines/template_url_service_test_util.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/testing_pref_service_syncable.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/search_engines_pref_names.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/search_engines/search_terms_data.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url_prepopulate_data.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url_service.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url_service_client.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "sync/api/sync_change_processor_wrapper_for_test.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/sync_error_factory.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/sync_error_factory_mock.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/search_engine_specifics.pb.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/sync.pb.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16;
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UTF8ToUTF16;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Extract the GUID from a search engine syncer::SyncData.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetGUID(const syncer::SyncData& sync_data) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sync_data.GetSpecifics().search_engine().sync_guid();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Extract the URL from a search engine syncer::SyncData.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetURL(const syncer::SyncData& sync_data) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sync_data.GetSpecifics().search_engine().url();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Extract the keyword from a search engine syncer::SyncData.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetKeyword(const syncer::SyncData& sync_data) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sync_data.GetSpecifics().search_engine().keyword();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Much like TemplateURLService::CreateSyncDataFromTemplateURL(), but allows the
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// caller to override the keyword, URL, or GUID fields with empty strings, in
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// order to create custom data that should be handled specially when synced to a
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// client.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncData CreateCustomSyncData(const TemplateURL& turl,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool autogenerate_keyword,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const std::string& url,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const std::string& sync_guid) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EntitySpecifics specifics;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::SearchEngineSpecifics* se_specifics =
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      specifics.mutable_search_engine();
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  se_specifics->set_short_name(base::UTF16ToUTF8(turl.short_name()));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_keyword(
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      autogenerate_keyword ? std::string() : base::UTF16ToUTF8(turl.keyword()));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_favicon_url(turl.favicon_url().spec());
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_url(url);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_safe_for_autoreplace(turl.safe_for_autoreplace());
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_originating_url(turl.originating_url().spec());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_date_created(turl.date_created().ToInternalValue());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_input_encodings(JoinString(turl.input_encodings(), ';'));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_show_in_default_list(turl.show_in_default_list());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_suggestions_url(turl.suggestions_url());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_prepopulate_id(turl.prepopulate_id());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_autogenerate_keyword(autogenerate_keyword);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_instant_url(turl.instant_url());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_last_modified(turl.last_modified().ToInternalValue());
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  se_specifics->set_sync_guid(sync_guid);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return syncer::SyncData::CreateLocalData(turl.sync_guid(),  // Must be valid!
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   se_specifics->keyword(), specifics);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TestChangeProcessor --------------------------------------------------------
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Dummy SyncChangeProcessor used to help review what SyncChanges are pushed
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// back up to Sync.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestChangeProcessor : public syncer::SyncChangeProcessor {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestChangeProcessor();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestChangeProcessor();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Store a copy of all the changes passed in so we can examine them later.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual syncer::SyncError ProcessSyncChanges(
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const tracked_objects::Location& from_here,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const syncer::SyncChangeList& change_list) OVERRIDE;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      OVERRIDE {
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return syncer::SyncDataList();
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool contains_guid(const std::string& guid) const {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return change_map_.count(guid) != 0;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange change_for_guid(const std::string& guid) const {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(contains_guid(guid));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return change_map_.find(guid)->second;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t change_list_size() { return change_map_.size(); }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_erroneous(bool erroneous) { erroneous_ = erroneous; }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Track the changes received in ProcessSyncChanges.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<std::string, syncer::SyncChange> change_map_;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool erroneous_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestChangeProcessor);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestChangeProcessor::TestChangeProcessor() : erroneous_(false) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestChangeProcessor::~TestChangeProcessor() {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncError TestChangeProcessor::ProcessSyncChanges(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const tracked_objects::Location& from_here,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncChangeList& change_list) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (erroneous_)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return syncer::SyncError(
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        syncer::SyncError::DATATYPE_ERROR,
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "Some error.",
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        syncer::SEARCH_ENGINES);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_map_.erase(change_map_.begin(), change_map_.end());
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::SyncChangeList::const_iterator iter = change_list.begin();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter != change_list.end(); ++iter)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    change_map_[GetGUID(iter->sync_data())] = *iter;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return syncer::SyncError();
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TemplateURLServiceSyncTest -------------------------------------------------
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TemplateURLServiceSyncTest : public testing::Test {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef TemplateURLService::SyncDataMap SyncDataMap;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURLServiceSyncTest();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TemplateURLService* model() { return test_util_a_->model(); }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For readability, we redefine an accessor for Model A for use in tests that
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // involve syncing two models.
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TemplateURLService* model_a() { return test_util_a_->model(); }
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TemplateURLService* model_b() { return test_util_b_->model(); }
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestingProfile* profile_a() { return test_util_a_->profile(); }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestChangeProcessor* processor() { return sync_processor_.get(); }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<syncer::SyncChangeProcessor> PassProcessor();
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<syncer::SyncErrorFactory> CreateAndPassSyncErrorFactory();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Creates a TemplateURL with some test values. The caller owns the returned
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TemplateURL*.
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TemplateURL* CreateTestTemplateURL(const base::string16& keyword,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const std::string& url,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const std::string& guid = std::string(),
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     time_t last_mod = 100,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bool safe_for_autoreplace = false,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bool created_by_policy = false) const;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verifies the two TemplateURLs are equal.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(stevet): Share this with TemplateURLServiceTest.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AssertEquals(const TemplateURL& expected,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const TemplateURL& actual) const;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Expect that two syncer::SyncDataLists have equal contents, in terms of the
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sync_guid, keyword, and url fields.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AssertEquals(const syncer::SyncDataList& data1,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const syncer::SyncDataList& data2) const;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convenience helper for creating SyncChanges. Takes ownership of |turl|.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange CreateTestSyncChange(
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      syncer::SyncChange::SyncChangeType type,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TemplateURL* turl) const;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper that creates some initial sync data. We cheat a little by specifying
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GUIDs for easy identification later. We also make the last_modified times
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // slightly older than CreateTestTemplateURL's default, to test conflict
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // resolution.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList CreateInitialSyncData() const;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Syntactic sugar.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* Deserialize(const syncer::SyncData& sync_data);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Creates a new TemplateURL copying the fields of |turl| but replacing
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the |url| and |guid| and initializing the date_created and last_modified
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // timestamps to a default value of 100. The caller owns the returned
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TemplateURL*.
2075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  TemplateURL* CopyTemplateURL(const TemplateURLData* turl,
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const std::string& url,
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const std::string& guid);
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::MessageLoop message_loop_;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We keep two TemplateURLServices to test syncing between them.
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<TemplateURLServiceTestUtil> test_util_a_;
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<TemplateURLServiceTestUtil> test_util_b_;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our dummy ChangeProcessor used to inspect changes pushed to Sync.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestChangeProcessor> sync_processor_;
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> sync_processor_wrapper_;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TemplateURLServiceSyncTest);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TemplateURLServiceSyncTest::TemplateURLServiceSyncTest()
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : sync_processor_(new TestChangeProcessor),
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest(
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          sync_processor_.get())) {}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TemplateURLServiceSyncTest::SetUp() {
230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DefaultSearchManager::SetFallbackSearchEnginesDisabledForTesting(true);
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  test_util_a_.reset(new TemplateURLServiceTestUtil);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use ChangeToLoadState() instead of VerifyLoad() so we don't actually pull
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the prepopulate data, which the sync tests don't care about (and would
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just foul them up).
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  test_util_a_->ChangeModelToLoadState();
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  test_util_b_.reset(new TemplateURLServiceTestUtil);
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  test_util_b_->VerifyLoad();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TemplateURLServiceSyncTest::TearDown() {
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  test_util_a_.reset();
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DefaultSearchManager::SetFallbackSearchEnginesDisabledForTesting(false);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<syncer::SyncChangeProcessor>
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TemplateURLServiceSyncTest::PassProcessor() {
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<syncer::SyncErrorFactory> TemplateURLServiceSyncTest::
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateAndPassSyncErrorFactory() {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return scoped_ptr<syncer::SyncErrorFactory>(
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new syncer::SyncErrorFactoryMock());
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TemplateURL* TemplateURLServiceSyncTest::CreateTestTemplateURL(
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& keyword,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& url,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& guid,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    time_t last_mod,
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool safe_for_autoreplace,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool created_by_policy) const {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURLData data;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.short_name = ASCIIToUTF16("unittest");
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.SetKeyword(keyword);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.SetURL(url);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.favicon_url = GURL("http://favicon.url");
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.safe_for_autoreplace = safe_for_autoreplace;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.date_created = Time::FromTimeT(100);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.last_modified = Time::FromTimeT(last_mod);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.created_by_policy = created_by_policy;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.prepopulate_id = 999999;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!guid.empty())
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data.sync_guid = guid;
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return new TemplateURL(data);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TemplateURLServiceSyncTest::AssertEquals(const TemplateURL& expected,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const TemplateURL& actual) const {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(expected.short_name(), actual.short_name());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(expected.keyword(), actual.keyword());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(expected.url(), actual.url());
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(expected.suggestions_url(), actual.suggestions_url());
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(expected.favicon_url(), actual.favicon_url());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(expected.show_in_default_list(), actual.show_in_default_list());
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(expected.safe_for_autoreplace(), actual.safe_for_autoreplace());
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(expected.input_encodings(), actual.input_encodings());
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(expected.date_created(), actual.date_created());
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(expected.last_modified(), actual.last_modified());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TemplateURLServiceSyncTest::AssertEquals(
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncDataList& data1,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncDataList& data2) const {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncDataMap map1 = TemplateURLService::CreateGUIDToSyncDataMap(data1);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncDataMap map2 = TemplateURLService::CreateGUIDToSyncDataMap(data2);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (SyncDataMap::const_iterator iter1 = map1.begin();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter1 != map1.end(); iter1++) {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SyncDataMap::iterator iter2 = map2.find(iter1->first);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter2 != map2.end()) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(GetKeyword(iter1->second), GetKeyword(iter2->second));
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(GetURL(iter1->second), GetURL(iter2->second));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      map2.erase(iter2);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, map2.size());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncChange TemplateURLServiceSyncTest::CreateTestSyncChange(
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::SyncChange::SyncChangeType type,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TemplateURL* turl) const {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We take control of the TemplateURL so make sure it's cleaned up after
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we create data out of it.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> scoped_turl(turl);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return syncer::SyncChange(
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TemplateURLService::CreateSyncDataFromTemplateURL(*scoped_turl));
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncDataList TemplateURLServiceSyncTest::CreateInitialSyncData() const {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList list;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(CreateTestTemplateURL(ASCIIToUTF16("key1"),
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key1.com", "key1", 90));
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(*turl));
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  turl.reset(CreateTestTemplateURL(ASCIIToUTF16("key2"), "http://key2.com",
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "key2", 90));
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(*turl));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  turl.reset(CreateTestTemplateURL(ASCIIToUTF16("key3"), "http://key3.com",
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "key3", 90));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(*turl));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return list;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TemplateURL* TemplateURLServiceSyncTest::Deserialize(
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncData& sync_data) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList dummy;
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return TemplateURLService::CreateTemplateURLFromTemplateURLAndSyncData(
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      NULL, SearchTermsData(), NULL, sync_data, &dummy);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TemplateURL* TemplateURLServiceSyncTest::CopyTemplateURL(
3475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const TemplateURLData* turl,
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& url,
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& guid) {
3505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  TemplateURLData data = *turl;
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.SetURL(url);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.date_created = Time::FromTimeT(100);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.last_modified = Time::FromTimeT(100);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.sync_guid = guid;
355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return new TemplateURL(data);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Actual tests ---------------------------------------------------------------
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, SerializeDeserialize) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a TemplateURL and convert it into a sync specific type.
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ASCIIToUTF16("unittest"), "http://www.unittest.com/"));
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncData sync_data =
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TemplateURLService::CreateSyncDataFromTemplateURL(*turl);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert the specifics back to a TemplateURL.
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> deserialized(Deserialize(sync_data));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(deserialized.get());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the original and the deserialized TURLs are equal in values.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AssertEquals(*turl, *deserialized);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, GetAllSyncDataBasic) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key1.com"));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key2"), "http://key2.com"));
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key3"), "http://key3.com"));
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList all_sync_data =
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model()->GetAllSyncData(syncer::SEARCH_ENGINES);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, all_sync_data.size());
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::SyncDataList::const_iterator iter = all_sync_data.begin();
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter != all_sync_data.end(); ++iter) {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string guid = GetGUID(*iter);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TemplateURL* service_turl = model()->GetTemplateURLForGUID(guid);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<TemplateURL> deserialized(Deserialize(*iter));
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AssertEquals(*service_turl, *deserialized);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, GetAllSyncDataWithExtension) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key1.com"));
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key2"), "http://key2.com"));
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  model()->RegisterOmniboxKeyword("blahblahblah", "unittest", "key3",
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  "http://blahblahblah");
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList all_sync_data =
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model()->GetAllSyncData(syncer::SEARCH_ENGINES);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(3U, all_sync_data.size());
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::SyncDataList::const_iterator iter = all_sync_data.begin();
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter != all_sync_data.end(); ++iter) {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string guid = GetGUID(*iter);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TemplateURL* service_turl = model()->GetTemplateURLForGUID(guid);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<TemplateURL> deserialized(Deserialize(*iter));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AssertEquals(*service_turl, *deserialized);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, GetAllSyncDataNoManagedEngines) {
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key1.com"));
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key2"), "http://key2.com"));
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* managed_turl = CreateTestTemplateURL(ASCIIToUTF16("key3"),
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key3.com", std::string(), 100, false, true);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(managed_turl);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList all_sync_data =
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model()->GetAllSyncData(syncer::SEARCH_ENGINES);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, all_sync_data.size());
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::SyncDataList::const_iterator iter = all_sync_data.begin();
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter != all_sync_data.end(); ++iter) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string guid = GetGUID(*iter);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TemplateURL* service_turl = model()->GetTemplateURLForGUID(guid);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<TemplateURL> deserialized(Deserialize(*iter));
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(service_turl->created_by_policy());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AssertEquals(*service_turl, *deserialized);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, UniquifyKeyword) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key1.com"));
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a key that conflicts with something in the model.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(CreateTestTemplateURL(ASCIIToUTF16("key1"),
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     "http://new.com", "xyz"));
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 new_keyword = model()->UniquifyKeyword(*turl, false);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("new.com"), new_keyword);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(new_keyword));
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("new.com"), "http://new.com",
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "xyz"));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test a second collision. This time it should be resolved by actually
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // modifying the original keyword, since the autogenerated keyword is already
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // used.
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  turl.reset(CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://new.com"));
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_keyword = model()->UniquifyKeyword(*turl, false);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("key1_"), new_keyword);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(new_keyword));
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key1_"), "http://new.com"));
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test a third collision. This should collide on both the autogenerated
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // keyword and the first uniquification attempt.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  turl.reset(CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://new.com"));
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_keyword = model()->UniquifyKeyword(*turl, false);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("key1__"), new_keyword);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(new_keyword));
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we force the method, it should uniquify the keyword even if it is
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // currently unique, and skip the host-based autogenerated keyword.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  turl.reset(
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("unique"), "http://unique.com"));
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_keyword = model()->UniquifyKeyword(*turl, true);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("unique_"), new_keyword);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(new_keyword));
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, IsLocalTemplateURLBetter) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test some edge cases of this function.
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    time_t local_time;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    time_t sync_time;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool local_is_default;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool local_created_by_policy;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool expected_result;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } test_cases[] = {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sync is better by timestamp but local is Default.
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {10, 100, true, false, true},
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sync is better by timestamp but local is Create by Policy.
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {10, 100, false, true, true},
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tie. Sync wins.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {100, 100, false, false, false},
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TemplateURL* local_turl = CreateTestTemplateURL(
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ASCIIToUTF16("localkey"), "www.local.com", "localguid",
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        test_cases[i].local_time, true, test_cases[i].local_created_by_policy);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model()->Add(local_turl);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_cases[i].local_is_default)
4915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      model()->SetUserSelectedDefaultSearchProvider(local_turl);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<TemplateURL> sync_turl(CreateTestTemplateURL(
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ASCIIToUTF16("synckey"), "www.sync.com", "syncguid",
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_cases[i].sync_time));
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(test_cases[i].expected_result,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        model()->IsLocalTemplateURLBetter(local_turl, sync_turl.get()));
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Undo the changes.
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_cases[i].local_is_default)
5015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      model()->SetUserSelectedDefaultSearchProvider(NULL);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model()->Remove(local_turl);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, ResolveSyncKeywordConflict) {
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This tests cases where neither the sync nor the local TemplateURL are
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // marked safe_for_autoreplace.
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a keyword that conflicts, and make it older.  Sync keyword is
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // uniquified, and a syncer::SyncChange is added.
512a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 original_turl_keyword = ASCIIToUTF16("key1");
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* original_turl = CreateTestTemplateURL(original_turl_keyword,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key1.com", std::string(), 9000);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(original_turl);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> sync_turl(CreateTestTemplateURL(original_turl_keyword,
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://new.com", "remote", 8999));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ResolveSyncKeywordConflict(sync_turl.get(), original_turl, &changes);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(original_turl_keyword, sync_turl->keyword());
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_turl_keyword, original_turl->keyword());
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, changes.size());
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("remote", GetGUID(changes[0].sync_data()));
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.clear();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Remove(original_turl);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sync is newer.  Original TemplateURL keyword is uniquified.  A SyncChange
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is added (which in a normal run would be deleted by PruneSyncChanges() when
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the local GUID doesn't appear in the sync GUID list).  Also ensure that
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this does not change the safe_for_autoreplace flag or the TemplateURLID in
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the original.
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  original_turl = CreateTestTemplateURL(original_turl_keyword,
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        "http://key1.com", "local", 9000);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(original_turl);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURLID original_id = original_turl->id();
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_turl.reset(CreateTestTemplateURL(original_turl_keyword, "http://new.com",
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        std::string(), 9001));
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ResolveSyncKeywordConflict(sync_turl.get(), original_turl, &changes);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_turl_keyword, sync_turl->keyword());
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(original_turl_keyword, original_turl->keyword());
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(original_turl->safe_for_autoreplace());
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_id, original_turl->id());
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(original_turl_keyword));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, changes.size());
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("local", GetGUID(changes[0].sync_data()));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.clear();
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Remove(original_turl);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Equal times. Same result as above. Sync left alone, original uniquified so
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sync_turl can fit.
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  original_turl = CreateTestTemplateURL(original_turl_keyword,
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        "http://key1.com", "local2", 9000);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(original_turl);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_turl.reset(CreateTestTemplateURL(original_turl_keyword, "http://new.com",
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        std::string(), 9000));
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ResolveSyncKeywordConflict(sync_turl.get(), original_turl, &changes);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_turl_keyword, sync_turl->keyword());
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(original_turl_keyword, original_turl->keyword());
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(original_turl_keyword));
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, changes.size());
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("local2", GetGUID(changes[0].sync_data()));
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.clear();
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Remove(original_turl);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sync is newer, but original TemplateURL is created by policy, so it wins.
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sync keyword is uniquified, and a syncer::SyncChange is added.
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  original_turl = CreateTestTemplateURL(original_turl_keyword,
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key1.com", std::string(), 9000, false, true);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(original_turl);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_turl.reset(CreateTestTemplateURL(original_turl_keyword, "http://new.com",
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        "remote2", 9999));
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ResolveSyncKeywordConflict(sync_turl.get(), original_turl, &changes);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(original_turl_keyword, sync_turl->keyword());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_turl_keyword, original_turl->keyword());
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(sync_turl->keyword()));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, changes.size());
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("remote2", GetGUID(changes[0].sync_data()));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.clear();
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Remove(original_turl);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, StartSyncEmpty) {
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      syncer::SEARCH_ENGINES, syncer::SyncDataList(),
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, processor()->change_list_size());
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_before_association());
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_after_association());
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeIntoEmpty) {
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data = CreateInitialSyncData();
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES, initial_data,
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We expect the model to have accepted all of the initial sync data. Search
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // through the model using the GUIDs to ensure that they're present.
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::SyncDataList::const_iterator iter = initial_data.begin();
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter != initial_data.end(); ++iter) {
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string guid = GetGUID(*iter);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(model()->GetTemplateURLForGUID(guid));
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, processor()->change_list_size());
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Locally the three new TemplateURL's should have been added.
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, merge_result.num_items_added());
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_before_association());
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, merge_result.num_items_after_association());
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeInAllNewData) {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("abc.com"), "http://abc.com",
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "abc"));
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("def.com"), "http://def.com",
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "def"));
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("xyz.com"), "http://xyz.com",
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "xyz"));
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data = CreateInitialSyncData();
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES, initial_data,
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We expect the model to have accepted all of the initial sync data. Search
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // through the model using the GUIDs to ensure that they're present.
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::SyncDataList::const_iterator iter = initial_data.begin();
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter != initial_data.end(); ++iter) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string guid = GetGUID(*iter);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(model()->GetTemplateURLForGUID(guid));
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All the original TemplateURLs should also remain in the model.
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("abc.com")));
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("def.com")));
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("xyz.com")));
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that Sync received the expected changes.
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, processor()->change_list_size());
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(processor()->contains_guid("abc"));
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(processor()->contains_guid("def"));
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(processor()->contains_guid("xyz"));
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Locally the three new TemplateURL's should have been added.
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, merge_result.num_items_added());
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, merge_result.num_items_before_association());
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(6, merge_result.num_items_after_association());
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeSyncIsTheSame) {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The local data is the same as the sync data merged in. i.e. - There have
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // been no changes since the last time we synced. Even the last_modified
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // timestamps are the same.
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data = CreateInitialSyncData();
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::SyncDataList::const_iterator iter = initial_data.begin();
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter != initial_data.end(); ++iter) {
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TemplateURL* converted = Deserialize(*iter);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model()->Add(converted);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES, initial_data,
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (syncer::SyncDataList::const_iterator iter = initial_data.begin();
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter != initial_data.end(); ++iter) {
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string guid = GetGUID(*iter);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(model()->GetTemplateURLForGUID(guid));
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, processor()->change_list_size());
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Locally everything should remain the same.
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, merge_result.num_items_before_association());
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, merge_result.num_items_after_association());
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeUpdateFromSync) {
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The local data is the same as the sync data merged in, but timestamps have
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changed. Ensure the right fields are merged in.
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* turl1 = CreateTestTemplateURL(ASCIIToUTF16("abc.com"),
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             "http://abc.com", "abc", 9000);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(turl1);
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* turl2 = CreateTestTemplateURL(ASCIIToUTF16("xyz.com"),
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             "http://xyz.com", "xyz", 9000);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(turl2);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl1_newer(CreateTestTemplateURL(
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASCIIToUTF16("abc.com"), "http://abc.ca", "abc", 9999));
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TemplateURLService::CreateSyncDataFromTemplateURL(*turl1_newer));
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl2_older(CreateTestTemplateURL(
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASCIIToUTF16("xyz.com"), "http://xyz.ca", "xyz", 8888));
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TemplateURLService::CreateSyncDataFromTemplateURL(*turl2_older));
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES, initial_data,
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both were local updates, so we expect the same count.
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the first replaced the initial abc TemplateURL.
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(turl1, model()->GetTemplateURLForGUID("abc"));
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://abc.ca", turl1->url());
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the second produced an upstream update to the xyz TemplateURL.
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, processor()->change_list_size());
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("xyz"));
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange change = processor()->change_for_guid("xyz");
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(change.change_type() == syncer::SyncChange::ACTION_UPDATE);
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://xyz.com", GetURL(change.sync_data()));
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Locally only the older item should have been modified.
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, merge_result.num_items_modified());
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, merge_result.num_items_before_association());
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, merge_result.num_items_after_association());
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeAddFromOlderSyncData) {
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GUIDs all differ, so this is data to be added from Sync, but the timestamps
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from Sync are older. Set up the local data so that one is a dupe, one has a
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // conflicting keyword, and the last has no conflicts (a clean ADD).
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key1.com",
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "aaa", 100));  // dupe
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key2"),
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://expected.com", "bbb", 100));  // keyword conflict
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("unique"),
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "http://unique.com", "ccc"));  // add
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES,
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateInitialSyncData(), PassProcessor(),
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateAndPassSyncErrorFactory());
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The dupe and conflict results in merges, as local values are always merged
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with sync values if there is a keyword conflict. The unique keyword should
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be added.
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The key1 duplicate results in the local copy winning. Ensure that Sync's
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // copy was not added, and the local copy is pushed upstream to Sync as an
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // update. The local copy should have received the sync data's GUID.
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key1"));
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check changes for the UPDATE.
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key1"));
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange key1_change = processor()->change_for_guid("key1");
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, key1_change.change_type());
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The local sync_guid should no longer be found.
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForGUID("aaa"));
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The key2 keyword conflict results in a merge, with the values of the local
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // copy winning, so ensure it retains the original URL, and that an update to
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the sync guid is pushed upstream to Sync.
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* key2 = model()->GetTemplateURLForGUID("key2");
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(key2);
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("key2"), key2->keyword());
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://expected.com", key2->url());
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check changes for the UPDATE.
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key2"));
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange key2_change = processor()->change_for_guid("key2");
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, key2_change.change_type());
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("key2", GetKeyword(key2_change.sync_data()));
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://expected.com", GetURL(key2_change.sync_data()));
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The local sync_guid should no longer be found.
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForGUID("bbb"));
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The last TemplateURL should have had no conflicts and was just added. It
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should not have replaced the third local TemplateURL.
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("ccc"));
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key3"));
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Two UPDATEs and one ADD.
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, processor()->change_list_size());
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One ADDs should be pushed up to Sync.
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("ccc"));
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            processor()->change_for_guid("ccc").change_type());
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All the sync items had new guids, but only one doesn't conflict and is
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // added. The other two conflicting cases result in local modifications
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to override the local guids but preserve the local data.
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, merge_result.num_items_added());
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, merge_result.num_items_modified());
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, merge_result.num_items_before_association());
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4, merge_result.num_items_after_association());
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeAddFromNewerSyncData) {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GUIDs all differ, so Sync may overtake some entries, but the timestamps
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from Sync are newer. Set up the local data so that one is a dupe, one has a
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // conflicting keyword, and the last has no conflicts (a clean ADD).
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key1.com",
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "aaa", 10));  // dupe
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key2"),
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://expected.com", "bbb", 10));  // keyword conflict
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("unique"),
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "http://unique.com", "ccc", 10));  // add
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES,
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateInitialSyncData(), PassProcessor(),
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateAndPassSyncErrorFactory());
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The dupe and keyword conflict results in merges. The unique keyword be
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the model.
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The key1 duplicate results in Sync's copy winning. Ensure that Sync's
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // copy replaced the local copy.
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key1"));
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForGUID("aaa"));
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(processor()->contains_guid("key1"));
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(processor()->contains_guid("aaa"));
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The key2 keyword conflict results in Sync's copy winning, so ensure it
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // retains the original keyword and is added. The local copy should be
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // removed.
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* key2_sync = model()->GetTemplateURLForGUID("key2");
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(key2_sync);
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("key2"), key2_sync->keyword());
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForGUID("bbb"));
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The last TemplateURL should have had no conflicts and was just added. It
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should not have replaced the third local TemplateURL.
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("ccc"));
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key3"));
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One ADD.
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, processor()->change_list_size());
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One ADDs should be pushed up to Sync.
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("ccc"));
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            processor()->change_for_guid("ccc").change_type());
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // One of the sync items is added directly without conflict. The other two
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // conflict but are newer than the local items so are added while the local
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is deleted.
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, merge_result.num_items_added());
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, merge_result.num_items_deleted());
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, merge_result.num_items_before_association());
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4, merge_result.num_items_after_association());
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, ProcessChangesEmptyModel) {
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We initially have no data.
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      syncer::SEARCH_ENGINES, syncer::SyncDataList(),
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a bunch of ADDs.
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key1.com", "key1")));
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key2"), "http://key2.com", "key2")));
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key3"), "http://key3.com", "key3")));
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, processor()->change_list_size());
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key1"));
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key2"));
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key3"));
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, ProcessChangesNoConflicts) {
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES,
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CreateInitialSyncData(), PassProcessor(),
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CreateAndPassSyncErrorFactory());
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Process different types of changes, without conflicts.
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key4"), "http://key4.com", "key4")));
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_UPDATE,
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("newkeyword"), "http://new.com",
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            "key2")));
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_DELETE,
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key3"), "http://key3.com", "key3")));
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add one, remove one, update one, so the number shouldn't change.
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, processor()->change_list_size());
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key1"));
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key2"));
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* turl = model()->GetTemplateURLForGUID("key2");
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(turl);
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("newkeyword"), turl->keyword());
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://new.com", turl->url());
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForGUID("key3"));
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key4"));
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, ProcessChangesWithConflictsSyncWins) {
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES,
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CreateInitialSyncData(), PassProcessor(),
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CreateAndPassSyncErrorFactory());
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Process different types of changes, with conflicts. Note that all this data
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has a newer timestamp, so Sync will win in these scenarios.
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key2"), "http://new.com", "aaa")));
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_UPDATE,
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key3"), "http://key3.com", "key1")));
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes);
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add one, update one, so we're up to 4.
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sync is always newer here, so it should always win.  We should create
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SyncChanges for the changes to the local entities, since they're synced
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // too.
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, processor()->change_list_size());
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key2"));
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            processor()->change_for_guid("key2").change_type());
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key3"));
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            processor()->change_for_guid("key3").change_type());
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // aaa conflicts with key2 and wins, forcing key2's keyword to update.
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("aaa"));
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(model()->GetTemplateURLForGUID("aaa"),
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("key2")));
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key2"));
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(model()->GetTemplateURLForGUID("key2"),
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("key2.com")));
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // key1 update conflicts with key3 and wins, forcing key3's keyword to update.
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key1"));
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(model()->GetTemplateURLForGUID("key1"),
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("key3")));
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key3"));
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(model()->GetTemplateURLForGUID("key3"),
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("key3.com")));
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, ProcessChangesWithConflictsLocalWins) {
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES,
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CreateInitialSyncData(), PassProcessor(),
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CreateAndPassSyncErrorFactory());
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Process different types of changes, with conflicts. Note that all this data
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has an older timestamp, so the local data will win in these scenarios.
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key2"), "http://new.com", "aaa",
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            10)));
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_UPDATE,
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key3"), "http://key3.com", "key1",
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            10)));
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes);
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add one, update one, so we're up to 4.
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Local data wins twice so two updates are pushed up to Sync.
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, processor()->change_list_size());
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // aaa conflicts with key2 and loses, forcing it's keyword to update.
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("aaa"));
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(model()->GetTemplateURLForGUID("aaa"),
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("new.com")));
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key2"));
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(model()->GetTemplateURLForGUID("key2"),
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("key2")));
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // key1 update conflicts with key3 and loses, forcing key1's keyword to
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // update.
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key1"));
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(model()->GetTemplateURLForGUID("key1"),
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("key3.com")));
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key3"));
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(model()->GetTemplateURLForGUID("key3"),
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("key3")));
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("aaa"));
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            processor()->change_for_guid("aaa").change_type());
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key1"));
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            processor()->change_for_guid("key1").change_type());
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, ProcessTemplateURLChange) {
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that ProcessTemplateURLChange is called and pushes the correct
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changes to Sync whenever local changes are made to TemplateURLs.
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES,
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CreateInitialSyncData(), PassProcessor(),
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CreateAndPassSyncErrorFactory());
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a new search engine.
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* new_turl =
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("baidu"), "http://baidu.cn", "new");
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(new_turl);
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, processor()->change_list_size());
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("new"));
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange change = processor()->change_for_guid("new");
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("baidu", GetKeyword(change.sync_data()));
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://baidu.cn", GetURL(change.sync_data()));
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change a keyword.
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* existing_turl = model()->GetTemplateURLForGUID("key1");
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ResetTemplateURL(existing_turl, existing_turl->short_name(),
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ASCIIToUTF16("k"), existing_turl->url());
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, processor()->change_list_size());
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key1"));
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change = processor()->change_for_guid("key1");
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("k", GetKeyword(change.sync_data()));
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove an existing search engine.
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  existing_turl = model()->GetTemplateURLForGUID("key2");
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Remove(existing_turl);
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, processor()->change_list_size());
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key2"));
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change = processor()->change_for_guid("key2");
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, change.change_type());
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, ProcessChangesWithLocalExtensions) {
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES,
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CreateInitialSyncData(), PassProcessor(),
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CreateAndPassSyncErrorFactory());
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1060868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Add some extension keywords locally.
1061116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  model()->RegisterOmniboxKeyword("extension1", "unittest", "keyword1",
1062116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  "http://extension1");
1063116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TemplateURL* extension1 =
1064116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword1"));
1065116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(extension1);
1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, processor()->change_list_size());
1067116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1068116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  model()->RegisterOmniboxKeyword("extension2", "unittest", "keyword2",
1069116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  "http://extension2");
1070116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TemplateURL* extension2 =
1071116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword2"));
1072116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(extension2);
1073868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, processor()->change_list_size());
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create some sync changes that will conflict with the extension keywords.
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateTestTemplateURL(ASCIIToUTF16("keyword1"), "http://aaa.com",
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          std::string(), 100, true)));
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateTestTemplateURL(ASCIIToUTF16("keyword2"), "http://bbb.com")));
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes);
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1084868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The existing extension keywords should be uniquified.
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForHost("aaa.com") == NULL);
1086868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(model()->GetTemplateURLForHost("aaa.com"),
1087868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword1")));
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* url_for_keyword2 =
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword2"));
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(extension2, url_for_keyword2);
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://bbb.com", url_for_keyword2->url());
1092868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1093868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Replaced extension keywords should be uniquified.
1094868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(extension1,
1095868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword1_")));
1096868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(extension2,
1097868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword2_")));
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, AutogeneratedKeywordMigrated) {
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a couple of sync entries with autogenerated keywords.
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data;
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key1.com", "key1"));
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateCustomSyncData(*turl, true, turl->url(), turl->sync_guid()));
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  turl.reset(CreateTestTemplateURL(ASCIIToUTF16("key2"),
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "{google:baseURL}search?q={searchTerms}", "key2"));
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateCustomSyncData(*turl, true, turl->url(), turl->sync_guid()));
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now try to sync the data locally.
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both entries should have been added, with explicit keywords.
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* key1 = model()->GetTemplateURLForHost("key1.com");
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(key1 == NULL);
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("key1.com"), key1->keyword());
11201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL google_url(model()->search_terms_data().GoogleBaseURLValue());
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* key2 = model()->GetTemplateURLForHost(google_url.host());
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(key2 == NULL);
1123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 google_keyword(net::StripWWWFromHost(google_url));
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(google_keyword, key2->keyword());
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should also have gotten some corresponding UPDATEs pushed upstream.
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(processor()->change_list_size(), 2U);
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key1"));
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange key1_change = processor()->change_for_guid("key1");
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, key1_change.change_type());
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("key1.com", GetKeyword(key1_change.sync_data()));
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key2"));
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange key2_change = processor()->change_for_guid("key2");
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, key2_change.change_type());
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(google_keyword, UTF8ToUTF16(GetKeyword(key2_change.sync_data())));
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, AutogeneratedKeywordConflicts) {
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sync brings in some autogenerated keywords, but the generated keywords we
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // try to create conflict with ones in the model.
1141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 google_keyword(net::StripWWWFromHost(GURL(
11421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      model()->search_terms_data().GoogleBaseURLValue())));
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string local_google_url =
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "{google:baseURL}1/search?q={searchTerms}";
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* google = CreateTestTemplateURL(google_keyword, local_google_url);
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(google);
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* other =
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("other.com"), "http://other.com/foo");
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(other);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data;
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(CreateTestTemplateURL(ASCIIToUTF16("sync1"),
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "{google:baseURL}2/search?q={searchTerms}", "sync1", 50));
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateCustomSyncData(*turl, true, turl->url(), turl->sync_guid()));
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string synced_other_url =
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://other.com/search?q={searchTerms}";
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  turl.reset(CreateTestTemplateURL(ASCIIToUTF16("sync2"),
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      synced_other_url, "sync2", 150));
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateCustomSyncData(*turl, true, turl->url(), turl->sync_guid()));
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before we merge the data, grab the local sync_guids so we can ensure that
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // they've been replaced.
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string local_google_guid = google->sync_guid();
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string local_other_guid = other->sync_guid();
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In this case, the conflicts should be handled just like any other keyword
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // conflicts -- the later-modified TemplateURL is assumed to be authoritative.
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since the initial TemplateURLs were local only, they should be merged with
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the sync TemplateURLs (GUIDs transferred over).
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForGUID(local_google_guid));
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(model()->GetTemplateURLForGUID("sync1"));
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(google_keyword, model()->GetTemplateURLForGUID("sync1")->keyword());
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForGUID(local_other_guid));
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(model()->GetTemplateURLForGUID("sync2"));
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("other.com"),
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            model()->GetTemplateURLForGUID("sync2")->keyword());
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both synced URLs should have associated UPDATEs, since both needed their
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // keywords to be generated.
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(processor()->change_list_size(), 2U);
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("sync1"));
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange sync1_change = processor()->change_for_guid("sync1");
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, sync1_change.change_type());
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(google_keyword, UTF8ToUTF16(GetKeyword(sync1_change.sync_data())));
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(local_google_url, GetURL(sync1_change.sync_data()));
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("sync2"));
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange sync2_change = processor()->change_for_guid("sync2");
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, sync2_change.change_type());
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("other.com", GetKeyword(sync2_change.sync_data()));
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(synced_other_url, GetURL(sync2_change.sync_data()));
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, TwoAutogeneratedKeywordsUsingGoogleBaseURL) {
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sync brings in two autogenerated keywords and both use Google base URLs.
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We make the first older so that it will get renamed once before the second
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and then again once after (when we resolve conflicts for the second).
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data;
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(CreateTestTemplateURL(ASCIIToUTF16("key1"),
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "{google:baseURL}1/search?q={searchTerms}", "key1", 50));
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateCustomSyncData(*turl, true, turl->url(), turl->sync_guid()));
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  turl.reset(CreateTestTemplateURL(ASCIIToUTF16("key2"),
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "{google:baseURL}2/search?q={searchTerms}", "key2"));
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateCustomSyncData(*turl, true, turl->url(), turl->sync_guid()));
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should still have coalesced the updates to one each.
1214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 google_keyword(net::StripWWWFromHost(GURL(
12151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      model()->search_terms_data().GoogleBaseURLValue())));
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* keyword1 =
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model()->GetTemplateURLForKeyword(google_keyword + ASCIIToUTF16("_"));
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(keyword1 == NULL);
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("key1", keyword1->sync_guid());
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* keyword2 = model()->GetTemplateURLForKeyword(google_keyword);
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(keyword2 == NULL);
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("key2", keyword2->sync_guid());
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(processor()->change_list_size(), 2U);
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key1"));
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange key1_change = processor()->change_for_guid("key1");
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, key1_change.change_type());
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(keyword1->keyword(),
12295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            base::UTF8ToUTF16(GetKeyword(key1_change.sync_data())));
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key2"));
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange key2_change = processor()->change_for_guid("key2");
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, key2_change.change_type());
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(keyword2->keyword(),
12345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            base::UTF8ToUTF16(GetKeyword(key2_change.sync_data())));
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, DuplicateEncodingsRemoved) {
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a sync entry with duplicate encodings.
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data;
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURLData data;
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.short_name = ASCIIToUTF16("test");
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.SetKeyword(ASCIIToUTF16("keyword"));
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.SetURL("http://test/%s");
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.input_encodings.push_back("UTF-8");
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.input_encodings.push_back("UTF-8");
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.input_encodings.push_back("UTF-16");
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.input_encodings.push_back("UTF-8");
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.input_encodings.push_back("Big5");
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.input_encodings.push_back("UTF-16");
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.input_encodings.push_back("Big5");
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.input_encodings.push_back("Windows-1252");
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.date_created = Time::FromTimeT(100);
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.last_modified = Time::FromTimeT(100);
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.sync_guid = "keyword";
1256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(new TemplateURL(data));
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TemplateURLService::CreateSyncDataFromTemplateURL(*turl));
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now try to sync the data locally.
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The entry should have been added, with duplicate encodings removed.
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* keyword =
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword"));
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(keyword == NULL);
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, keyword->input_encodings().size());
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should also have gotten a corresponding UPDATE pushed upstream.
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(processor()->change_list_size(), 1U);
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("keyword"));
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange keyword_change = processor()->change_for_guid("keyword");
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, keyword_change.change_type());
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("UTF-8;UTF-16;Big5;Windows-1252", keyword_change.sync_data().
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSpecifics().search_engine().input_encodings());
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeTwoClientsBasic) {
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start off B with some empty data.
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_b()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES,
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      CreateInitialSyncData(), PassProcessor(),
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      CreateAndPassSyncErrorFactory());
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Merge A and B. All of B's data should transfer over to A, which initially
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has no data.
1287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> delegate_b(
1288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new syncer::SyncChangeProcessorWrapperForTest(model_b()));
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_a()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES,
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_b()->GetAllSyncData(syncer::SEARCH_ENGINES),
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_b.PassAs<syncer::SyncChangeProcessor>(),
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateAndPassSyncErrorFactory());
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // They should be consistent.
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AssertEquals(model_a()->GetAllSyncData(syncer::SEARCH_ENGINES),
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               model_b()->GetAllSyncData(syncer::SEARCH_ENGINES));
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeTwoClientsDupesAndConflicts) {
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start off B with some empty data.
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_b()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES,
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      CreateInitialSyncData(), PassProcessor(),
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      CreateAndPassSyncErrorFactory());
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up A so we have some interesting duplicates and conflicts.
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_a()->Add(CreateTestTemplateURL(ASCIIToUTF16("key4"), "http://key4.com",
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "key4"));  // Added
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_a()->Add(CreateTestTemplateURL(ASCIIToUTF16("key2"), "http://key2.com",
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "key2"));  // Merge - Copy of key2.
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_a()->Add(CreateTestTemplateURL(ASCIIToUTF16("key3"), "http://key3.com",
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "key5", 10));  // Merge - Dupe of key3.
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_a()->Add(CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key6.com",
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "key6", 10));  // Conflict with key1
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Merge A and B.
1316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> delegate_b(
1317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new syncer::SyncChangeProcessorWrapperForTest(model_b()));
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_a()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES,
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_b()->GetAllSyncData(syncer::SEARCH_ENGINES),
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_b.PassAs<syncer::SyncChangeProcessor>(),
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateAndPassSyncErrorFactory());
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // They should be consistent.
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AssertEquals(model_a()->GetAllSyncData(syncer::SEARCH_ENGINES),
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               model_b()->GetAllSyncData(syncer::SEARCH_ENGINES));
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, StopSyncing) {
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncError error =
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      model()->MergeDataAndStartSyncing(
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          syncer::SEARCH_ENGINES,
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CreateInitialSyncData(),
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          PassProcessor(),
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CreateAndPassSyncErrorFactory()).error();
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(error.IsSet());
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->StopSyncing(syncer::SEARCH_ENGINES);
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_UPDATE,
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("newkeyword"), "http://new.com",
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            "key2")));
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = model()->ProcessSyncChanges(FROM_HERE, changes);
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(error.IsSet());
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the sync changes were not accepted.
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key2"));
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("newkeyword")));
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, SyncErrorOnInitialSync) {
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processor()->set_erroneous(true);
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncError error =
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      model()->MergeDataAndStartSyncing(
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          syncer::SEARCH_ENGINES,
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CreateInitialSyncData(),
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          PassProcessor(),
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CreateAndPassSyncErrorFactory()).error();
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(error.IsSet());
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that if the initial merge was erroneous, then subsequence attempts
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to push data into the local model are rejected, since the model was never
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // successfully associated with Sync in the first place.
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_UPDATE,
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("newkeyword"), "http://new.com",
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            "key2")));
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processor()->set_erroneous(false);
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = model()->ProcessSyncChanges(FROM_HERE, changes);
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(error.IsSet());
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the sync changes were not accepted.
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key2"));
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("newkeyword")));
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, SyncErrorOnLaterSync) {
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that if the SyncProcessor succeeds in the initial merge, but fails
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in future ProcessSyncChanges, we still return an error.
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncError error =
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      model()->MergeDataAndStartSyncing(
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          syncer::SEARCH_ENGINES,
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CreateInitialSyncData(),
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          PassProcessor(),
13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CreateAndPassSyncErrorFactory()).error();
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(error.IsSet());
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_UPDATE,
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("newkeyword"), "http://new.com",
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            "key2")));
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processor()->set_erroneous(true);
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = model()->ProcessSyncChanges(FROM_HERE, changes);
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(error.IsSet());
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeTwiceWithSameSyncData) {
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that a second merge with the same data as the first does not
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // actually update the local data.
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data;
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(CreateInitialSyncData()[0]);
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key1.com",
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "key1", 10));  // earlier
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncError error =
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      model()->MergeDataAndStartSyncing(
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          syncer::SEARCH_ENGINES,
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          initial_data,
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          PassProcessor(),
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CreateAndPassSyncErrorFactory()).error();
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(error.IsSet());
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have updated the original TemplateURL with Sync's version.
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep a copy of it so we can compare it after we re-merge.
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* key1_url = model()->GetTemplateURLForGUID("key1");
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(key1_url);
1417f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<TemplateURL> updated_turl(new TemplateURL(key1_url->data()));
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(Time::FromTimeT(90), updated_turl->last_modified());
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Modify a single field of the initial data. This should not be updated in
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the second merge, as the last_modified timestamp remains the same.
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> temp_turl(Deserialize(initial_data[0]));
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURLData data(temp_turl->data());
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.short_name = ASCIIToUTF16("SomethingDifferent");
1425f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  temp_turl.reset(new TemplateURL(data));
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.clear();
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TemplateURLService::CreateSyncDataFromTemplateURL(*temp_turl));
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remerge the data again. This simulates shutting down and syncing again
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at a different time, but the cloud data has not changed.
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->StopSyncing(syncer::SEARCH_ENGINES);
1433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  sync_processor_wrapper_.reset(
1434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  error = model()->MergeDataAndStartSyncing(
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES,
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      initial_data,
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PassProcessor(),
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateAndPassSyncErrorFactory()).error();
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(error.IsSet());
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the TemplateURL was not modified.
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* reupdated_turl = model()->GetTemplateURLForGUID("key1");
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reupdated_turl);
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AssertEquals(*updated_turl, *reupdated_turl);
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, SyncedDefaultGUIDArrivesFirst) {
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data = CreateInitialSyncData();
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The default search provider should support replacement.
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(CreateTestTemplateURL(ASCIIToUTF16("key2"),
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key2.com/{searchTerms}", "key2", 90));
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data[1] = TemplateURLService::CreateSyncDataFromTemplateURL(*turl);
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
14565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  model()->SetUserSelectedDefaultSearchProvider(
14575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      model()->GetTemplateURLForGUID("key2"));
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* default_search = model()->GetDefaultSearchProvider();
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(default_search);
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change kSyncedDefaultSearchProviderGUID to a GUID that does not exist in
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the model yet. Ensure that the default has not changed in any way.
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_a()->GetTestingPrefService()->SetString(
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kSyncedDefaultSearchProviderGUID, "newdefault");
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(default_search, model()->GetDefaultSearchProvider());
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bring in a random new search engine with a different GUID. Ensure that
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it doesn't change the default.
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes1;
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes1.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("random"), "http://random.com",
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            "random")));
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes1);
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(default_search, model()->GetDefaultSearchProvider());
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, bring in the expected entry with the right GUID. Ensure that
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the default has changed to the new search engine.
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes2;
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes2.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("new"), "http://new.com/{searchTerms}",
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            "newdefault")));
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes2);
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(default_search, model()->GetDefaultSearchProvider());
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ("newdefault", model()->GetDefaultSearchProvider()->sync_guid());
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, DefaultGuidDeletedBeforeNewDSPArrives) {
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data;
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The default search provider should support replacement.
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl1(CreateTestTemplateURL(ASCIIToUTF16("key1"),
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key1.com/{searchTerms}", "key1", 90));
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a second default search provider for the
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FindNewDefaultSearchProvider method to find.
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURLData data;
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.short_name = ASCIIToUTF16("unittest");
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.SetKeyword(ASCIIToUTF16("key2"));
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.SetURL("http://key2.com/{searchTerms}");
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.favicon_url = GURL("http://favicon.url");
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.safe_for_autoreplace = false;
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.date_created = Time::FromTimeT(100);
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.last_modified = Time::FromTimeT(100);
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.created_by_policy = false;
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.prepopulate_id = 999999;
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.sync_guid = "key2";
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.show_in_default_list = true;
1513f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<TemplateURL> turl2(new TemplateURL(data));
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *turl1));
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *turl2));
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
15205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  model()->SetUserSelectedDefaultSearchProvider(
15215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      model()->GetTemplateURLForGUID("key1"));
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ("key1", model()->GetDefaultSearchProvider()->sync_guid());
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* default_search = model()->GetDefaultSearchProvider();
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(default_search);
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change kSyncedDefaultSearchProviderGUID to a GUID that does not exist in
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the model yet. Ensure that the default has not changed in any way.
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_a()->GetTestingPrefService()->SetString(
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kSyncedDefaultSearchProviderGUID, "newdefault");
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ("key1", model()->GetDefaultSearchProvider()->sync_guid());
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("newdefault", profile_a()->GetTestingPrefService()->GetString(
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kSyncedDefaultSearchProviderGUID));
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a situation where an ACTION_DELETE on the default arrives before
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the new default search provider entry. This should fail to delete the
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // target entry, and instead send up an "undelete" to the server, after
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // further uniquifying the keyword to avoid infinite sync loops. The synced
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default GUID should not be changed so that when the expected default entry
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // arrives, it can still be set as the default.
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes1;
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes1.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_DELETE,
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          turl1.release()));
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes1);
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("key1_")));
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("key1", model()->GetDefaultSearchProvider()->sync_guid());
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("newdefault", profile_a()->GetTestingPrefService()->GetString(
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kSyncedDefaultSearchProviderGUID));
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange undelete = processor()->change_for_guid("key1");
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_ADD, undelete.change_type());
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("key1_",
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            undelete.sync_data().GetSpecifics().search_engine().keyword());
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, bring in the expected entry with the right GUID. Ensure that
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the default has changed to the new search engine.
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes2;
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes2.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("new"), "http://new.com/{searchTerms}",
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            "newdefault")));
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes2);
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("newdefault", model()->GetDefaultSearchProvider()->sync_guid());
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("newdefault", profile_a()->GetTestingPrefService()->GetString(
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kSyncedDefaultSearchProviderGUID));
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, SyncedDefaultArrivesAfterStartup) {
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start with the default set to something in the model before we start
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // syncing.
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("what"),
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "http://thewhat.com/{searchTerms}",
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "initdefault"));
15785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  model()->SetUserSelectedDefaultSearchProvider(
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model()->GetTemplateURLForGUID("initdefault"));
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* default_search = model()->GetDefaultSearchProvider();
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(default_search);
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set kSyncedDefaultSearchProviderGUID to something that is not yet in
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the model but is expected in the initial sync. Ensure that this doesn't
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change our default since we're not quite syncing yet.
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_a()->GetTestingPrefService()->SetString(
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kSyncedDefaultSearchProviderGUID, "key2");
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(default_search, model()->GetDefaultSearchProvider());
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now sync the initial data, which will include the search engine entry
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destined to become the new default.
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data = CreateInitialSyncData();
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The default search provider should support replacement.
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(CreateTestTemplateURL(ASCIIToUTF16("key2"),
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key2.com/{searchTerms}", "key2", 90));
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data[1] = TemplateURLService::CreateSyncDataFromTemplateURL(*turl);
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the new default has been set.
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(default_search, model()->GetDefaultSearchProvider());
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ("key2", model()->GetDefaultSearchProvider()->sync_guid());
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, SyncedDefaultAlreadySetOnStartup) {
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start with the default set to something in the model before we start
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // syncing.
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kGUID[] = "initdefault";
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("what"),
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "http://thewhat.com/{searchTerms}",
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     kGUID));
16165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  model()->SetUserSelectedDefaultSearchProvider(
16175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      model()->GetTemplateURLForGUID(kGUID));
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* default_search = model()->GetDefaultSearchProvider();
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(default_search);
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set kSyncedDefaultSearchProviderGUID to the current default.
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_a()->GetTestingPrefService()->SetString(
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kSyncedDefaultSearchProviderGUID, kGUID);
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(default_search, model()->GetDefaultSearchProvider());
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now sync the initial data.
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data = CreateInitialSyncData();
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the new entries were added and the default has not changed.
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(default_search, model()->GetDefaultSearchProvider());
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, SyncWithManagedDefaultSearch) {
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First start off with a few entries and make sure we can set an unmanaged
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default search provider.
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data = CreateInitialSyncData();
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
16445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  model()->SetUserSelectedDefaultSearchProvider(
16455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      model()->GetTemplateURLForGUID("key2"));
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(model()->is_default_search_managed());
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(model()->GetDefaultSearchProvider());
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change the default search provider to a managed one.
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kName[] = "manageddefault";
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSearchURL[] = "http://manageddefault.com/search?t={searchTerms}";
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kIconURL[] = "http://manageddefault.com/icon.jpg";
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kEncodings[] = "UTF-16;UTF-32";
16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kAlternateURL[] =
16572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http://manageddefault.com/search#t={searchTerms}";
16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kSearchTermsReplacementKey[] = "espv";
1659116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  test_util_a_->SetManagedDefaultSearchPreferences(true, kName, kName,
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSearchURL, std::string(), kIconURL, kEncodings, kAlternateURL,
16612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSearchTermsReplacementKey);
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* dsp_turl = model()->GetDefaultSearchProvider();
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->is_default_search_managed());
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a new entry from Sync. It should still sync in despite the default
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // being managed.
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("newkeyword"),
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            "http://new.com/{searchTerms}",
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            "newdefault")));
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes);
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change kSyncedDefaultSearchProviderGUID to point to the new entry and
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ensure that the DSP remains managed.
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_a()->GetTestingPrefService()->SetString(
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kSyncedDefaultSearchProviderGUID,
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "newdefault");
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(dsp_turl, model()->GetDefaultSearchProvider());
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->is_default_search_managed());
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go unmanaged. Ensure that the DSP changes to the expected pending entry
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from Sync.
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* expected_default =
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model()->GetTemplateURLForGUID("newdefault");
1690116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  test_util_a_->RemoveManagedDefaultSearchPreferences();
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_default, model()->GetDefaultSearchProvider());
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, SyncMergeDeletesDefault) {
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the value from Sync is a duplicate of the local default and is newer, it
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should safely replace the local value and set as the new default.
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* default_turl = CreateTestTemplateURL(ASCIIToUTF16("key1"),
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key1.com/{searchTerms}", "whateverguid", 10);
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(default_turl);
17015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  model()->SetUserSelectedDefaultSearchProvider(default_turl);
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data = CreateInitialSyncData();
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The key1 entry should be a duplicate of the default.
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(CreateTestTemplateURL(ASCIIToUTF16("key1"),
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key1.com/{searchTerms}", "key1", 90));
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data[0] = TemplateURLService::CreateSyncDataFromTemplateURL(*turl);
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(model()->GetTemplateURLForGUID("whateverguid"));
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(model()->GetDefaultSearchProvider(),
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            model()->GetTemplateURLForGUID("key1"));
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, LocalDefaultWinsConflict) {
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We expect that the local default always wins keyword conflict resolution.
1720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::string16 keyword(ASCIIToUTF16("key1"));
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url("http://whatever.com/{searchTerms}");
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* default_turl = CreateTestTemplateURL(keyword,
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    url,
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    "whateverguid",
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    10);
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(default_turl);
17275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  model()->SetUserSelectedDefaultSearchProvider(default_turl);
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data = CreateInitialSyncData();
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The key1 entry should be different from the default but conflict in the
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // keyword.
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(CreateTestTemplateURL(keyword,
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key1.com/{searchTerms}", "key1", 90));
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data[0] = TemplateURLService::CreateSyncDataFromTemplateURL(*turl);
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since the local default was not yet synced, it should be merged with the
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // conflicting TemplateURL. However, its values should have been preserved
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since it would have won conflict resolution due to being the default.
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* winner = model()->GetTemplateURLForGUID("key1");
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(winner);
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(model()->GetDefaultSearchProvider(), winner);
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(keyword, winner->keyword());
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, winner->url());
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key1"));
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            processor()->change_for_guid("key1").change_type());
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, GetURL(processor()->change_for_guid("key1").sync_data()));
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no loser, as the two were merged together. The local sync_guid
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should no longer be found in the model.
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TemplateURL* loser = model()->GetTemplateURLForGUID("whateverguid");
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(loser);
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, DeleteBogusData) {
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a couple of bogus entries to sync.
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data;
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("key1"), "http://key1.com", "key1"));
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateCustomSyncData(*turl, false, std::string(), turl->sync_guid()));
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  turl.reset(CreateTestTemplateURL(ASCIIToUTF16("key2"), "http://key2.com"));
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateCustomSyncData(*turl, false, turl->url(), std::string()));
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now try to sync the data locally.
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing should have been added, and both bogus entries should be marked for
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deletion.
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, model()->GetTemplateURLs().size());
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, processor()->change_list_size());
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("key1"));
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            processor()->change_for_guid("key1").change_type());
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid(std::string()));
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            processor()->change_for_guid(std::string()).change_type());
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, PreSyncDeletes) {
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->pre_sync_deletes_.insert("key1");
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->pre_sync_deletes_.insert("key2");
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->pre_sync_deletes_.insert("aaa");
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("whatever"),
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://key1.com", "bbb"));
17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES,
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateInitialSyncData(), PassProcessor(),
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateAndPassSyncErrorFactory());
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We expect the model to have GUIDs {bbb, key3} after our initial merge.
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("bbb"));
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->GetTemplateURLForGUID("key3"));
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange change = processor()->change_for_guid("key1");
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, change.change_type());
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change = processor()->change_for_guid("key2");
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, change.change_type());
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "aaa" should have been pruned out on account of not being from Sync.
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(processor()->contains_guid("aaa"));
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The set of pre-sync deletes should be cleared so they're not reused if
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MergeDataAndStartSyncing gets called again.
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(model()->pre_sync_deletes_.empty());
18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Those sync items deleted via pre-sync-deletes should not get added. The
18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // remaining sync item (key3) should though.
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, merge_result.num_items_added());
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, merge_result.num_items_before_association());
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, merge_result.num_items_after_association());
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, PreSyncUpdates) {
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kNewKeyword = "somethingnew";
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch the prepopulate search engines so we know what they are.
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t default_search_provider_index = 0;
18235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ScopedVector<TemplateURLData> prepop_turls =
18244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      TemplateURLPrepopulateData::GetPrepopulatedEngines(
18255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          profile_a()->GetTestingPrefService(), &default_search_provider_index);
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have to prematurely exit this test if for some reason this machine does
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not have any prepopulate TemplateURLs.
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(prepop_turls.empty());
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a copy of the first TemplateURL with a really old timestamp and a
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // new keyword. Add it to the model.
18335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  TemplateURLData data_copy(*prepop_turls[0]);
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_copy.last_modified = Time::FromTimeT(10);
1835a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 original_keyword = data_copy.keyword();
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_copy.SetKeyword(ASCIIToUTF16(kNewKeyword));
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set safe_for_autoreplace to false so our keyword survives.
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_copy.safe_for_autoreplace = false;
1839f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  model()->Add(new TemplateURL(data_copy));
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Merge the prepopulate search engines.
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time pre_merge_time = base::Time::Now();
1843a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  base::RunLoop().RunUntilIdle();
1844116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  test_util_a_->ResetModel(true);
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The newly added search engine should have been safely merged, with an
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // updated time.
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* added_turl = model()->GetTemplateURLForKeyword(
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASCIIToUTF16(kNewKeyword));
1850010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ASSERT_TRUE(added_turl);
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time new_timestamp = added_turl->last_modified();
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(new_timestamp, pre_merge_time);
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string sync_guid = added_turl->sync_guid();
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bring down a copy of the prepopulate engine from Sync with the old values,
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // including the old timestamp and the same GUID. Ensure that it loses
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // conflict resolution against the local value, and an update is sent to the
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // server. The new timestamp should be preserved.
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data;
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_copy.SetKeyword(original_keyword);
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_copy.sync_guid = sync_guid;
1862f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<TemplateURL> sync_turl(new TemplateURL(data_copy));
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TemplateURLService::CreateSyncDataFromTemplateURL(*sync_turl));
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES,
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      initial_data, PassProcessor(), CreateAndPassSyncErrorFactory());
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(added_turl, model()->GetTemplateURLForKeyword(
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASCIIToUTF16(kNewKeyword)));
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(new_timestamp, added_turl->last_modified());
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange change = processor()->change_for_guid(sync_guid);
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kNewKeyword,
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            change.sync_data().GetSpecifics().search_engine().keyword());
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(new_timestamp, base::Time::FromInternalValue(
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      change.sync_data().GetSpecifics().search_engine().last_modified()));
18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All the sync data is old, so nothing should change locally.
18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(static_cast<int>(prepop_turls.size()),
18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            merge_result.num_items_before_association());
18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(static_cast<int>(prepop_turls.size()),
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            merge_result.num_items_after_association());
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, SyncBaseURLs) {
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that bringing in a remote TemplateURL that uses Google base URLs
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // causes it to get a local keyword that matches the local base URL.
1893116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  test_util_a_->SetGoogleBaseURL(GURL("http://google.com/"));
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncDataList initial_data;
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TemplateURL> turl(CreateTestTemplateURL(
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASCIIToUTF16("google.co.uk"), "{google:baseURL}search?q={searchTerms}",
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "guid"));
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_data.push_back(
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TemplateURLService::CreateSyncDataFromTemplateURL(*turl));
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->MergeDataAndStartSyncing(syncer::SEARCH_ENGINES, initial_data,
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassProcessor(), CreateAndPassSyncErrorFactory());
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURL* synced_turl = model()->GetTemplateURLForGUID("guid");
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(synced_turl);
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("google.com"), synced_turl->keyword());
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, processor()->change_list_size());
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remote updates to this URL's keyword should be silently ignored.
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChangeList changes;
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_UPDATE,
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestTemplateURL(ASCIIToUTF16("google.de"),
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "{google:baseURL}search?q={searchTerms}", "guid")));
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes);
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("google.com"), synced_turl->keyword());
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, processor()->change_list_size());
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A local change to the Google base URL should update the keyword and
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // generate a sync change.
1918116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  test_util_a_->SetGoogleBaseURL(GURL("http://google.co.in/"));
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("google.co.in"), synced_turl->keyword());
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, processor()->change_list_size());
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(processor()->contains_guid("guid"));
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncChange change(processor()->change_for_guid("guid"));
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("google.co.in", GetKeyword(change.sync_data()));
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeInSyncTemplateURL) {
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An enumeration used to indicate which TemplateURL test value is expected
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for a particular test result.
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ExpectedTemplateURL {
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOCAL,
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SYNC,
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BOTH,
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEITHER,
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets up and executes a MergeInSyncTemplateURL test given a number of
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // expected start and end states:
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * |conflict_winner| denotes which TemplateURL should win the
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    conflict.
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * |synced_at_start| denotes which of the TemplateURLs should known
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    to Sync.
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * |update_sent| denotes which TemplateURL should have an
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    ACTION_UPDATE sent to the server after the merge.
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * |turl_uniquified| denotes which TemplateURL should have its
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    keyword updated after the merge.
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * |present_in_model| denotes which TemplateURL should be found in
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    the model after the merge.
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * If |keywords_conflict| is true, the TemplateURLs are set up with
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    the same keyword.
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectedTemplateURL conflict_winner;
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectedTemplateURL synced_at_start;
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectedTemplateURL update_sent;
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectedTemplateURL turl_uniquified;
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectedTemplateURL present_in_model;
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool keywords_conflict;
19582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int merge_results[3];  // in Added, Modified, Deleted order.
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } test_cases[] = {
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Both are synced and the new sync entry is better: Local is uniquified and
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // UPDATE sent. Sync is added.
19622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {SYNC, BOTH, LOCAL, LOCAL, BOTH, true, {1, 1, 0}},
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Both are synced and the local entry is better: Sync is uniquified and
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // added to the model. An UPDATE is sent for it.
19652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {LOCAL, BOTH, SYNC, SYNC, BOTH, true, {1, 1, 0}},
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Local was not known to Sync and the new sync entry is better: Sync is
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // added. Local is removed. No updates.
19682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {SYNC, SYNC, NEITHER, NEITHER, SYNC, true, {1, 0, 1}},
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Local was not known to sync and the local entry is better: Local is
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // updated with sync GUID, Sync is not added. UPDATE sent for Sync.
19712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {LOCAL, SYNC, SYNC, NEITHER, SYNC, true, {0, 1, 0}},
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No conflicting keyword. Both should be added with their original
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // keywords, with no updates sent. Note that MergeDataAndStartSyncing is
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // responsible for creating the ACTION_ADD for the local TemplateURL.
19752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {NEITHER, SYNC, NEITHER, NEITHER, BOTH, false, {1, 0, 0}},
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Assert all the valid states of ExpectedTemplateURLs.
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(test_cases[i].conflict_winner == BOTH);
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(test_cases[i].synced_at_start == NEITHER);
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(test_cases[i].synced_at_start == LOCAL);
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(test_cases[i].update_sent == BOTH);
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(test_cases[i].turl_uniquified == BOTH);
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(test_cases[i].present_in_model == NEITHER);
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1987a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16 local_keyword = ASCIIToUTF16("localkeyword");
1988a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16 sync_keyword = test_cases[i].keywords_conflict ?
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        local_keyword : ASCIIToUTF16("synckeyword");
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string local_url = "www.localurl.com";
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string sync_url = "www.syncurl.com";
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const time_t local_last_modified = 100;
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const time_t sync_last_modified =
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        test_cases[i].conflict_winner == SYNC ? 110 : 90;
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string local_guid = "local_guid";
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string sync_guid = "sync_guid";
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Initialize expectations.
1999a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 expected_local_keyword = local_keyword;
2000a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 expected_sync_keyword = sync_keyword;
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create the data and run the actual test.
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TemplateURL* local_turl = CreateTestTemplateURL(
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        local_keyword, local_url, local_guid, local_last_modified);
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model()->Add(local_turl);
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<TemplateURL> sync_turl(CreateTestTemplateURL(
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sync_keyword, sync_url, sync_guid, sync_last_modified));
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SyncDataMap sync_data;
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_cases[i].synced_at_start == SYNC ||
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        test_cases[i].synced_at_start == BOTH) {
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_data[sync_turl->sync_guid()] =
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          TemplateURLService::CreateSyncDataFromTemplateURL(*sync_turl);
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_cases[i].synced_at_start == BOTH) {
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_data[local_turl->sync_guid()] =
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          TemplateURLService::CreateSyncDataFromTemplateURL(*local_turl);
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SyncDataMap initial_data;
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    initial_data[local_turl->sync_guid()] =
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TemplateURLService::CreateSyncDataFromTemplateURL(*local_turl);
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::SyncChangeList change_list;
20242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncer::SyncMergeResult merge_result(syncer::SEARCH_ENGINES);
20252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model()->MergeInSyncTemplateURL(sync_turl.get(),
20262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    sync_data,
20272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    &change_list,
20282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    &initial_data,
20292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    &merge_result);
20302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Verify the merge results were set appropriately.
20322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(test_cases[i].merge_results[0], merge_result.num_items_added());
20332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(test_cases[i].merge_results[1],
20342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              merge_result.num_items_modified());
20352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(test_cases[i].merge_results[2], merge_result.num_items_deleted());
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check for expected updates, if any.
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string expected_update_guid;
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_cases[i].update_sent == LOCAL)
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_update_guid = local_guid;
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (test_cases[i].update_sent == SYNC)
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_update_guid = sync_guid;
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!expected_update_guid.empty()) {
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(1U, change_list.size());
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(expected_update_guid, GetGUID(change_list[0].sync_data()));
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                change_list[0].change_type());
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(0U, change_list.size());
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Adjust the expectations based on the expectation enums.
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_cases[i].turl_uniquified == LOCAL) {
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(test_cases[i].keywords_conflict);
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_local_keyword = ASCIIToUTF16("localkeyword_");
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_cases[i].turl_uniquified == SYNC) {
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(test_cases[i].keywords_conflict);
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_sync_keyword = ASCIIToUTF16("localkeyword_");
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check for TemplateURLs expected in the model. Note that this is checked
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // by GUID rather than the initial pointer, as a merge could occur (the
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sync TemplateURL overtakes the local one). Also remove the present
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TemplateURL when done so the next test case starts with a clean slate.
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_cases[i].present_in_model == LOCAL ||
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        test_cases[i].present_in_model == BOTH) {
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(model()->GetTemplateURLForGUID(local_guid));
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(expected_local_keyword, local_turl->keyword());
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(local_url, local_turl->url());
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(local_last_modified, local_turl->last_modified().ToTimeT());
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model()->Remove(model()->GetTemplateURLForGUID(local_guid));
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_cases[i].present_in_model == SYNC ||
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        test_cases[i].present_in_model == BOTH) {
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(model()->GetTemplateURLForGUID(sync_guid));
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(expected_sync_keyword, sync_turl->keyword());
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(sync_url, sync_turl->url());
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(sync_last_modified, sync_turl->last_modified().ToTimeT());
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model()->Remove(model()->GetTemplateURLForGUID(sync_guid));
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }  // for
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergePrepopulatedEngine) {
20865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<TemplateURLData> default_turl(
20872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(NULL));
20882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Merge with an initial list containing a prepopulated engine with a wrong
20902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // URL.
20912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList list;
20922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TemplateURL> sync_turl(CopyTemplateURL(default_turl.get(),
20932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http://wrong.url.com?q={searchTerms}", "default"));
20942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  list.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(*sync_turl));
20952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
20962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES, list, PassProcessor(),
20972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateAndPassSyncErrorFactory());
20982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TemplateURL* result_turl = model()->GetTemplateURLForGUID("default");
21002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(result_turl);
21012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(default_turl->keyword(), result_turl->keyword());
21025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(default_turl->short_name, result_turl->short_name());
21032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(default_turl->url(), result_turl->url());
21042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, AddPrepopulatedEngine) {
21072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
21082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES, syncer::SyncDataList(), PassProcessor(),
21092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateAndPassSyncErrorFactory());
21102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<TemplateURLData> default_turl(
21122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(NULL));
21132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TemplateURL* sync_turl = CopyTemplateURL(default_turl.get(),
21142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http://wrong.url.com?q={searchTerms}", "default");
21152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add a prepopulated engine with a wrong URL.
21172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes;
21182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_ADD,
21192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         sync_turl));
21202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes);
21212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TemplateURL* result_turl = model()->GetTemplateURLForGUID("default");
21232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(result_turl);
21242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(default_turl->keyword(), result_turl->keyword());
21255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(default_turl->short_name, result_turl->short_name());
21262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(default_turl->url(), result_turl->url());
21272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, UpdatePrepopulatedEngine) {
21305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<TemplateURLData> default_turl(
21312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(NULL));
21322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  TemplateURLData data = *default_turl;
21342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.SetURL("http://old.wrong.url.com?q={searchTerms}");
21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.sync_guid = "default";
2136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  model()->Add(new TemplateURL(data));
21372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
21392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES, syncer::SyncDataList(), PassProcessor(),
21402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateAndPassSyncErrorFactory());
21412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TemplateURL* sync_turl = CopyTemplateURL(default_turl.get(),
21432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http://new.wrong.url.com?q={searchTerms}", "default");
21442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the engine in the model, which is prepopulated, with a new one.
21462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Both have wrong URLs, but it should still get corrected.
21472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes;
21482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  changes.push_back(CreateTestSyncChange(syncer::SyncChange::ACTION_UPDATE,
21492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         sync_turl));
21502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model()->ProcessSyncChanges(FROM_HERE, changes);
21512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TemplateURL* result_turl = model()->GetTemplateURLForGUID("default");
21532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(result_turl);
21542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(default_turl->keyword(), result_turl->keyword());
21555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(default_turl->short_name, result_turl->short_name());
21562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(default_turl->url(), result_turl->url());
21572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeEditedPrepopulatedEngine) {
21605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<TemplateURLData> default_turl(
21612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(NULL));
21622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  TemplateURLData data(*default_turl);
21642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.safe_for_autoreplace = false;
21652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.SetKeyword(ASCIIToUTF16("new_kw"));
21662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.short_name = ASCIIToUTF16("my name");
21672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.SetURL("http://wrong.url.com?q={searchTerms}");
21682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.date_created = Time::FromTimeT(50);
21692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.last_modified = Time::FromTimeT(50);
21702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.sync_guid = "default";
2171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  model()->Add(new TemplateURL(data));
21722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.date_created = Time::FromTimeT(100);
21742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.last_modified = Time::FromTimeT(100);
2175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<TemplateURL> sync_turl(new TemplateURL(data));
21762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList list;
21772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  list.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(*sync_turl));
21782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
21792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES, list, PassProcessor(),
21802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateAndPassSyncErrorFactory());
21812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TemplateURL* result_turl = model()->GetTemplateURLForGUID("default");
21832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(result_turl);
21842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("new_kw"), result_turl->keyword());
21852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16("my name"), result_turl->short_name());
21862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(default_turl->url(), result_turl->url());
21872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, MergeNonEditedPrepopulatedEngine) {
21905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<TemplateURLData> default_turl(
21912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(NULL));
21922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  TemplateURLData data(*default_turl);
21942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.safe_for_autoreplace = true;  // Can be replaced with built-in values.
21952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.SetKeyword(ASCIIToUTF16("new_kw"));
21962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.short_name = ASCIIToUTF16("my name");
21972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.SetURL("http://wrong.url.com?q={searchTerms}");
21982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.date_created = Time::FromTimeT(50);
21992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.last_modified = Time::FromTimeT(50);
22002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.sync_guid = "default";
2201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  model()->Add(new TemplateURL(data));
22022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.date_created = Time::FromTimeT(100);
22042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.last_modified = Time::FromTimeT(100);
2205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<TemplateURL> sync_turl(new TemplateURL(data));
22062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList list;
22072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  list.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(*sync_turl));
22082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result = model()->MergeDataAndStartSyncing(
22092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::SEARCH_ENGINES, list, PassProcessor(),
22102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateAndPassSyncErrorFactory());
22112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TemplateURL* result_turl = model()->GetTemplateURLForGUID("default");
22132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(result_turl);
22142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(default_turl->keyword(), result_turl->keyword());
22155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(default_turl->short_name, result_turl->short_name());
22162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(default_turl->url(), result_turl->url());
22172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
22190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)TEST_F(TemplateURLServiceSyncTest, GUIDUpdatedOnDefaultSearchChange) {
22200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  const char kGUID[] = "initdefault";
22210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("what"),
22220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)                                     "http://thewhat.com/{searchTerms}",
22230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)                                     kGUID));
22240de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  model()->SetUserSelectedDefaultSearchProvider(
22250de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)      model()->GetTemplateURLForGUID(kGUID));
22260de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
22270de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  const TemplateURL* default_search = model()->GetDefaultSearchProvider();
22280de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  ASSERT_TRUE(default_search);
22290de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
22300de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  const char kNewGUID[] = "newdefault";
22310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  model()->Add(CreateTestTemplateURL(ASCIIToUTF16("what"),
22320de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)                                     "http://thewhat.com/{searchTerms}",
22330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)                                     kNewGUID));
22340de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  model()->SetUserSelectedDefaultSearchProvider(
22350de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)      model()->GetTemplateURLForGUID(kNewGUID));
22360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
22370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  EXPECT_EQ(kNewGUID, profile_a()->GetTestingPrefService()->GetString(
22380de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)      prefs::kSyncedDefaultSearchProviderGUID));
22390de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}
2240