12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync/glue/favicon_cache.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/time/time.h"
119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_notifications.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_service.h"
14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "sync/api/attachments/attachment_id.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "sync/api/sync_change_processor_wrapper_for_test.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/sync_error_factory_mock.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "sync/api/time.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/protocol/favicon_image_specifics.pb.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/protocol/favicon_tracking_specifics.pb.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/protocol/sync.pb.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace browser_sync {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Total number of favicons to use in sync test batches.
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kFaviconBatchSize = 10;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Maximum number of favicons to sync.
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMaxSyncFavicons = kFaviconBatchSize*2;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TestChangeProcessor --------------------------------------------------------
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Dummy SyncChangeProcessor used to help review what SyncChanges are pushed
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// back up to Sync.
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestChangeProcessor : public syncer::SyncChangeProcessor {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestChangeProcessor();
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TestChangeProcessor();
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store a copy of all the changes passed in so we can examine them later.
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual syncer::SyncError ProcessSyncChanges(
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const tracked_objects::Location& from_here,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const syncer::SyncChangeList& change_list) OVERRIDE;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      OVERRIDE {
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return syncer::SyncDataList();
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool contains_guid(const std::string& guid) const {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return change_map_.count(guid) != 0;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChange change_for_guid(const std::string& guid) const {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(contains_guid(guid));
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return change_map_.find(guid)->second;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the last change list received, and resets the internal list.
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList GetAndResetChangeList() {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncer::SyncChangeList list;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list.swap(change_list_);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return list;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_erroneous(bool erroneous) { erroneous_ = erroneous; }
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Track the changes received in ProcessSyncChanges.
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, syncer::SyncChange> change_map_;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList change_list_;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool erroneous_;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestChangeProcessor);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestChangeProcessor::TestChangeProcessor() : erroneous_(false) {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestChangeProcessor::~TestChangeProcessor() {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)syncer::SyncError TestChangeProcessor::ProcessSyncChanges(
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const tracked_objects::Location& from_here,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const syncer::SyncChangeList& change_list) {
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (erroneous_) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return syncer::SyncError(
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        FROM_HERE,
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        syncer::SyncError::DATATYPE_ERROR,
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "Some error.",
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        change_list[0].sync_data().GetDataType());
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_list_.insert(change_list_.end(),
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      change_list.begin(),
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      change_list.end());
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_map_.erase(change_map_.begin(), change_map_.end());
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (syncer::SyncChangeList::const_iterator iter = change_list.begin();
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      iter != change_list.end(); ++iter) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    change_map_[iter->sync_data().GetTitle()] = *iter;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return syncer::SyncError();
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TestFaviconData ------------------------------------------------------------
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct TestFaviconData {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestFaviconData() : last_visit_time(0), is_bookmarked(false) {}
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL page_url;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL icon_url;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string image_16;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string image_32;
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string image_64;
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int64 last_visit_time;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_bookmarked;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestFaviconData BuildFaviconData(int index) {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestFaviconData data;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.page_url = GURL(base::StringPrintf("http://bla.com/%.2i.html", index));
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.icon_url = GURL(base::StringPrintf("http://bla.com/%.2i.ico", index));
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.image_16 = base::StringPrintf("16 %i", index);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(zea): enable this once the cache supports writing them.
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // data.image_32 = base::StringPrintf("32 %i", index);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // data.image_64 = base::StringPrintf("64 %i", index);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.last_visit_time = index;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return data;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FillImageSpecifics(
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const TestFaviconData& test_data,
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::FaviconImageSpecifics* image_specifics) {
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  image_specifics->set_favicon_url(test_data.icon_url.spec());
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!test_data.image_16.empty()) {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_specifics->mutable_favicon_web()->set_height(16);
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_specifics->mutable_favicon_web()->set_width(16);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_specifics->mutable_favicon_web()->set_favicon(test_data.image_16);
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!test_data.image_32.empty()) {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_specifics->mutable_favicon_web_32()->set_height(32);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_specifics->mutable_favicon_web_32()->set_width(32);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_specifics->mutable_favicon_web_32()->set_favicon(test_data.image_32);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!test_data.image_64.empty()) {
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_specifics->mutable_favicon_touch_64()->set_height(64);
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_specifics->mutable_favicon_touch_64()->set_width(64);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_specifics->mutable_favicon_touch_64()->
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        set_favicon(test_data.image_64);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FillTrackingSpecifics(
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const TestFaviconData& test_data,
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::FaviconTrackingSpecifics* tracking_specifics) {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tracking_specifics->set_favicon_url(test_data.icon_url.spec());
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tracking_specifics->set_last_visit_time_ms(test_data.last_visit_time);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tracking_specifics->set_is_bookmarked(test_data.is_bookmarked);
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)testing::AssertionResult CompareFaviconDataToSpecifics(
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const TestFaviconData& test_data,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const sync_pb::EntitySpecifics& specifics) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (specifics.has_favicon_image()) {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::FaviconImageSpecifics image_specifics = specifics.favicon_image();
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (image_specifics.favicon_url() != test_data.icon_url.spec())
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Image icon url doesn't match.";
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!test_data.image_16.empty()) {
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (image_specifics.favicon_web().favicon() != test_data.image_16 ||
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          image_specifics.favicon_web().height() != 16 ||
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          image_specifics.favicon_web().width() != 16) {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return testing::AssertionFailure() << "16p image data doesn't match.";
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (image_specifics.has_favicon_web()) {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Missing 16p favicon.";
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!test_data.image_32.empty()) {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (image_specifics.favicon_web_32().favicon() != test_data.image_32 ||
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          image_specifics.favicon_web().height() != 32 ||
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          image_specifics.favicon_web().width() != 32) {
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return testing::AssertionFailure() << "32p image data doesn't match.";
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (image_specifics.has_favicon_web_32()) {
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Missing 32p favicon.";
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!test_data.image_64.empty()) {
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (image_specifics.favicon_touch_64().favicon() != test_data.image_64 ||
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          image_specifics.favicon_web().height() != 64 ||
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          image_specifics.favicon_web().width() != 64) {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return testing::AssertionFailure() << "64p image data doesn't match.";
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (image_specifics.has_favicon_touch_64()) {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Missing 64p favicon.";
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::FaviconTrackingSpecifics tracking_specifics =
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        specifics.favicon_tracking();
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (tracking_specifics.favicon_url() != test_data.icon_url.spec())
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Tracking icon url doesn't match.";
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (tracking_specifics.last_visit_time_ms() != test_data.last_visit_time)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Visit time doesn't match.";
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (tracking_specifics.is_bookmarked() != test_data.is_bookmarked)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Bookmark status doens't match.";
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return testing::AssertionSuccess();
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)testing::AssertionResult VerifyChanges(
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncer::ModelType expected_model_type,
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<syncer::SyncChange::SyncChangeType>&
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        expected_change_types,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<int>& expected_icons,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const syncer::SyncChangeList& change_list) {
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(expected_change_types.size(), expected_icons.size());
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (change_list.size() != expected_icons.size())
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return testing::AssertionFailure() << "Change list size doesn't match.";
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < expected_icons.size(); ++i) {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData data = BuildFaviconData(expected_icons[i]);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (change_list[i].sync_data().GetDataType() != expected_model_type)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Change datatype doesn't match.";
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (change_list[i].change_type() != expected_change_types[i])
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Change type doesn't match.";
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (change_list[i].change_type() == syncer::SyncChange::ACTION_DELETE) {
225e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      if (syncer::SyncDataLocal(change_list[i].sync_data()).GetTag() !=
226e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          data.icon_url.spec())
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return testing::AssertionFailure() << "Deletion url does not match.";
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      testing::AssertionResult compare_result =
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CompareFaviconDataToSpecifics(
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              data,
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              change_list[i].sync_data().GetSpecifics());
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!compare_result)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return compare_result;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return testing::AssertionSuccess();
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Helper to extract the favicon id embedded in the tag of a sync
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// change.
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int GetFaviconId(const syncer::SyncChange change) {
243e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  std::string tag = syncer::SyncDataLocal(change.sync_data()).GetTag();
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const std::string kPrefix = "http://bla.com/";
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const std::string kSuffix = ".ico";
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (tag.find(kPrefix) != 0)
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return -1;
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string temp = tag.substr(kPrefix.length());
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (temp.rfind(kSuffix) <= 0)
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return -1;
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  temp = temp.substr(0, temp.rfind(kSuffix));
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int result = -1;
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!base::StringToInt(temp, &result))
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return -1;
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return result;
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SyncFaviconCacheTest : public testing::Test {
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SyncFaviconCacheTest();
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~SyncFaviconCacheTest() {}
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetUpInitialSync(const syncer::SyncDataList& initial_image_data,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        const syncer::SyncDataList& initial_tracking_data);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t GetFaviconCount() const;
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t GetTaskCount() const;
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing::AssertionResult ExpectFaviconEquals(
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const std::string& page_url,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const std::string& bytes) const;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing::AssertionResult VerifyLocalIcons(
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::vector<int>& expected_icons);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing::AssertionResult VerifyLocalCustomIcons(
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::vector<TestFaviconData>& expected_icons);
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<syncer::SyncChangeProcessor> CreateAndPassProcessor();
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<syncer::SyncErrorFactory> CreateAndPassSyncErrorFactory();
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FaviconCache* cache() { return &cache_; }
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestChangeProcessor* processor() { return sync_processor_.get(); }
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Finish an outstanding favicon load for the icon described in |test_data|.
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnCustomFaviconDataAvailable(const TestFaviconData& test_data);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Helper method to run the message loop after invoking
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // OnReceivedSyncFavicon, which posts an internal task.
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void TriggerSyncFaviconReceived(const GURL& page_url,
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  const GURL& icon_url,
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  const std::string& icon_bytes,
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  int64 last_visit_time_ms);
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoopForUI message_loop_;
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FaviconCache cache_;
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Our dummy ChangeProcessor used to inspect changes pushed to Sync.
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TestChangeProcessor> sync_processor_;
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> sync_processor_wrapper_;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncFaviconCacheTest::SyncFaviconCacheTest()
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : cache_(NULL, kMaxSyncFavicons),
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sync_processor_(new TestChangeProcessor),
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest(
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          sync_processor_.get())) {}
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFaviconCacheTest::SetUpInitialSync(
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const syncer::SyncDataList& initial_image_data,
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const syncer::SyncDataList& initial_tracking_data) {
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    initial_image_data,
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    CreateAndPassProcessor(),
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    CreateAndPassSyncErrorFactory());
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(0U, processor()->GetAndResetChangeList().size());
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    initial_tracking_data,
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    CreateAndPassProcessor(),
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    CreateAndPassSyncErrorFactory());
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(0U, processor()->GetAndResetChangeList().size());
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t SyncFaviconCacheTest::GetFaviconCount() const {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return cache_.NumFaviconsForTest();
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t SyncFaviconCacheTest::GetTaskCount() const {
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return cache_.NumTasksForTest();
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)testing::AssertionResult SyncFaviconCacheTest::ExpectFaviconEquals(
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& page_url,
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& bytes) const {
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL gurl(page_url);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedMemory> favicon;
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!cache_.GetSyncedFaviconForPageURL(gurl, &favicon))
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return testing::AssertionFailure() << "Favicon is missing.";
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (favicon->size() != bytes.size())
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return testing::AssertionFailure() << "Favicon sizes don't match.";
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < favicon->size(); ++i) {
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (bytes[i] != *(favicon->front() + i))
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Favicon data doesn't match.";
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return testing::AssertionSuccess();
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)testing::AssertionResult SyncFaviconCacheTest::VerifyLocalIcons(
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<int>& expected_icons) {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<TestFaviconData> expected_custom_icons;
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < expected_icons.size(); ++i) {
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_custom_icons.push_back(BuildFaviconData(expected_icons[i]));
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return VerifyLocalCustomIcons(expected_custom_icons);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)testing::AssertionResult SyncFaviconCacheTest::VerifyLocalCustomIcons(
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<TestFaviconData>& expected_custom_icons) {
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList image_data_list =
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->GetAllSyncData(syncer::FAVICON_IMAGES);
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList tracking_data_list =
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->GetAllSyncData(syncer::FAVICON_TRACKING);
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (expected_custom_icons.size() > image_data_list.size() ||
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_custom_icons.size() > tracking_data_list.size())
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return testing::AssertionFailure() << "Number of icons doesn't match.";
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < expected_custom_icons.size(); ++i) {
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const TestFaviconData& test_data = expected_custom_icons[i];
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Find the test data in the data lists. Assume that both lists have the
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // same ordering, which may not match the |expected_custom_icons| ordering.
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool found_match = false;
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t j = 0; j < image_data_list.size(); ++j) {
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (image_data_list[j].GetTitle() != test_data.icon_url.spec())
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      found_match = true;
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const sync_pb::FaviconImageSpecifics& image_specifics =
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          image_data_list[j].GetSpecifics().favicon_image();
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sync_pb::FaviconImageSpecifics expected_image_specifics;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FillImageSpecifics(test_data, &expected_image_specifics);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (image_specifics.SerializeAsString() !=
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          expected_image_specifics.SerializeAsString()) {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return testing::AssertionFailure() << "Image data doesn't match.";
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const sync_pb::FaviconTrackingSpecifics& tracking_specifics =
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          tracking_data_list[j].GetSpecifics().favicon_tracking();
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sync_pb::FaviconTrackingSpecifics expected_tracking_specifics;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FillTrackingSpecifics(test_data, &expected_tracking_specifics);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (tracking_specifics.SerializeAsString() !=
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          expected_tracking_specifics.SerializeAsString()) {
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return testing::AssertionFailure() << "Tracking data doesn't match.";
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!found_match)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return testing::AssertionFailure() << "Could not find favicon.";
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return testing::AssertionSuccess();
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<syncer::SyncChangeProcessor>
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncFaviconCacheTest::CreateAndPassProcessor() {
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scoped_ptr<syncer::SyncChangeProcessor>(
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<syncer::SyncErrorFactory> SyncFaviconCacheTest::
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateAndPassSyncErrorFactory() {
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scoped_ptr<syncer::SyncErrorFactory>(
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new syncer::SyncErrorFactoryMock());
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFaviconCacheTest::OnCustomFaviconDataAvailable(
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const TestFaviconData& test_data) {
414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!test_data.image_16.empty()) {
416f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    favicon_base::FaviconRawBitmapResult bitmap_result;
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.icon_url = test_data.icon_url;
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.pixel_size.set_width(16);
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.pixel_size.set_height(16);
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RefCountedString* temp_string = new base::RefCountedString();
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    temp_string->data() = test_data.image_16;
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.bitmap_data = temp_string;
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_results.push_back(bitmap_result);
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!test_data.image_32.empty()) {
426f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    favicon_base::FaviconRawBitmapResult bitmap_result;
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.icon_url = test_data.icon_url;
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.pixel_size.set_width(32);
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.pixel_size.set_height(32);
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RefCountedString* temp_string = new base::RefCountedString();
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    temp_string->data() = test_data.image_32;
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.bitmap_data = temp_string;
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_results.push_back(bitmap_result);
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!test_data.image_64.empty()) {
436f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    favicon_base::FaviconRawBitmapResult bitmap_result;
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.icon_url = test_data.icon_url;
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.pixel_size.set_width(64);
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.pixel_size.set_height(64);
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RefCountedString* temp_string = new base::RefCountedString();
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    temp_string->data() = test_data.image_64;
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_result.bitmap_data = temp_string;
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bitmap_results.push_back(bitmap_result);
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->OnFaviconDataAvailable(test_data.page_url, bitmap_results);
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SyncFaviconCacheTest::TriggerSyncFaviconReceived(
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& page_url,
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& icon_url,
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& icon_bytes,
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64 last_visit_time_ms) {
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  cache()->OnReceivedSyncFavicon(page_url,
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 icon_url,
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 icon_bytes,
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 last_visit_time_ms);
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_.RunUntilIdle();
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A freshly constructed cache should be empty.
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, Empty) {
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ReceiveSyncFavicon) {
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string page_url = "http://www.google.com";
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string fav_url = "http://www.google.com/favicon.ico";
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string bytes = "bytes";
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TriggerSyncFaviconReceived(GURL(page_url), GURL(fav_url), bytes, 0);
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1U, GetFaviconCount());
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(ExpectFaviconEquals(page_url, bytes));
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ReceiveEmptySyncFavicon) {
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string page_url = "http://www.google.com";
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string fav_url = "http://www.google.com/favicon.ico";
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string bytes = "bytes";
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TriggerSyncFaviconReceived(GURL(page_url),
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             GURL(fav_url),
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             std::string(),
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             0);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(ExpectFaviconEquals(page_url, std::string()));
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Then receive the actual favicon.
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TriggerSyncFaviconReceived(GURL(page_url), GURL(fav_url), bytes, 0);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1U, GetFaviconCount());
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(ExpectFaviconEquals(page_url, bytes));
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ReceiveUpdatedSyncFavicon) {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string page_url = "http://www.google.com";
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string fav_url = "http://www.google.com/favicon.ico";
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string bytes = "bytes";
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string bytes2 = "bytes2";
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TriggerSyncFaviconReceived(GURL(page_url), GURL(fav_url), bytes, 0);
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1U, GetFaviconCount());
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(ExpectFaviconEquals(page_url, bytes));
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The cache should not update existing favicons from tab sync favicons
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (which can be reassociated several times).
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TriggerSyncFaviconReceived(GURL(page_url), GURL(fav_url), bytes2, 0);
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1U, GetFaviconCount());
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(ExpectFaviconEquals(page_url, bytes));
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(ExpectFaviconEquals(page_url, bytes2));
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, MultipleMappings) {
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string page_url = "http://www.google.com";
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string page2_url = "http://bla.google.com";
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string fav_url = "http://www.google.com/favicon.ico";
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string bytes = "bytes";
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TriggerSyncFaviconReceived(GURL(page_url), GURL(fav_url), bytes, 0);
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1U, GetFaviconCount());
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(ExpectFaviconEquals(page_url, bytes));
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Map another page to the same favicon. They should share the same data.
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TriggerSyncFaviconReceived(GURL(page2_url), GURL(fav_url), bytes, 0);
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1U, GetFaviconCount());
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(ExpectFaviconEquals(page2_url, bytes));
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, SyncEmpty) {
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result =
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        syncer::SyncDataList(),
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_before_association());
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_after_association());
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  merge_result =
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        syncer::SyncDataList(),
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_before_association());
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_after_association());
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Setting up sync with existing local favicons should push those favicons into
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// sync.
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, SyncExistingLocal) {
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<syncer::SyncChange::SyncChangeType> expected_change_types;
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData favicon = BuildFaviconData(i);
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TriggerSyncFaviconReceived(favicon.page_url,
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               favicon.icon_url,
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               favicon.image_16,
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               i);
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_change_types.push_back(syncer::SyncChange::ACTION_ADD);
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result =
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        syncer::SyncDataList(),
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize,
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList change_list = processor()->GetAndResetChangeList();
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyChanges(syncer::FAVICON_IMAGES,
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_change_types,
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_icons,
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            change_list));
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  merge_result =
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        syncer::SyncDataList(),
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize,
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_list = processor()->GetAndResetChangeList();
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyChanges(syncer::FAVICON_TRACKING,
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_change_types,
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_icons,
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            change_list));
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Setting up sync with existing sync data should load that data into the local
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// cache.
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, SyncExistingRemote) {
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(BuildFaviconData(i),
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
619a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
620a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
621a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
622a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
623a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
624a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
627a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
628a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
629a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
630a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
631a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
632a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result =
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        initial_image_data,
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize,
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_added());
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_before_association());
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  merge_result =
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        initial_tracking_data,
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize,
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_modified());
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalIcons(expected_icons));
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Setting up sync with local data and sync data should merge the two image
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// sets, with remote data having priority in case both exist.
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, SyncMergesImages) {
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // First go through and add local 16p favicons.
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData favicon = BuildFaviconData(i);
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TriggerSyncFaviconReceived(favicon.page_url,
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               favicon.icon_url,
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               favicon.image_16,
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               i);
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Then go through and create the initial sync data, which does not have 16p
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // favicons for the first half, and has custom 16p favicons for the second.
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<syncer::SyncChange::SyncChangeType> expected_change_types;
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<TestFaviconData> expected_data;
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i < kFaviconBatchSize/2) {
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      test_data.image_16 = std::string();
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_icons.push_back(i);
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      test_data.image_16 += "custom";
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_data.push_back(test_data);
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(test_data,
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
698a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
699a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
700a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
701a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
702a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
703a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(test_data,
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
706a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
707a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
708a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
709a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
710a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
711a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result =
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        initial_image_data,
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize,
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize/2, changes.size());
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_modified());
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  merge_result =
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        initial_tracking_data,
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize,
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_modified());
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalIcons(expected_icons));
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalCustomIcons(expected_data));
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyChanges(syncer::FAVICON_IMAGES,
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_change_types,
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_icons,
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            changes));
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Setting up sync with local data and sync data should merge the two tracking
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// sets, such that the visit time is the most recent.
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, SyncMergesTracking) {
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // First go through and add local 16p favicons.
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData favicon = BuildFaviconData(i);
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TriggerSyncFaviconReceived(favicon.page_url,
758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               favicon.icon_url,
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               favicon.image_16,
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               i);
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Then go through and create the initial sync data, which for the first half
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the local has a newer visit, and for the second the remote does.
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<syncer::SyncChange::SyncChangeType> expected_change_types;
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<TestFaviconData> expected_data;
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i < kFaviconBatchSize/2) {
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      test_data.last_visit_time = i-1;
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_icons.push_back(i);
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      test_data.last_visit_time = i+1;
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_data.push_back(test_data);
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(test_data,
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
783a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
784a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
785a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
786a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
787a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
788a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(test_data,
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
791a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
792a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
793a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
794a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
795a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
796a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result =
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        initial_image_data,
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize,
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_modified());
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  merge_result =
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        initial_tracking_data,
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize,
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize/2, changes.size());
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_modified());
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_deleted());
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalIcons(expected_icons));
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalCustomIcons(expected_data));
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyChanges(syncer::FAVICON_TRACKING,
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_change_types,
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_icons,
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            changes));
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Receiving old icons (missing image data) should result in pushing the new
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// merged icons back to the remote syncer.
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ReceiveStaleImages) {
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList stale_changes;
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<syncer::SyncChange::SyncChangeType> expected_change_types;
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(BuildFaviconData(i),
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
848a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
849a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
850a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
851a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
852a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
853a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_specifics.mutable_favicon_image()->clear_favicon_web();
856a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    stale_changes.push_back(syncer::SyncChange(
857a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
858a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncChange::ACTION_UPDATE,
859a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
860a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            1,
861a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            image_specifics,
862a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
863a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
864a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
867a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
868a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
869a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
870a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
871a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
872a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now receive the same icons as an update, but with missing image data.
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, stale_changes);
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalIcons(expected_icons));
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ((unsigned long)kFaviconBatchSize, changes.size());
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyChanges(syncer::FAVICON_IMAGES,
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_change_types,
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_icons,
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            changes));
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// New icons should be added locally without pushing anything back to the
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// remote syncer.
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ReceiveNewImages) {
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList new_changes;
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(test_data,
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
900a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    new_changes.push_back(syncer::SyncChange(
901a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
902a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncChange::ACTION_UPDATE,
903a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
904a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            1,
905a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            image_specifics,
906a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
907a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
908a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
909a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    image_specifics.mutable_favicon_image()
910a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        ->mutable_favicon_web()
911a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        ->mutable_favicon()
912a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        ->append("old");
913a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
914a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
915a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
916a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
917a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
918a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
921a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
922a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
923a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
924a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
925a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
926a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now receive the new icons as an update.
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, new_changes);
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalIcons(expected_icons));
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Recieving the same icons as the local data should have no effect.
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ReceiveSameImages) {
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList same_changes;
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(test_data,
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
948a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    same_changes.push_back(syncer::SyncChange(
949a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
950a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncChange::ACTION_UPDATE,
951a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
952a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            1,
953a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            image_specifics,
954a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
955a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
956a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
957a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
958a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
959a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
960a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
961a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
962a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
965a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
966a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
967a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
968a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
969a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
970a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now receive the new icons as an update.
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, same_changes);
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalIcons(expected_icons));
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Receiving stale tracking (old visit times) should result in pushing back
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the newer visit times to the remote syncer.
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ReceiveStaleTracking) {
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList stale_changes;
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<syncer::SyncChange::SyncChangeType> expected_change_types;
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(BuildFaviconData(i),
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
993a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
994a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
995a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
996a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
997a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
998a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1002a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1003a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1004a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1005a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1006a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1007a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(-1);
1009a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    stale_changes.push_back(syncer::SyncChange(
1010a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
1011a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncChange::ACTION_UPDATE,
1012a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
1013a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            1,
1014a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            tracking_specifics,
1015a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
1016a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
1017a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now receive the same icons as an update, but with missing image data.
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, stale_changes);
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalIcons(expected_icons));
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ((unsigned long)kFaviconBatchSize, changes.size());
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyChanges(syncer::FAVICON_TRACKING,
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_change_types,
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            expected_icons,
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            changes));
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// New tracking information should be added locally without pushing anything
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// back to the remote syncer.
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ReceiveNewTracking) {
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList new_changes;
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We start from one here so that we don't have to deal with a -1 visit time.
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 1; i <= kFaviconBatchSize; ++i) {
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(BuildFaviconData(i),
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
1045a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1046a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1047a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1048a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1049a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1050a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1053a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    new_changes.push_back(syncer::SyncChange(
1054a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
1055a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncChange::ACTION_UPDATE,
1056a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
1057a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            1,
1058a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            tracking_specifics,
1059a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
1060a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
1061a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(i-1);
1063a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1064a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1065a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1066a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1067a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1068a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now receive the new icons as an update.
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, new_changes);
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalIcons(expected_icons));
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Receiving the same tracking information as the local data should have no
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// effect.
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ReceiveSameTracking) {
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList same_changes;
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(BuildFaviconData(i),
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
1090a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1091a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1092a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1093a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1094a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1095a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1098a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1099a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
1104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    same_changes.push_back(syncer::SyncChange(
1105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
1106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncChange::ACTION_UPDATE,
1107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
1108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            1,
1109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            tracking_specifics,
1110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
1111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
1112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now receive the new icons as an update.
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, same_changes);
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(VerifyLocalIcons(expected_icons));
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verify we can delete favicons after setting up sync.
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, DeleteFavicons) {
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  syncer::SyncChangeList tracking_deletions, image_deletions;
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(BuildFaviconData(i),
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
1131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1135a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
1145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    tracking_deletions.push_back(syncer::SyncChange(
1146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
1147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncChange::ACTION_DELETE,
1148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
1149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            1,
1150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            tracking_specifics,
1151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
1152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
1153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
1154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    image_deletions.push_back(syncer::SyncChange(
1155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
1156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncChange::ACTION_DELETE,
1157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
1158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            1,
1159a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            image_specifics,
1160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
1161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
1162a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now receive the tracking deletions. Since we'll still have orphan data,
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the favicon count should remain the same.
1169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
1170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, tracking_deletions);
1171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Once the image deletions arrive, the favicon count should be 0 again.
1175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, image_deletions);
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that MergeDataAndStartSyncing enforces the sync favicon limit by
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// dropping local icons.
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ExpireOnMergeData) {
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set up sync so it has the maximum number of favicons, while the local has
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the same amount of different favicons.
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kMaxSyncFavicons; ++i) {
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(BuildFaviconData(i),
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
1192a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1193a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1194a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1196a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1200a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1201a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1202a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1203a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1204a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1205a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData favicon = BuildFaviconData(i+kMaxSyncFavicons);
1209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TriggerSyncFaviconReceived(favicon.page_url,
1210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               favicon.icon_url,
1211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               favicon.image_16,
1212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               i+kMaxSyncFavicons);
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(VerifyLocalIcons(expected_icons));
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Drops image part of the unsynced icons.
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncMergeResult merge_result =
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        initial_image_data,
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
1223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ((unsigned long)kMaxSyncFavicons * 2,
1224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            GetFaviconCount());  // Still have tracking.
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kMaxSyncFavicons,
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_added());
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_modified());
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_deleted());
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_before_association());
1232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons * 2, merge_result.num_items_after_association());
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Drops tracking part of the unsynced icons.
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  merge_result =
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        initial_tracking_data,
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassProcessor(),
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        CreateAndPassSyncErrorFactory());
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kMaxSyncFavicons,
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, merge_result.num_items_added());
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_modified());
1245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_deleted());
1246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons * 2, merge_result.num_items_before_association());
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_after_association());
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyLocalIcons(expected_icons));
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Receiving sync additions (via ProcessSyncChanges) should not trigger
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// expirations.
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, NoExpireOnProcessSyncChanges) {
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList image_changes, tracking_changes;
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kMaxSyncFavicons; ++i) {
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(BuildFaviconData(i),
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
1263a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1264a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1265a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1266a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1267a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1271a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1272a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1273a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1274a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1275a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1276a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Set up new tracking specifics for the icons received at change time.
12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i + kMaxSyncFavicons);
12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(BuildFaviconData(i + kMaxSyncFavicons),
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
1281a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    image_changes.push_back(syncer::SyncChange(
1282a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
1283a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncChange::ACTION_ADD,
1284a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
1285a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            1,
1286a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            image_specifics,
1287a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
1288a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
1289a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i + kMaxSyncFavicons),
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1292a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    tracking_changes.push_back(syncer::SyncChange(
1293a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        FROM_HERE,
1294a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncChange::ACTION_ADD,
1295a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::SyncData::CreateRemoteData(
1296a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            1,
1297a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            tracking_specifics,
1298a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::Time(),
1299a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentIdList(),
1300a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            syncer::AttachmentServiceProxyForTest::Create())));
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now receive the new icons as an update.
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kMaxSyncFavicons, GetFaviconCount());
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, image_changes);
13082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, tracking_changes);
13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyLocalIcons(expected_icons));
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_GT(GetFaviconCount(), (unsigned long)kMaxSyncFavicons);
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that visiting a new page triggers a favicon load and a sync addition.
13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, AddOnFaviconVisited) {
13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetTaskCount());
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OnCustomFaviconDataAvailable(test_data);
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(2U, changes.size());
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(syncer::FAVICON_IMAGES, changes[0].sync_data().GetDataType());
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CompareFaviconDataToSpecifics(test_data,
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      changes[0].sync_data().GetSpecifics()));
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(syncer::FAVICON_TRACKING, changes[1].sync_data().GetDataType());
13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Just verify the favicon url for the tracking specifics and that the
13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // timestamp is non-null.
13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[1].change_type());
13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(test_data.icon_url.spec(),
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              changes[1].sync_data().GetSpecifics().favicon_tracking().
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  favicon_url());
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_NE(changes[1].sync_data().GetSpecifics().favicon_tracking().
13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  last_visit_time_ms(), 0);
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that visiting a known page does not trigger a favicon load and just
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// updates the sync tracking info.
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, UpdateOnFaviconVisited) {
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add the favicons.
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OnCustomFaviconDataAvailable(test_data);
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Visit the favicons again.
13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(1U, changes.size());
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Just verify the favicon url for the tracking specifics and that the
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // timestamp is non-null.
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(test_data.icon_url.spec(),
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              changes[0].sync_data().GetSpecifics().favicon_tracking().
13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  favicon_url());
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_NE(changes[0].sync_data().GetSpecifics().favicon_tracking().
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  last_visit_time_ms(), 0);
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure we properly expire old synced favicons as new ones are updated.
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ExpireOnFaviconVisited) {
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add the initial favicons.
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kMaxSyncFavicons; ++i) {
14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OnCustomFaviconDataAvailable(test_data);
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Visit some new favicons, triggering expirations of the old favicons.
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData old_favicon = BuildFaviconData(i);
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i + kMaxSyncFavicons);
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OnCustomFaviconDataAvailable(test_data);
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(4U, changes.size());
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CompareFaviconDataToSpecifics(test_data,
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      changes[0].sync_data().GetSpecifics()));
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, changes[1].change_type());
1422e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    EXPECT_EQ(old_favicon.icon_url.spec(),
1423e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch              syncer::SyncDataLocal(changes[1].sync_data()).GetTag());
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[2].change_type());
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(test_data.icon_url.spec(),
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              changes[2].sync_data().GetSpecifics().favicon_tracking().
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  favicon_url());
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_NE(changes[2].sync_data().GetSpecifics().favicon_tracking().
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  last_visit_time_ms(), 0);
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, changes[3].change_type());
1432e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    EXPECT_EQ(old_favicon.icon_url.spec(),
1433e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch              syncer::SyncDataLocal(changes[3].sync_data()).GetTag());
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kMaxSyncFavicons, GetFaviconCount());
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A full history clear notification should result in all synced favicons being
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// deleted.
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, HistoryFullClear) {
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<syncer::SyncChange::SyncChangeType> expected_deletions;
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_icons.push_back(i);
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_deletions.push_back(syncer::SyncChange::ACTION_DELETE);
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(test_data,
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
1453a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1454a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1455a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1456a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1457a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1458a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1461a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1462a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1463a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1464a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1465a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1466a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(changes.empty());
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::URLsDeletedDetails deletions;
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  deletions.all_history = true;
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::NotificationService::current()->Notify(
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        chrome::NOTIFICATION_HISTORY_URLS_DELETED,
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Source<Profile>(NULL),
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Details<history::URLsDeletedDetails>(&deletions));
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  changes = processor()->GetAndResetChangeList();
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(changes.size(), (unsigned long)kFaviconBatchSize*2);
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes_1, changes_2;
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    changes_1.push_back(changes[i]);
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    changes_2.push_back(changes[i + kFaviconBatchSize]);
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyChanges(syncer::FAVICON_IMAGES,
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                expected_deletions,
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                expected_icons,
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                changes_1);
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyChanges(syncer::FAVICON_TRACKING,
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                expected_deletions,
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                expected_icons,
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                changes_2);
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A partial history clear notification should result in the expired favicons
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// also being deleted from sync.
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, HistorySubsetClear) {
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<int> expected_icons;
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<syncer::SyncChange::SyncChangeType> expected_deletions;
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::URLsDeletedDetails deletions;
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i < kFaviconBatchSize/2) {
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_icons.push_back(i);
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_deletions.push_back(syncer::SyncChange::ACTION_DELETE);
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      deletions.favicon_urls.insert(test_data.icon_url);
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillImageSpecifics(test_data,
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
1515a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1516a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1517a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1518a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1519a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1520a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1523a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1524a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1525a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1526a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1527a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1528a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(changes.empty());
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::NotificationService::current()->Notify(
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        chrome::NOTIFICATION_HISTORY_URLS_DELETED,
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Source<Profile>(NULL),
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Details<history::URLsDeletedDetails>(&deletions));
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize/2, GetFaviconCount());
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  changes = processor()->GetAndResetChangeList();
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(changes.size(), (unsigned long)kFaviconBatchSize);
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syncer::SyncChangeList changes_1, changes_2;
15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < kFaviconBatchSize/2; ++i) {
15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    changes_1.push_back(changes[i]);
15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    changes_2.push_back(changes[i + kFaviconBatchSize/2]);
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyChanges(syncer::FAVICON_IMAGES,
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                expected_deletions,
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                expected_icons,
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                changes_1);
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyChanges(syncer::FAVICON_TRACKING,
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                expected_deletions,
15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                expected_icons,
15552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                changes_2);
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Any favicon urls with the "data" scheme should be ignored.
1559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, IgnoreDataScheme) {
1560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
1561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
1562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<int> expected_icons;
1563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
1565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
1566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    cache()->OnFaviconVisited(test_data.page_url, GURL());
1567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetTaskCount());
1570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
1572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
1573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    test_data.icon_url = GURL("data:image/png;base64;blabla");
1574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(test_data.icon_url.is_valid());
1575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnCustomFaviconDataAvailable(test_data);
1576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
1579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
1580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
1581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(changes.empty());
1582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// When visiting a page we've already loaded the favicon for, don't attempt to
1585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// reload the favicon, just update the visit time using the cached icon url.
1586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, ReuseCachedIconUrl) {
1587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
1588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
1589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<int> expected_icons;
1590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
1592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    expected_icons.push_back(i);
1593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
1594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
1595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetTaskCount());
1598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
1600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
1601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnCustomFaviconDataAvailable(test_data);
1602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  processor()->GetAndResetChangeList();
1604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
1605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
1606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
1608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
1609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
1610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
1611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(1U, changes.size());
1612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Just verify the favicon url for the tracking specifics and that the
1613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // timestamp is non-null.
1614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
1615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(test_data.icon_url.spec(),
1616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              changes[0].sync_data().GetSpecifics().favicon_tracking().
1617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  favicon_url());
1618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_NE(changes[0].sync_data().GetSpecifics().favicon_tracking().
1619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  last_visit_time_ms(), 0);
1620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
1622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// If we wind up with orphan image/tracking nodes, then receive an update
1625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// for those favicons, we should lazily create the missing nodes.
1626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, UpdatedOrphans) {
1627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
1628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
1629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  syncer::SyncChangeList initial_image_changes;
1631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  syncer::SyncChangeList initial_tracking_changes;
1632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize; ++i) {
1633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
1634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Even favicons have image data but no tracking data. Odd favicons have
1635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // tracking data but no image data.
1636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (i % 2 == 0) {
1637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      sync_pb::EntitySpecifics image_specifics;
1638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FillImageSpecifics(BuildFaviconData(i),
1639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         image_specifics.mutable_favicon_image());
1640a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      initial_image_changes.push_back(syncer::SyncChange(
1641a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          FROM_HERE,
1642a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          syncer::SyncChange::ACTION_ADD,
1643a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          syncer::SyncData::CreateRemoteData(
1644a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              1,
1645a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              image_specifics,
1646a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              base::Time(),
1647a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              syncer::AttachmentIdList(),
1648a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              syncer::AttachmentServiceProxyForTest::Create())));
1649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
1650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      sync_pb::EntitySpecifics tracking_specifics;
1651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FillTrackingSpecifics(BuildFaviconData(i),
1652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            tracking_specifics.mutable_favicon_tracking());
1653a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      initial_tracking_changes.push_back(syncer::SyncChange(
1654a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          FROM_HERE,
1655a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          syncer::SyncChange::ACTION_ADD,
1656a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          syncer::SyncData::CreateRemoteData(
1657a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              1,
1658a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              tracking_specifics,
1659a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              base::Time(),
1660a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              syncer::AttachmentIdList(),
1661a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              syncer::AttachmentServiceProxyForTest::Create())));
1662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, initial_image_changes);
1666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  cache()->ProcessSyncChanges(FROM_HERE, initial_tracking_changes);
1667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
1668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
1669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 0; i < kFaviconBatchSize/2; ++i) {
1671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
1672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    cache()->OnFaviconVisited(test_data.page_url, GURL());
1673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1U, GetTaskCount());
1674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnCustomFaviconDataAvailable(test_data);
1675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
1676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Even favicons had image data, so should now receive new tracking data
1678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // and updated image data (we allow one update after the initial add).
1679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Odd favicons had tracking so should now receive new image data and
1680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // updated tracking data.
1681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (i % 2 == 0) {
1682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ASSERT_EQ(2U, changes.size());
1683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
1684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_TRUE(
1685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CompareFaviconDataToSpecifics(test_data,
1686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        changes[0].sync_data().GetSpecifics()));
1687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[1].change_type());
1688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_EQ(test_data.icon_url.spec(),
1689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                changes[1].sync_data().GetSpecifics().favicon_tracking().
1690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    favicon_url());
1691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_NE(changes[1].sync_data().GetSpecifics().favicon_tracking().
1692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    last_visit_time_ms(), 0);
1693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
1694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ASSERT_EQ(2U, changes.size());
1695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
1696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_TRUE(
1697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CompareFaviconDataToSpecifics(test_data,
1698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        changes[0].sync_data().GetSpecifics()));
1699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[1].change_type());
1700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_EQ(test_data.icon_url.spec(),
1701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                changes[1].sync_data().GetSpecifics().favicon_tracking().
1702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    favicon_url());
1703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_NE(changes[1].sync_data().GetSpecifics().favicon_tracking().
1704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    last_visit_time_ms(), 0);
1705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
1709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
1710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Verify that orphaned favicon images don't result in creating invalid
17137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// favicon tracking data.
17147dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(SyncFaviconCacheTest, PartialAssociationInfo) {
17157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  syncer::SyncDataList initial_image_data, initial_tracking_data;
17167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (int i = 0; i < kFaviconBatchSize; ++i) {
17177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    sync_pb::EntitySpecifics image_specifics;
17187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    FillImageSpecifics(BuildFaviconData(i),
17197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       image_specifics.mutable_favicon_image());
1720a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1721a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1722a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1723a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1724a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1725a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
17267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    image_specifics.mutable_favicon_image()->clear_favicon_web();
17277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
17287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
17297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SetUpInitialSync(initial_image_data, initial_tracking_data);
17307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  syncer::SyncChangeList change_list = processor()->GetAndResetChangeList();
17317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(change_list.empty());
17327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
17337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
17347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
17357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Tests that we don't choke if a favicon visit node with a null visit time is
17367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// present (see crbug.com/258196) and an update is made.
17377dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(SyncFaviconCacheTest, NullFaviconVisitTime) {
17387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(0U, GetFaviconCount());
17397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
17407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  syncer::SyncDataList initial_image_data, initial_tracking_data;
17417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::vector<int> expected_icons;
17427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (int i = 0; i < kFaviconBatchSize; ++i) {
17437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    expected_icons.push_back(i);
17447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
17457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    FillImageSpecifics(BuildFaviconData(i),
17467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       image_specifics.mutable_favicon_image());
1747a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1748a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1749a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1750a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1751a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1752a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
17537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    FillTrackingSpecifics(BuildFaviconData(i),
17547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                          tracking_specifics.mutable_favicon_tracking());
17557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(
17567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        syncer::TimeToProtoTime(base::Time()));
1757a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1758a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1759a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1760a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1761a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1762a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
17637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
17647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
17657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
17667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    initial_image_data,
17677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    CreateAndPassProcessor(),
17687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    CreateAndPassSyncErrorFactory());
17697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_EQ(0U, processor()->GetAndResetChangeList().size());
17707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
17717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    initial_tracking_data,
17727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    CreateAndPassProcessor(),
17737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                    CreateAndPassSyncErrorFactory());
17747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_EQ((unsigned long)kFaviconBatchSize,
17757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            processor()->GetAndResetChangeList().size());
17767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
17777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
17787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Visit the favicons again.
17797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(0U, GetTaskCount());
17807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (int i = 0; i < kFaviconBatchSize; ++i) {
17817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TestFaviconData test_data = BuildFaviconData(i);
17827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
17837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
17847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
17857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ASSERT_EQ(1U, changes.size());
17867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Just verify the favicon url for the tracking specifics and that the
17877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // timestamp is non-null.
17887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
17897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(test_data.icon_url.spec(),
17907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              changes[0].sync_data().GetSpecifics().favicon_tracking().
17917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  favicon_url());
17927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_NE(changes[0].sync_data().GetSpecifics().favicon_tracking().
17937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  last_visit_time_ms(), 0);
17947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
17957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(0U, GetTaskCount());
17967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
17977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
17987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
17994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// If another synced client has a clock skewed towards the future, it's possible
18004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// that favicons added locally will be expired as they are added. Ensure this
18014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// doesn't crash (see crbug.com/306150).
18024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SyncFaviconCacheTest, VisitFaviconClockSkew) {
18034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0U, GetFaviconCount());
18044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const int kClockSkew = 20;  // 20 minutes in the future.
18054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
18064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Set up sync with kMaxSyncFavicons starting kClockSkew minutes in the
18074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // future.
18084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
18094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (int i = 0; i < kMaxSyncFavicons; ++i) {
18104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
18114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i);
18124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    test_data.last_visit_time =
18134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        syncer::TimeToProtoTime(
18144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            base::Time::Now() + base::TimeDelta::FromMinutes(kClockSkew));
18154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FillImageSpecifics(test_data,
18164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       image_specifics.mutable_favicon_image());
1817a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1818a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1819a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1820a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1821a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1822a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
18234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FillTrackingSpecifics(test_data,
18244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1825a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1826a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1827a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1828a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1829a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1830a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
18314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
18324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
18334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
18344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Visit some new favicons with local time, which will be expired as they
18354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // are added.
18364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
18374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (int i = 0; i < kClockSkew; ++i) {
18384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TestFaviconData test_data = BuildFaviconData(i + kMaxSyncFavicons);
18394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
18404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    OnCustomFaviconDataAvailable(test_data);
18414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
18424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // The changes will be an add followed by a delete for both the image and
18434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // tracking info.
18444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
18454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_EQ(changes.size(), 4U);
18464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_EQ(changes[0].change_type(), syncer::SyncChange::ACTION_ADD);
18474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_EQ(changes[0].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
18484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_EQ(changes[1].change_type(), syncer::SyncChange::ACTION_DELETE);
18494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_EQ(changes[1].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
18504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_EQ(changes[2].change_type(), syncer::SyncChange::ACTION_ADD);
18514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_EQ(changes[2].sync_data().GetDataType(), syncer::FAVICON_TRACKING);
18524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_EQ(changes[3].change_type(), syncer::SyncChange::ACTION_DELETE);
18534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_EQ(changes[3].sync_data().GetDataType(), syncer::FAVICON_TRACKING);
18544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
18554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0U, GetTaskCount());
18564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ((unsigned long)kMaxSyncFavicons, GetFaviconCount());
18574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
18584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1859a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Simulate a case where the set of tracking info and image info doesn't match,
1860a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// and there is more tracking info than the max. A local update should correctly
1861a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// determine whether to update/add an image/tracking entity.
1862a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(SyncFaviconCacheTest, MixedThreshold) {
1863a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // First go through and add local favicons.
1864a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = kMaxSyncFavicons; i < kMaxSyncFavicons + 5; ++i) {
1865a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TestFaviconData favicon = BuildFaviconData(i);
1866a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TriggerSyncFaviconReceived(favicon.page_url,
1867a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               favicon.icon_url,
1868a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               favicon.image_16,
1869a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               favicon.last_visit_time);
1870a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1871a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1872a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  syncer::SyncDataList initial_image_data, initial_tracking_data;
1873a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Then sync with enough favicons such that the tracking info is over the max
1874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // after merge completes.
1875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < kMaxSyncFavicons; ++i) {
1876a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    sync_pb::EntitySpecifics image_specifics;
1877a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Push the images forward by 5, to match the unsynced favicons.
1878a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FillImageSpecifics(BuildFaviconData(i + 5),
1879a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       image_specifics.mutable_favicon_image());
1880a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
1881a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1882a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        image_specifics,
1883a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1884a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1885a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
1886a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1887a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    sync_pb::EntitySpecifics tracking_specifics;
1888a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FillTrackingSpecifics(BuildFaviconData(i),
1889a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                          tracking_specifics.mutable_favicon_tracking());
1890a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
1891a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        1,
1892a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        tracking_specifics,
1893a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Time(),
1894a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentIdList(),
1895a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        syncer::AttachmentServiceProxyForTest::Create()));
1896a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1897a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetUpInitialSync(initial_image_data, initial_tracking_data);
1898a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1899a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The local unsynced tracking info should be dropped, but not deleted.
1900a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
1901a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1902a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Because the image and tracking data don't overlap, the total number of
1903a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // favicons is still over the limit.
1904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ((unsigned long)kMaxSyncFavicons + 5, GetFaviconCount());
1905a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1906a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Trigger a tracking change for one of the favicons whose tracking info
1907a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // was dropped, resulting in a tracking add and expiration of the orphaned
1908a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // images.
1909a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestFaviconData test_data = BuildFaviconData(kMaxSyncFavicons);
1910a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
1911a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1912a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
1913a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // 1 image update, 5 image deletions, 1 tracking deletion.
1914a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(6U, changes.size());
1915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Expire image for favicon[kMaxSyncFavicons + 1].
1916a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[0].change_type(), syncer::SyncChange::ACTION_DELETE);
1917a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[0].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
1918a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons + 1, GetFaviconId(changes[0]));
1919a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Expire image for favicon[kMaxSyncFavicons + 2].
1920a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[1].change_type(), syncer::SyncChange::ACTION_DELETE);
1921a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[1].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
1922a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons + 2, GetFaviconId(changes[1]));
1923a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Expire image for favicon[kMaxSyncFavicons + 3].
1924a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[2].change_type(), syncer::SyncChange::ACTION_DELETE);
1925a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[2].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
1926a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons + 3, GetFaviconId(changes[2]));
1927a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Expire image for favicon[kMaxSyncFavicons + 4].
1928a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[3].change_type(), syncer::SyncChange::ACTION_DELETE);
1929a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[3].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
1930a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons + 4, GetFaviconId(changes[3]));
1931a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Update tracking for favicon[kMaxSyncFavicons].
1932a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[4].change_type(), syncer::SyncChange::ACTION_ADD);
1933a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[4].sync_data().GetDataType(), syncer::FAVICON_TRACKING);
1934a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(kMaxSyncFavicons, GetFaviconId(changes[4]));
1935a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Expire tracking for favicon[0].
1936a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[5].change_type(), syncer::SyncChange::ACTION_DELETE);
1937a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(changes[5].sync_data().GetDataType(), syncer::FAVICON_TRACKING);
1938a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, GetFaviconId(changes[5]));
1939a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1940a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
19412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace browser_sync
1942