This source file includes following definitions.
- GetAllSyncData
- contains_guid
- change_for_guid
- GetAndResetChangeList
- set_erroneous
- ProcessSyncChanges
- BuildFaviconData
- FillImageSpecifics
- FillTrackingSpecifics
- CompareFaviconDataToSpecifics
- VerifyChanges
- GetFaviconId
- cache
- processor
- sync_processor_wrapper_
- SetUpInitialSync
- GetFaviconCount
- GetTaskCount
- ExpectFaviconEquals
- VerifyLocalIcons
- VerifyLocalCustomIcons
- CreateAndPassProcessor
- CreateAndPassSyncErrorFactory
- OnCustomFaviconDataAvailable
- TriggerSyncFaviconReceived
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "chrome/browser/sync/glue/favicon_cache.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/history/history_notifications.h"
#include "content/public/browser/notification_service.h"
#include "sync/api/sync_change_processor_wrapper_for_test.h"
#include "sync/api/sync_error_factory_mock.h"
#include "sync/api/time.h"
#include "sync/protocol/favicon_image_specifics.pb.h"
#include "sync/protocol/favicon_tracking_specifics.pb.h"
#include "sync/protocol/sync.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace browser_sync {
namespace {
const int kFaviconBatchSize = 10;
const int kMaxSyncFavicons = kFaviconBatchSize*2;
class TestChangeProcessor : public syncer::SyncChangeProcessor {
public:
TestChangeProcessor();
virtual ~TestChangeProcessor();
virtual syncer::SyncError ProcessSyncChanges(
const tracked_objects::Location& from_here,
const syncer::SyncChangeList& change_list) OVERRIDE;
virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
OVERRIDE {
return syncer::SyncDataList();
}
bool contains_guid(const std::string& guid) const {
return change_map_.count(guid) != 0;
}
syncer::SyncChange change_for_guid(const std::string& guid) const {
DCHECK(contains_guid(guid));
return change_map_.find(guid)->second;
}
syncer::SyncChangeList GetAndResetChangeList() {
syncer::SyncChangeList list;
list.swap(change_list_);
return list;
}
void set_erroneous(bool erroneous) { erroneous_ = erroneous; }
private:
std::map<std::string, syncer::SyncChange> change_map_;
syncer::SyncChangeList change_list_;
bool erroneous_;
DISALLOW_COPY_AND_ASSIGN(TestChangeProcessor);
};
TestChangeProcessor::TestChangeProcessor() : erroneous_(false) {
}
TestChangeProcessor::~TestChangeProcessor() {
}
syncer::SyncError TestChangeProcessor::ProcessSyncChanges(
const tracked_objects::Location& from_here,
const syncer::SyncChangeList& change_list) {
if (erroneous_) {
return syncer::SyncError(
FROM_HERE,
syncer::SyncError::DATATYPE_ERROR,
"Some error.",
change_list[0].sync_data().GetDataType());
}
change_list_.insert(change_list_.end(),
change_list.begin(),
change_list.end());
change_map_.erase(change_map_.begin(), change_map_.end());
for (syncer::SyncChangeList::const_iterator iter = change_list.begin();
iter != change_list.end(); ++iter) {
change_map_[iter->sync_data().GetTitle()] = *iter;
}
return syncer::SyncError();
}
struct TestFaviconData {
TestFaviconData() : last_visit_time(0), is_bookmarked(false) {}
GURL page_url;
GURL icon_url;
std::string image_16;
std::string image_32;
std::string image_64;
int64 last_visit_time;
bool is_bookmarked;
};
TestFaviconData BuildFaviconData(int index) {
TestFaviconData data;
data.page_url = GURL(base::StringPrintf("http://bla.com/%.2i.html", index));
data.icon_url = GURL(base::StringPrintf("http://bla.com/%.2i.ico", index));
data.image_16 = base::StringPrintf("16 %i", index);
data.last_visit_time = index;
return data;
}
void FillImageSpecifics(
const TestFaviconData& test_data,
sync_pb::FaviconImageSpecifics* image_specifics) {
image_specifics->set_favicon_url(test_data.icon_url.spec());
if (!test_data.image_16.empty()) {
image_specifics->mutable_favicon_web()->set_height(16);
image_specifics->mutable_favicon_web()->set_width(16);
image_specifics->mutable_favicon_web()->set_favicon(test_data.image_16);
}
if (!test_data.image_32.empty()) {
image_specifics->mutable_favicon_web_32()->set_height(32);
image_specifics->mutable_favicon_web_32()->set_width(32);
image_specifics->mutable_favicon_web_32()->set_favicon(test_data.image_32);
}
if (!test_data.image_64.empty()) {
image_specifics->mutable_favicon_touch_64()->set_height(64);
image_specifics->mutable_favicon_touch_64()->set_width(64);
image_specifics->mutable_favicon_touch_64()->
set_favicon(test_data.image_64);
}
}
void FillTrackingSpecifics(
const TestFaviconData& test_data,
sync_pb::FaviconTrackingSpecifics* tracking_specifics) {
tracking_specifics->set_favicon_url(test_data.icon_url.spec());
tracking_specifics->set_last_visit_time_ms(test_data.last_visit_time);
tracking_specifics->set_is_bookmarked(test_data.is_bookmarked);
}
testing::AssertionResult CompareFaviconDataToSpecifics(
const TestFaviconData& test_data,
const sync_pb::EntitySpecifics& specifics) {
if (specifics.has_favicon_image()) {
sync_pb::FaviconImageSpecifics image_specifics = specifics.favicon_image();
if (image_specifics.favicon_url() != test_data.icon_url.spec())
return testing::AssertionFailure() << "Image icon url doesn't match.";
if (!test_data.image_16.empty()) {
if (image_specifics.favicon_web().favicon() != test_data.image_16 ||
image_specifics.favicon_web().height() != 16 ||
image_specifics.favicon_web().width() != 16) {
return testing::AssertionFailure() << "16p image data doesn't match.";
}
} else if (image_specifics.has_favicon_web()) {
return testing::AssertionFailure() << "Missing 16p favicon.";
}
if (!test_data.image_32.empty()) {
if (image_specifics.favicon_web_32().favicon() != test_data.image_32 ||
image_specifics.favicon_web().height() != 32 ||
image_specifics.favicon_web().width() != 32) {
return testing::AssertionFailure() << "32p image data doesn't match.";
}
} else if (image_specifics.has_favicon_web_32()) {
return testing::AssertionFailure() << "Missing 32p favicon.";
}
if (!test_data.image_64.empty()) {
if (image_specifics.favicon_touch_64().favicon() != test_data.image_64 ||
image_specifics.favicon_web().height() != 64 ||
image_specifics.favicon_web().width() != 64) {
return testing::AssertionFailure() << "64p image data doesn't match.";
}
} else if (image_specifics.has_favicon_touch_64()) {
return testing::AssertionFailure() << "Missing 64p favicon.";
}
} else {
sync_pb::FaviconTrackingSpecifics tracking_specifics =
specifics.favicon_tracking();
if (tracking_specifics.favicon_url() != test_data.icon_url.spec())
return testing::AssertionFailure() << "Tracking icon url doesn't match.";
if (tracking_specifics.last_visit_time_ms() != test_data.last_visit_time)
return testing::AssertionFailure() << "Visit time doesn't match.";
if (tracking_specifics.is_bookmarked() != test_data.is_bookmarked)
return testing::AssertionFailure() << "Bookmark status doens't match.";
}
return testing::AssertionSuccess();
}
testing::AssertionResult VerifyChanges(
syncer::ModelType expected_model_type,
const std::vector<syncer::SyncChange::SyncChangeType>&
expected_change_types,
const std::vector<int>& expected_icons,
const syncer::SyncChangeList& change_list) {
DCHECK_EQ(expected_change_types.size(), expected_icons.size());
if (change_list.size() != expected_icons.size())
return testing::AssertionFailure() << "Change list size doesn't match.";
for (size_t i = 0; i < expected_icons.size(); ++i) {
TestFaviconData data = BuildFaviconData(expected_icons[i]);
if (change_list[i].sync_data().GetDataType() != expected_model_type)
return testing::AssertionFailure() << "Change datatype doesn't match.";
if (change_list[i].change_type() != expected_change_types[i])
return testing::AssertionFailure() << "Change type doesn't match.";
if (change_list[i].change_type() == syncer::SyncChange::ACTION_DELETE) {
if (syncer::SyncDataLocal(change_list[i].sync_data()).GetTag() !=
data.icon_url.spec())
return testing::AssertionFailure() << "Deletion url does not match.";
} else {
testing::AssertionResult compare_result =
CompareFaviconDataToSpecifics(
data,
change_list[i].sync_data().GetSpecifics());
if (!compare_result)
return compare_result;
}
}
return testing::AssertionSuccess();
}
int GetFaviconId(const syncer::SyncChange change) {
std::string tag = syncer::SyncDataLocal(change.sync_data()).GetTag();
const std::string kPrefix = "http://bla.com/";
const std::string kSuffix = ".ico";
if (tag.find(kPrefix) != 0)
return -1;
std::string temp = tag.substr(kPrefix.length());
if (temp.rfind(kSuffix) <= 0)
return -1;
temp = temp.substr(0, temp.rfind(kSuffix));
int result = -1;
if (!base::StringToInt(temp, &result))
return -1;
return result;
}
}
class SyncFaviconCacheTest : public testing::Test {
public:
SyncFaviconCacheTest();
virtual ~SyncFaviconCacheTest() {}
void SetUpInitialSync(const syncer::SyncDataList& initial_image_data,
const syncer::SyncDataList& initial_tracking_data);
size_t GetFaviconCount() const;
size_t GetTaskCount() const;
testing::AssertionResult ExpectFaviconEquals(
const std::string& page_url,
const std::string& bytes) const;
testing::AssertionResult VerifyLocalIcons(
const std::vector<int>& expected_icons);
testing::AssertionResult VerifyLocalCustomIcons(
const std::vector<TestFaviconData>& expected_icons);
scoped_ptr<syncer::SyncChangeProcessor> CreateAndPassProcessor();
scoped_ptr<syncer::SyncErrorFactory> CreateAndPassSyncErrorFactory();
FaviconCache* cache() { return &cache_; }
TestChangeProcessor* processor() { return sync_processor_.get(); }
void OnCustomFaviconDataAvailable(const TestFaviconData& test_data);
void TriggerSyncFaviconReceived(const GURL& page_url,
const GURL& icon_url,
const std::string& icon_bytes,
int64 last_visit_time_ms);
private:
base::MessageLoopForUI message_loop_;
FaviconCache cache_;
scoped_ptr<TestChangeProcessor> sync_processor_;
scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> sync_processor_wrapper_;
};
SyncFaviconCacheTest::SyncFaviconCacheTest()
: cache_(NULL, kMaxSyncFavicons),
sync_processor_(new TestChangeProcessor),
sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest(
sync_processor_.get())) {}
void SyncFaviconCacheTest::SetUpInitialSync(
const syncer::SyncDataList& initial_image_data,
const syncer::SyncDataList& initial_tracking_data) {
cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
initial_image_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
ASSERT_EQ(0U, processor()->GetAndResetChangeList().size());
cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
initial_tracking_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
ASSERT_EQ(0U, processor()->GetAndResetChangeList().size());
}
size_t SyncFaviconCacheTest::GetFaviconCount() const {
return cache_.NumFaviconsForTest();
}
size_t SyncFaviconCacheTest::GetTaskCount() const {
return cache_.NumTasksForTest();
}
testing::AssertionResult SyncFaviconCacheTest::ExpectFaviconEquals(
const std::string& page_url,
const std::string& bytes) const {
GURL gurl(page_url);
scoped_refptr<base::RefCountedMemory> favicon;
if (!cache_.GetSyncedFaviconForPageURL(gurl, &favicon))
return testing::AssertionFailure() << "Favicon is missing.";
if (favicon->size() != bytes.size())
return testing::AssertionFailure() << "Favicon sizes don't match.";
for (size_t i = 0; i < favicon->size(); ++i) {
if (bytes[i] != *(favicon->front() + i))
return testing::AssertionFailure() << "Favicon data doesn't match.";
}
return testing::AssertionSuccess();
}
testing::AssertionResult SyncFaviconCacheTest::VerifyLocalIcons(
const std::vector<int>& expected_icons) {
std::vector<TestFaviconData> expected_custom_icons;
for (size_t i = 0; i < expected_icons.size(); ++i) {
expected_custom_icons.push_back(BuildFaviconData(expected_icons[i]));
}
return VerifyLocalCustomIcons(expected_custom_icons);
}
testing::AssertionResult SyncFaviconCacheTest::VerifyLocalCustomIcons(
const std::vector<TestFaviconData>& expected_custom_icons) {
syncer::SyncDataList image_data_list =
cache()->GetAllSyncData(syncer::FAVICON_IMAGES);
syncer::SyncDataList tracking_data_list =
cache()->GetAllSyncData(syncer::FAVICON_TRACKING);
if (expected_custom_icons.size() > image_data_list.size() ||
expected_custom_icons.size() > tracking_data_list.size())
return testing::AssertionFailure() << "Number of icons doesn't match.";
for (size_t i = 0; i < expected_custom_icons.size(); ++i) {
const TestFaviconData& test_data = expected_custom_icons[i];
bool found_match = false;
for (size_t j = 0; j < image_data_list.size(); ++j) {
if (image_data_list[j].GetTitle() != test_data.icon_url.spec())
continue;
found_match = true;
const sync_pb::FaviconImageSpecifics& image_specifics =
image_data_list[j].GetSpecifics().favicon_image();
sync_pb::FaviconImageSpecifics expected_image_specifics;
FillImageSpecifics(test_data, &expected_image_specifics);
if (image_specifics.SerializeAsString() !=
expected_image_specifics.SerializeAsString()) {
return testing::AssertionFailure() << "Image data doesn't match.";
}
const sync_pb::FaviconTrackingSpecifics& tracking_specifics =
tracking_data_list[j].GetSpecifics().favicon_tracking();
sync_pb::FaviconTrackingSpecifics expected_tracking_specifics;
FillTrackingSpecifics(test_data, &expected_tracking_specifics);
if (tracking_specifics.SerializeAsString() !=
expected_tracking_specifics.SerializeAsString()) {
return testing::AssertionFailure() << "Tracking data doesn't match.";
}
}
if (!found_match)
return testing::AssertionFailure() << "Could not find favicon.";
}
return testing::AssertionSuccess();
}
scoped_ptr<syncer::SyncChangeProcessor>
SyncFaviconCacheTest::CreateAndPassProcessor() {
return scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
}
scoped_ptr<syncer::SyncErrorFactory> SyncFaviconCacheTest::
CreateAndPassSyncErrorFactory() {
return scoped_ptr<syncer::SyncErrorFactory>(
new syncer::SyncErrorFactoryMock());
}
void SyncFaviconCacheTest::OnCustomFaviconDataAvailable(
const TestFaviconData& test_data) {
std::vector<chrome::FaviconBitmapResult> bitmap_results;
if (!test_data.image_16.empty()) {
chrome::FaviconBitmapResult bitmap_result;
bitmap_result.icon_url = test_data.icon_url;
bitmap_result.pixel_size.set_width(16);
bitmap_result.pixel_size.set_height(16);
base::RefCountedString* temp_string = new base::RefCountedString();
temp_string->data() = test_data.image_16;
bitmap_result.bitmap_data = temp_string;
bitmap_results.push_back(bitmap_result);
}
if (!test_data.image_32.empty()) {
chrome::FaviconBitmapResult bitmap_result;
bitmap_result.icon_url = test_data.icon_url;
bitmap_result.pixel_size.set_width(32);
bitmap_result.pixel_size.set_height(32);
base::RefCountedString* temp_string = new base::RefCountedString();
temp_string->data() = test_data.image_32;
bitmap_result.bitmap_data = temp_string;
bitmap_results.push_back(bitmap_result);
}
if (!test_data.image_64.empty()) {
chrome::FaviconBitmapResult bitmap_result;
bitmap_result.icon_url = test_data.icon_url;
bitmap_result.pixel_size.set_width(64);
bitmap_result.pixel_size.set_height(64);
base::RefCountedString* temp_string = new base::RefCountedString();
temp_string->data() = test_data.image_64;
bitmap_result.bitmap_data = temp_string;
bitmap_results.push_back(bitmap_result);
}
cache()->OnFaviconDataAvailable(test_data.page_url, bitmap_results);
}
void SyncFaviconCacheTest::TriggerSyncFaviconReceived(
const GURL& page_url,
const GURL& icon_url,
const std::string& icon_bytes,
int64 last_visit_time_ms) {
cache()->OnReceivedSyncFavicon(page_url,
icon_url,
icon_bytes,
last_visit_time_ms);
message_loop_.RunUntilIdle();
}
TEST_F(SyncFaviconCacheTest, Empty) {
EXPECT_EQ(0U, GetFaviconCount());
}
TEST_F(SyncFaviconCacheTest, ReceiveSyncFavicon) {
std::string page_url = "http://www.google.com";
std::string fav_url = "http://www.google.com/favicon.ico";
std::string bytes = "bytes";
EXPECT_EQ(0U, GetFaviconCount());
TriggerSyncFaviconReceived(GURL(page_url), GURL(fav_url), bytes, 0);
EXPECT_EQ(1U, GetFaviconCount());
EXPECT_TRUE(ExpectFaviconEquals(page_url, bytes));
}
TEST_F(SyncFaviconCacheTest, ReceiveEmptySyncFavicon) {
std::string page_url = "http://www.google.com";
std::string fav_url = "http://www.google.com/favicon.ico";
std::string bytes = "bytes";
EXPECT_EQ(0U, GetFaviconCount());
TriggerSyncFaviconReceived(GURL(page_url),
GURL(fav_url),
std::string(),
0);
EXPECT_EQ(0U, GetFaviconCount());
EXPECT_FALSE(ExpectFaviconEquals(page_url, std::string()));
TriggerSyncFaviconReceived(GURL(page_url), GURL(fav_url), bytes, 0);
EXPECT_EQ(1U, GetFaviconCount());
EXPECT_TRUE(ExpectFaviconEquals(page_url, bytes));
}
TEST_F(SyncFaviconCacheTest, ReceiveUpdatedSyncFavicon) {
std::string page_url = "http://www.google.com";
std::string fav_url = "http://www.google.com/favicon.ico";
std::string bytes = "bytes";
std::string bytes2 = "bytes2";
EXPECT_EQ(0U, GetFaviconCount());
TriggerSyncFaviconReceived(GURL(page_url), GURL(fav_url), bytes, 0);
EXPECT_EQ(1U, GetFaviconCount());
EXPECT_TRUE(ExpectFaviconEquals(page_url, bytes));
TriggerSyncFaviconReceived(GURL(page_url), GURL(fav_url), bytes2, 0);
EXPECT_EQ(1U, GetFaviconCount());
EXPECT_TRUE(ExpectFaviconEquals(page_url, bytes));
EXPECT_FALSE(ExpectFaviconEquals(page_url, bytes2));
}
TEST_F(SyncFaviconCacheTest, MultipleMappings) {
std::string page_url = "http://www.google.com";
std::string page2_url = "http://bla.google.com";
std::string fav_url = "http://www.google.com/favicon.ico";
std::string bytes = "bytes";
EXPECT_EQ(0U, GetFaviconCount());
TriggerSyncFaviconReceived(GURL(page_url), GURL(fav_url), bytes, 0);
EXPECT_EQ(1U, GetFaviconCount());
EXPECT_TRUE(ExpectFaviconEquals(page_url, bytes));
TriggerSyncFaviconReceived(GURL(page2_url), GURL(fav_url), bytes, 0);
EXPECT_EQ(1U, GetFaviconCount());
EXPECT_TRUE(ExpectFaviconEquals(page2_url, bytes));
}
TEST_F(SyncFaviconCacheTest, SyncEmpty) {
syncer::SyncMergeResult merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
syncer::SyncDataList(),
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ(0U, cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ(0, merge_result.num_items_added());
EXPECT_EQ(0, merge_result.num_items_modified());
EXPECT_EQ(0, merge_result.num_items_deleted());
EXPECT_EQ(0, merge_result.num_items_before_association());
EXPECT_EQ(0, merge_result.num_items_after_association());
merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
syncer::SyncDataList(),
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ(0U, cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ(0, merge_result.num_items_added());
EXPECT_EQ(0, merge_result.num_items_modified());
EXPECT_EQ(0, merge_result.num_items_deleted());
EXPECT_EQ(0, merge_result.num_items_before_association());
EXPECT_EQ(0, merge_result.num_items_after_association());
}
TEST_F(SyncFaviconCacheTest, SyncExistingLocal) {
std::vector<syncer::SyncChange::SyncChangeType> expected_change_types;
std::vector<int> expected_icons;
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData favicon = BuildFaviconData(i);
TriggerSyncFaviconReceived(favicon.page_url,
favicon.icon_url,
favicon.image_16,
i);
expected_change_types.push_back(syncer::SyncChange::ACTION_ADD);
expected_icons.push_back(i);
}
syncer::SyncMergeResult merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
syncer::SyncDataList(),
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ((unsigned long)kFaviconBatchSize,
cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
syncer::SyncChangeList change_list = processor()->GetAndResetChangeList();
EXPECT_TRUE(VerifyChanges(syncer::FAVICON_IMAGES,
expected_change_types,
expected_icons,
change_list));
EXPECT_EQ(0, merge_result.num_items_added());
EXPECT_EQ(0, merge_result.num_items_modified());
EXPECT_EQ(0, merge_result.num_items_deleted());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
syncer::SyncDataList(),
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ((unsigned long)kFaviconBatchSize,
cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
change_list = processor()->GetAndResetChangeList();
EXPECT_TRUE(VerifyChanges(syncer::FAVICON_TRACKING,
expected_change_types,
expected_icons,
change_list));
EXPECT_EQ(0, merge_result.num_items_added());
EXPECT_EQ(0, merge_result.num_items_modified());
EXPECT_EQ(0, merge_result.num_items_deleted());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
}
TEST_F(SyncFaviconCacheTest, SyncExistingRemote) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
std::vector<int> expected_icons;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
syncer::SyncMergeResult merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
initial_image_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ((unsigned long)kFaviconBatchSize,
cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_added());
EXPECT_EQ(0, merge_result.num_items_modified());
EXPECT_EQ(0, merge_result.num_items_deleted());
EXPECT_EQ(0, merge_result.num_items_before_association());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
initial_tracking_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ((unsigned long)kFaviconBatchSize,
cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ(0, merge_result.num_items_added());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_modified());
EXPECT_EQ(0, merge_result.num_items_deleted());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
ASSERT_TRUE(VerifyLocalIcons(expected_icons));
}
TEST_F(SyncFaviconCacheTest, SyncMergesImages) {
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData favicon = BuildFaviconData(i);
TriggerSyncFaviconReceived(favicon.page_url,
favicon.icon_url,
favicon.image_16,
i);
}
std::vector<syncer::SyncChange::SyncChangeType> expected_change_types;
std::vector<int> expected_icons;
std::vector<TestFaviconData> expected_data;
syncer::SyncDataList initial_image_data, initial_tracking_data;
for (int i = 0; i < kFaviconBatchSize; ++i) {
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
TestFaviconData test_data = BuildFaviconData(i);
if (i < kFaviconBatchSize/2) {
test_data.image_16 = std::string();
expected_icons.push_back(i);
expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
} else {
test_data.image_16 += "custom";
expected_data.push_back(test_data);
}
FillImageSpecifics(test_data,
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(test_data,
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
syncer::SyncMergeResult merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
initial_image_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ((unsigned long)kFaviconBatchSize,
cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
EXPECT_EQ((unsigned long)kFaviconBatchSize/2, changes.size());
EXPECT_EQ(0, merge_result.num_items_added());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_modified());
EXPECT_EQ(0, merge_result.num_items_deleted());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
initial_tracking_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ((unsigned long)kFaviconBatchSize,
cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ(0, merge_result.num_items_added());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_modified());
EXPECT_EQ(0, merge_result.num_items_deleted());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
ASSERT_TRUE(VerifyLocalIcons(expected_icons));
ASSERT_TRUE(VerifyLocalCustomIcons(expected_data));
ASSERT_TRUE(VerifyChanges(syncer::FAVICON_IMAGES,
expected_change_types,
expected_icons,
changes));
}
TEST_F(SyncFaviconCacheTest, SyncMergesTracking) {
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData favicon = BuildFaviconData(i);
TriggerSyncFaviconReceived(favicon.page_url,
favicon.icon_url,
favicon.image_16,
i);
}
std::vector<syncer::SyncChange::SyncChangeType> expected_change_types;
std::vector<int> expected_icons;
std::vector<TestFaviconData> expected_data;
syncer::SyncDataList initial_image_data, initial_tracking_data;
for (int i = 0; i < kFaviconBatchSize; ++i) {
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
TestFaviconData test_data = BuildFaviconData(i);
if (i < kFaviconBatchSize/2) {
test_data.last_visit_time = i-1;
expected_icons.push_back(i);
expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
} else {
test_data.last_visit_time = i+1;
expected_data.push_back(test_data);
}
FillImageSpecifics(test_data,
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(test_data,
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
syncer::SyncMergeResult merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
initial_image_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ((unsigned long)kFaviconBatchSize,
cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ(0, merge_result.num_items_added());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_modified());
EXPECT_EQ(0, merge_result.num_items_deleted());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
initial_tracking_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ((unsigned long)kFaviconBatchSize,
cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
EXPECT_EQ((unsigned long)kFaviconBatchSize/2, changes.size());
EXPECT_EQ(0, merge_result.num_items_added());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_modified());
EXPECT_EQ(0, merge_result.num_items_deleted());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_before_association());
EXPECT_EQ(kFaviconBatchSize, merge_result.num_items_after_association());
ASSERT_TRUE(VerifyLocalIcons(expected_icons));
ASSERT_TRUE(VerifyLocalCustomIcons(expected_data));
ASSERT_TRUE(VerifyChanges(syncer::FAVICON_TRACKING,
expected_change_types,
expected_icons,
changes));
}
TEST_F(SyncFaviconCacheTest, ReceiveStaleImages) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
syncer::SyncChangeList stale_changes;
std::vector<int> expected_icons;
std::vector<syncer::SyncChange::SyncChangeType> expected_change_types;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
image_specifics.mutable_favicon_image()->clear_favicon_web();
stale_changes.push_back(
syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time())));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
cache()->ProcessSyncChanges(FROM_HERE, stale_changes);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
ASSERT_TRUE(VerifyLocalIcons(expected_icons));
ASSERT_EQ((unsigned long)kFaviconBatchSize, changes.size());
ASSERT_TRUE(VerifyChanges(syncer::FAVICON_IMAGES,
expected_change_types,
expected_icons,
changes));
}
TEST_F(SyncFaviconCacheTest, ReceiveNewImages) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
syncer::SyncChangeList new_changes;
std::vector<int> expected_icons;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
TestFaviconData test_data = BuildFaviconData(i);
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(test_data,
image_specifics.mutable_favicon_image());
new_changes.push_back(
syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time())));
image_specifics.mutable_favicon_image()->mutable_favicon_web()->
mutable_favicon()->append("old");
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
cache()->ProcessSyncChanges(FROM_HERE, new_changes);
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
ASSERT_TRUE(VerifyLocalIcons(expected_icons));
}
TEST_F(SyncFaviconCacheTest, ReceiveSameImages) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
syncer::SyncChangeList same_changes;
std::vector<int> expected_icons;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
TestFaviconData test_data = BuildFaviconData(i);
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(test_data,
image_specifics.mutable_favicon_image());
same_changes.push_back(
syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time())));
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
cache()->ProcessSyncChanges(FROM_HERE, same_changes);
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
ASSERT_TRUE(VerifyLocalIcons(expected_icons));
}
TEST_F(SyncFaviconCacheTest, ReceiveStaleTracking) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
syncer::SyncChangeList stale_changes;
std::vector<int> expected_icons;
std::vector<syncer::SyncChange::SyncChangeType> expected_change_types;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(-1);
stale_changes.push_back(
syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time())));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
cache()->ProcessSyncChanges(FROM_HERE, stale_changes);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
ASSERT_TRUE(VerifyLocalIcons(expected_icons));
ASSERT_EQ((unsigned long)kFaviconBatchSize, changes.size());
ASSERT_TRUE(VerifyChanges(syncer::FAVICON_TRACKING,
expected_change_types,
expected_icons,
changes));
}
TEST_F(SyncFaviconCacheTest, ReceiveNewTracking) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
syncer::SyncChangeList new_changes;
std::vector<int> expected_icons;
for (int i = 1; i <= kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
new_changes.push_back(
syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time())));
tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(i-1);
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
cache()->ProcessSyncChanges(FROM_HERE, new_changes);
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
ASSERT_TRUE(VerifyLocalIcons(expected_icons));
}
TEST_F(SyncFaviconCacheTest, ReceiveSameTracking) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
syncer::SyncChangeList same_changes;
std::vector<int> expected_icons;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
same_changes.push_back(
syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time())));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
cache()->ProcessSyncChanges(FROM_HERE, same_changes);
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
ASSERT_TRUE(VerifyLocalIcons(expected_icons));
}
TEST_F(SyncFaviconCacheTest, DeleteFavicons) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
syncer::SyncChangeList tracking_deletions, image_deletions;
for (int i = 0; i < kFaviconBatchSize; ++i) {
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
tracking_deletions.push_back(
syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_DELETE,
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time())));
image_deletions.push_back(
syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_DELETE,
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time())));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
cache()->ProcessSyncChanges(FROM_HERE, tracking_deletions);
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
cache()->ProcessSyncChanges(FROM_HERE, image_deletions);
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ(0U, GetFaviconCount());
}
TEST_F(SyncFaviconCacheTest, ExpireOnMergeData) {
std::vector<int> expected_icons;
syncer::SyncDataList initial_image_data, initial_tracking_data;
for (int i = 0; i < kMaxSyncFavicons; ++i) {
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
expected_icons.push_back(i);
TestFaviconData favicon = BuildFaviconData(i+kMaxSyncFavicons);
TriggerSyncFaviconReceived(favicon.page_url,
favicon.icon_url,
favicon.image_16,
i+kMaxSyncFavicons);
}
EXPECT_FALSE(VerifyLocalIcons(expected_icons));
syncer::SyncMergeResult merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
initial_image_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ((unsigned long)kMaxSyncFavicons * 2,
GetFaviconCount());
EXPECT_EQ((unsigned long)kMaxSyncFavicons,
cache()->GetAllSyncData(syncer::FAVICON_IMAGES).size());
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_added());
EXPECT_EQ(0, merge_result.num_items_modified());
EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_deleted());
EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_before_association());
EXPECT_EQ(kMaxSyncFavicons * 2, merge_result.num_items_after_association());
merge_result =
cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
initial_tracking_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
EXPECT_EQ((unsigned long)kMaxSyncFavicons,
cache()->GetAllSyncData(syncer::FAVICON_TRACKING).size());
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ(0, merge_result.num_items_added());
EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_modified());
EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_deleted());
EXPECT_EQ(kMaxSyncFavicons * 2, merge_result.num_items_before_association());
EXPECT_EQ(kMaxSyncFavicons, merge_result.num_items_after_association());
EXPECT_TRUE(VerifyLocalIcons(expected_icons));
}
TEST_F(SyncFaviconCacheTest, NoExpireOnProcessSyncChanges) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
syncer::SyncChangeList image_changes, tracking_changes;
std::vector<int> expected_icons;
for (int i = 0; i < kMaxSyncFavicons; ++i) {
expected_icons.push_back(i);
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
expected_icons.push_back(i + kMaxSyncFavicons);
FillImageSpecifics(BuildFaviconData(i + kMaxSyncFavicons),
image_specifics.mutable_favicon_image());
image_changes.push_back(
syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_ADD,
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time())));
FillTrackingSpecifics(BuildFaviconData(i + kMaxSyncFavicons),
tracking_specifics.mutable_favicon_tracking());
tracking_changes.push_back(
syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_ADD,
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time())));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
EXPECT_EQ((unsigned long)kMaxSyncFavicons, GetFaviconCount());
cache()->ProcessSyncChanges(FROM_HERE, image_changes);
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
cache()->ProcessSyncChanges(FROM_HERE, tracking_changes);
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_TRUE(VerifyLocalIcons(expected_icons));
EXPECT_GT(GetFaviconCount(), (unsigned long)kMaxSyncFavicons);
}
TEST_F(SyncFaviconCacheTest, AddOnFaviconVisited) {
EXPECT_EQ(0U, GetFaviconCount());
SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
std::vector<int> expected_icons;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
TestFaviconData test_data = BuildFaviconData(i);
cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
}
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetTaskCount());
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData test_data = BuildFaviconData(i);
OnCustomFaviconDataAvailable(test_data);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
ASSERT_EQ(2U, changes.size());
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
EXPECT_EQ(syncer::FAVICON_IMAGES, changes[0].sync_data().GetDataType());
EXPECT_TRUE(
CompareFaviconDataToSpecifics(test_data,
changes[0].sync_data().GetSpecifics()));
EXPECT_EQ(syncer::FAVICON_TRACKING, changes[1].sync_data().GetDataType());
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[1].change_type());
EXPECT_EQ(test_data.icon_url.spec(),
changes[1].sync_data().GetSpecifics().favicon_tracking().
favicon_url());
EXPECT_NE(changes[1].sync_data().GetSpecifics().favicon_tracking().
last_visit_time_ms(), 0);
}
EXPECT_EQ(0U, GetTaskCount());
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
}
TEST_F(SyncFaviconCacheTest, UpdateOnFaviconVisited) {
EXPECT_EQ(0U, GetFaviconCount());
SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
std::vector<int> expected_icons;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
TestFaviconData test_data = BuildFaviconData(i);
cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
OnCustomFaviconDataAvailable(test_data);
}
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
EXPECT_EQ(0U, GetTaskCount());
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData test_data = BuildFaviconData(i);
cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
ASSERT_EQ(1U, changes.size());
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
EXPECT_EQ(test_data.icon_url.spec(),
changes[0].sync_data().GetSpecifics().favicon_tracking().
favicon_url());
EXPECT_NE(changes[0].sync_data().GetSpecifics().favicon_tracking().
last_visit_time_ms(), 0);
}
EXPECT_EQ(0U, GetTaskCount());
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
}
TEST_F(SyncFaviconCacheTest, ExpireOnFaviconVisited) {
EXPECT_EQ(0U, GetFaviconCount());
SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
std::vector<int> expected_icons;
for (int i = 0; i < kMaxSyncFavicons; ++i) {
expected_icons.push_back(i);
TestFaviconData test_data = BuildFaviconData(i);
cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
OnCustomFaviconDataAvailable(test_data);
}
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
EXPECT_EQ(0U, GetTaskCount());
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData old_favicon = BuildFaviconData(i);
TestFaviconData test_data = BuildFaviconData(i + kMaxSyncFavicons);
cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
OnCustomFaviconDataAvailable(test_data);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
ASSERT_EQ(4U, changes.size());
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
EXPECT_TRUE(
CompareFaviconDataToSpecifics(test_data,
changes[0].sync_data().GetSpecifics()));
EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, changes[1].change_type());
EXPECT_EQ(old_favicon.icon_url.spec(),
syncer::SyncDataLocal(changes[1].sync_data()).GetTag());
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[2].change_type());
EXPECT_EQ(test_data.icon_url.spec(),
changes[2].sync_data().GetSpecifics().favicon_tracking().
favicon_url());
EXPECT_NE(changes[2].sync_data().GetSpecifics().favicon_tracking().
last_visit_time_ms(), 0);
EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, changes[3].change_type());
EXPECT_EQ(old_favicon.icon_url.spec(),
syncer::SyncDataLocal(changes[3].sync_data()).GetTag());
}
EXPECT_EQ(0U, GetTaskCount());
EXPECT_EQ((unsigned long)kMaxSyncFavicons, GetFaviconCount());
}
TEST_F(SyncFaviconCacheTest, HistoryFullClear) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
std::vector<int> expected_icons;
std::vector<syncer::SyncChange::SyncChangeType> expected_deletions;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
expected_deletions.push_back(syncer::SyncChange::ACTION_DELETE);
TestFaviconData test_data = BuildFaviconData(i);
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(test_data,
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
EXPECT_TRUE(changes.empty());
history::URLsDeletedDetails deletions;
deletions.all_history = true;
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_HISTORY_URLS_DELETED,
content::Source<Profile>(NULL),
content::Details<history::URLsDeletedDetails>(&deletions));
EXPECT_EQ(0U, GetFaviconCount());
changes = processor()->GetAndResetChangeList();
ASSERT_EQ(changes.size(), (unsigned long)kFaviconBatchSize*2);
syncer::SyncChangeList changes_1, changes_2;
for (int i = 0; i < kFaviconBatchSize; ++i) {
changes_1.push_back(changes[i]);
changes_2.push_back(changes[i + kFaviconBatchSize]);
}
VerifyChanges(syncer::FAVICON_IMAGES,
expected_deletions,
expected_icons,
changes_1);
VerifyChanges(syncer::FAVICON_TRACKING,
expected_deletions,
expected_icons,
changes_2);
}
TEST_F(SyncFaviconCacheTest, HistorySubsetClear) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
std::vector<int> expected_icons;
std::vector<syncer::SyncChange::SyncChangeType> expected_deletions;
history::URLsDeletedDetails deletions;
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData test_data = BuildFaviconData(i);
if (i < kFaviconBatchSize/2) {
expected_icons.push_back(i);
expected_deletions.push_back(syncer::SyncChange::ACTION_DELETE);
deletions.favicon_urls.insert(test_data.icon_url);
}
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(test_data,
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
EXPECT_TRUE(changes.empty());
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_HISTORY_URLS_DELETED,
content::Source<Profile>(NULL),
content::Details<history::URLsDeletedDetails>(&deletions));
EXPECT_EQ((unsigned long)kFaviconBatchSize/2, GetFaviconCount());
changes = processor()->GetAndResetChangeList();
ASSERT_EQ(changes.size(), (unsigned long)kFaviconBatchSize);
syncer::SyncChangeList changes_1, changes_2;
for (size_t i = 0; i < kFaviconBatchSize/2; ++i) {
changes_1.push_back(changes[i]);
changes_2.push_back(changes[i + kFaviconBatchSize/2]);
}
VerifyChanges(syncer::FAVICON_IMAGES,
expected_deletions,
expected_icons,
changes_1);
VerifyChanges(syncer::FAVICON_TRACKING,
expected_deletions,
expected_icons,
changes_2);
}
TEST_F(SyncFaviconCacheTest, IgnoreDataScheme) {
EXPECT_EQ(0U, GetFaviconCount());
SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
std::vector<int> expected_icons;
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData test_data = BuildFaviconData(i);
cache()->OnFaviconVisited(test_data.page_url, GURL());
}
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetTaskCount());
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData test_data = BuildFaviconData(i);
test_data.icon_url = GURL("data:image/png;base64;blabla");
EXPECT_TRUE(test_data.icon_url.is_valid());
OnCustomFaviconDataAvailable(test_data);
}
EXPECT_EQ(0U, GetTaskCount());
EXPECT_EQ(0U, GetFaviconCount());
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
EXPECT_TRUE(changes.empty());
}
TEST_F(SyncFaviconCacheTest, ReuseCachedIconUrl) {
EXPECT_EQ(0U, GetFaviconCount());
SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
std::vector<int> expected_icons;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
TestFaviconData test_data = BuildFaviconData(i);
cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
}
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetTaskCount());
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData test_data = BuildFaviconData(i);
OnCustomFaviconDataAvailable(test_data);
}
processor()->GetAndResetChangeList();
EXPECT_EQ(0U, GetTaskCount());
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData test_data = BuildFaviconData(i);
cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
ASSERT_EQ(1U, changes.size());
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
EXPECT_EQ(test_data.icon_url.spec(),
changes[0].sync_data().GetSpecifics().favicon_tracking().
favicon_url());
EXPECT_NE(changes[0].sync_data().GetSpecifics().favicon_tracking().
last_visit_time_ms(), 0);
}
EXPECT_EQ(0U, GetTaskCount());
}
TEST_F(SyncFaviconCacheTest, UpdatedOrphans) {
EXPECT_EQ(0U, GetFaviconCount());
SetUpInitialSync(syncer::SyncDataList(), syncer::SyncDataList());
syncer::SyncChangeList initial_image_changes;
syncer::SyncChangeList initial_tracking_changes;
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData test_data = BuildFaviconData(i);
if (i % 2 == 0) {
sync_pb::EntitySpecifics image_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_changes.push_back(
syncer::SyncChange(FROM_HERE,
syncer::SyncChange::ACTION_ADD,
syncer::SyncData::CreateRemoteData(
1, image_specifics, base::Time())));
} else {
sync_pb::EntitySpecifics tracking_specifics;
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_changes.push_back(
syncer::SyncChange(FROM_HERE,
syncer::SyncChange::ACTION_ADD,
syncer::SyncData::CreateRemoteData(
1, tracking_specifics, base::Time())));
}
}
cache()->ProcessSyncChanges(FROM_HERE, initial_image_changes);
cache()->ProcessSyncChanges(FROM_HERE, initial_tracking_changes);
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
for (int i = 0; i < kFaviconBatchSize/2; ++i) {
TestFaviconData test_data = BuildFaviconData(i);
cache()->OnFaviconVisited(test_data.page_url, GURL());
EXPECT_EQ(1U, GetTaskCount());
OnCustomFaviconDataAvailable(test_data);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
if (i % 2 == 0) {
ASSERT_EQ(2U, changes.size());
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
EXPECT_TRUE(
CompareFaviconDataToSpecifics(test_data,
changes[0].sync_data().GetSpecifics()));
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[1].change_type());
EXPECT_EQ(test_data.icon_url.spec(),
changes[1].sync_data().GetSpecifics().favicon_tracking().
favicon_url());
EXPECT_NE(changes[1].sync_data().GetSpecifics().favicon_tracking().
last_visit_time_ms(), 0);
} else {
ASSERT_EQ(2U, changes.size());
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
EXPECT_TRUE(
CompareFaviconDataToSpecifics(test_data,
changes[0].sync_data().GetSpecifics()));
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[1].change_type());
EXPECT_EQ(test_data.icon_url.spec(),
changes[1].sync_data().GetSpecifics().favicon_tracking().
favicon_url());
EXPECT_NE(changes[1].sync_data().GetSpecifics().favicon_tracking().
last_visit_time_ms(), 0);
}
}
EXPECT_EQ(0U, GetTaskCount());
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
}
TEST_F(SyncFaviconCacheTest, PartialAssociationInfo) {
syncer::SyncDataList initial_image_data, initial_tracking_data;
for (int i = 0; i < kFaviconBatchSize; ++i) {
sync_pb::EntitySpecifics image_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
image_specifics.mutable_favicon_image()->clear_favicon_web();
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
syncer::SyncChangeList change_list = processor()->GetAndResetChangeList();
EXPECT_TRUE(change_list.empty());
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
}
TEST_F(SyncFaviconCacheTest, NullFaviconVisitTime) {
EXPECT_EQ(0U, GetFaviconCount());
syncer::SyncDataList initial_image_data, initial_tracking_data;
std::vector<int> expected_icons;
for (int i = 0; i < kFaviconBatchSize; ++i) {
expected_icons.push_back(i);
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
FillImageSpecifics(BuildFaviconData(i),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(
syncer::TimeToProtoTime(base::Time()));
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
initial_image_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
ASSERT_EQ(0U, processor()->GetAndResetChangeList().size());
cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
initial_tracking_data,
CreateAndPassProcessor(),
CreateAndPassSyncErrorFactory());
ASSERT_EQ((unsigned long)kFaviconBatchSize,
processor()->GetAndResetChangeList().size());
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
EXPECT_EQ(0U, GetTaskCount());
for (int i = 0; i < kFaviconBatchSize; ++i) {
TestFaviconData test_data = BuildFaviconData(i);
cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
ASSERT_EQ(1U, changes.size());
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
EXPECT_EQ(test_data.icon_url.spec(),
changes[0].sync_data().GetSpecifics().favicon_tracking().
favicon_url());
EXPECT_NE(changes[0].sync_data().GetSpecifics().favicon_tracking().
last_visit_time_ms(), 0);
}
EXPECT_EQ(0U, GetTaskCount());
EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
}
TEST_F(SyncFaviconCacheTest, VisitFaviconClockSkew) {
EXPECT_EQ(0U, GetFaviconCount());
const int kClockSkew = 20;
syncer::SyncDataList initial_image_data, initial_tracking_data;
for (int i = 0; i < kMaxSyncFavicons; ++i) {
sync_pb::EntitySpecifics image_specifics, tracking_specifics;
TestFaviconData test_data = BuildFaviconData(i);
test_data.last_visit_time =
syncer::TimeToProtoTime(
base::Time::Now() + base::TimeDelta::FromMinutes(kClockSkew));
FillImageSpecifics(test_data,
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
FillTrackingSpecifics(test_data,
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
EXPECT_EQ(0U, GetTaskCount());
for (int i = 0; i < kClockSkew; ++i) {
TestFaviconData test_data = BuildFaviconData(i + kMaxSyncFavicons);
cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
OnCustomFaviconDataAvailable(test_data);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
ASSERT_EQ(changes.size(), 4U);
ASSERT_EQ(changes[0].change_type(), syncer::SyncChange::ACTION_ADD);
ASSERT_EQ(changes[0].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
ASSERT_EQ(changes[1].change_type(), syncer::SyncChange::ACTION_DELETE);
ASSERT_EQ(changes[1].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
ASSERT_EQ(changes[2].change_type(), syncer::SyncChange::ACTION_ADD);
ASSERT_EQ(changes[2].sync_data().GetDataType(), syncer::FAVICON_TRACKING);
ASSERT_EQ(changes[3].change_type(), syncer::SyncChange::ACTION_DELETE);
ASSERT_EQ(changes[3].sync_data().GetDataType(), syncer::FAVICON_TRACKING);
}
EXPECT_EQ(0U, GetTaskCount());
EXPECT_EQ((unsigned long)kMaxSyncFavicons, GetFaviconCount());
}
TEST_F(SyncFaviconCacheTest, MixedThreshold) {
for (int i = kMaxSyncFavicons; i < kMaxSyncFavicons + 5; ++i) {
TestFaviconData favicon = BuildFaviconData(i);
TriggerSyncFaviconReceived(favicon.page_url,
favicon.icon_url,
favicon.image_16,
favicon.last_visit_time);
}
syncer::SyncDataList initial_image_data, initial_tracking_data;
for (int i = 0; i < kMaxSyncFavicons; ++i) {
sync_pb::EntitySpecifics image_specifics;
FillImageSpecifics(BuildFaviconData(i + 5),
image_specifics.mutable_favicon_image());
initial_image_data.push_back(
syncer::SyncData::CreateRemoteData(1,
image_specifics,
base::Time()));
sync_pb::EntitySpecifics tracking_specifics;
FillTrackingSpecifics(BuildFaviconData(i),
tracking_specifics.mutable_favicon_tracking());
initial_tracking_data.push_back(
syncer::SyncData::CreateRemoteData(1,
tracking_specifics,
base::Time()));
}
SetUpInitialSync(initial_image_data, initial_tracking_data);
EXPECT_EQ(0U, processor()->GetAndResetChangeList().size());
EXPECT_EQ((unsigned long)kMaxSyncFavicons + 5, GetFaviconCount());
TestFaviconData test_data = BuildFaviconData(kMaxSyncFavicons);
cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
ASSERT_EQ(6U, changes.size());
EXPECT_EQ(changes[0].change_type(), syncer::SyncChange::ACTION_DELETE);
EXPECT_EQ(changes[0].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
EXPECT_EQ(kMaxSyncFavicons + 1, GetFaviconId(changes[0]));
EXPECT_EQ(changes[1].change_type(), syncer::SyncChange::ACTION_DELETE);
EXPECT_EQ(changes[1].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
EXPECT_EQ(kMaxSyncFavicons + 2, GetFaviconId(changes[1]));
EXPECT_EQ(changes[2].change_type(), syncer::SyncChange::ACTION_DELETE);
EXPECT_EQ(changes[2].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
EXPECT_EQ(kMaxSyncFavicons + 3, GetFaviconId(changes[2]));
EXPECT_EQ(changes[3].change_type(), syncer::SyncChange::ACTION_DELETE);
EXPECT_EQ(changes[3].sync_data().GetDataType(), syncer::FAVICON_IMAGES);
EXPECT_EQ(kMaxSyncFavicons + 4, GetFaviconId(changes[3]));
EXPECT_EQ(changes[4].change_type(), syncer::SyncChange::ACTION_ADD);
EXPECT_EQ(changes[4].sync_data().GetDataType(), syncer::FAVICON_TRACKING);
EXPECT_EQ(kMaxSyncFavicons, GetFaviconId(changes[4]));
EXPECT_EQ(changes[5].change_type(), syncer::SyncChange::ACTION_DELETE);
EXPECT_EQ(changes[5].sync_data().GetDataType(), syncer::FAVICON_TRACKING);
EXPECT_EQ(0, GetFaviconId(changes[5]));
}
}