1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "sync/engine/model_type_entity.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "base/time/time.h" 9 #include "sync/internal_api/public/base/model_type.h" 10 #include "sync/protocol/sync.pb.h" 11 #include "sync/syncable/syncable_util.h" 12 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 namespace syncer { 16 17 // Some simple sanity tests for the ModelTypeEntity. 18 // 19 // A lot of the more complicated sync logic is implemented in the 20 // ModelTypeSyncProxyImpl that owns the ModelTypeEntity. We can't unit test it 21 // here. 22 // 23 // Instead, we focus on simple tests to make sure that variables are getting 24 // properly intialized and flags properly set. Anything more complicated would 25 // be a redundant and incomplete version of the ModelTypeSyncProxyImpl tests. 26 class ModelTypeEntityTest : public ::testing::Test { 27 public: 28 ModelTypeEntityTest() 29 : kServerId("ServerID"), 30 kClientTag("sample.pref.name"), 31 kClientTagHash(syncable::GenerateSyncableHash(PREFERENCES, kClientTag)), 32 kCtime(base::Time::UnixEpoch() + base::TimeDelta::FromDays(10)), 33 kMtime(base::Time::UnixEpoch() + base::TimeDelta::FromDays(20)) { 34 sync_pb::PreferenceSpecifics* pref_specifics = 35 specifics.mutable_preference(); 36 pref_specifics->set_name(kClientTag); 37 pref_specifics->set_value("pref.value"); 38 } 39 40 const std::string kServerId; 41 const std::string kClientTag; 42 const std::string kClientTagHash; 43 const base::Time kCtime; 44 const base::Time kMtime; 45 sync_pb::EntitySpecifics specifics; 46 }; 47 48 TEST_F(ModelTypeEntityTest, NewLocalItem) { 49 scoped_ptr<ModelTypeEntity> entity( 50 ModelTypeEntity::NewLocalItem("asdf", specifics, kCtime)); 51 52 EXPECT_TRUE(entity->IsWriteRequired()); 53 EXPECT_TRUE(entity->IsUnsynced()); 54 EXPECT_FALSE(entity->UpdateIsReflection(1)); 55 EXPECT_TRUE(entity->UpdateIsInConflict(1)); 56 } 57 58 TEST_F(ModelTypeEntityTest, FromServerUpdate) { 59 scoped_ptr<ModelTypeEntity> entity( 60 ModelTypeEntity::FromServerUpdate(kServerId, 61 kClientTagHash, 62 kClientTag, // As non-unique name. 63 10, 64 specifics, 65 false, 66 kCtime, 67 kMtime, 68 std::string())); 69 70 EXPECT_TRUE(entity->IsWriteRequired()); 71 EXPECT_FALSE(entity->IsUnsynced()); 72 EXPECT_TRUE(entity->UpdateIsReflection(9)); 73 EXPECT_TRUE(entity->UpdateIsReflection(10)); 74 EXPECT_FALSE(entity->UpdateIsReflection(11)); 75 EXPECT_FALSE(entity->UpdateIsInConflict(11)); 76 } 77 78 // Tombstones should behave just like regular updates. Mostly. The strangest 79 // thing about them is that they don't have specifics, so it can be hard to 80 // detect their type. Fortunately, this class doesn't care about types in 81 // received updates. 82 TEST_F(ModelTypeEntityTest, TombstoneUpdate) { 83 scoped_ptr<ModelTypeEntity> entity( 84 ModelTypeEntity::FromServerUpdate(kServerId, 85 kClientTagHash, 86 kClientTag, // As non-unique name. 87 10, 88 sync_pb::EntitySpecifics(), 89 true, 90 kCtime, 91 kMtime, 92 std::string())); 93 94 EXPECT_TRUE(entity->IsWriteRequired()); 95 EXPECT_FALSE(entity->IsUnsynced()); 96 EXPECT_TRUE(entity->UpdateIsReflection(9)); 97 EXPECT_TRUE(entity->UpdateIsReflection(10)); 98 EXPECT_FALSE(entity->UpdateIsReflection(11)); 99 EXPECT_FALSE(entity->UpdateIsInConflict(11)); 100 } 101 102 // Apply a deletion update. 103 TEST_F(ModelTypeEntityTest, ApplyUpdate) { 104 scoped_ptr<ModelTypeEntity> entity( 105 ModelTypeEntity::FromServerUpdate(kServerId, 106 kClientTagHash, 107 kClientTag, // As non-unique name. 108 10, 109 specifics, 110 false, 111 kCtime, 112 kMtime, 113 std::string())); 114 115 // A deletion update one version later. 116 entity->ApplyUpdateFromServer(11, 117 true, 118 sync_pb::EntitySpecifics(), 119 kMtime + base::TimeDelta::FromSeconds(10), 120 std::string()); 121 122 EXPECT_TRUE(entity->IsWriteRequired()); 123 EXPECT_FALSE(entity->IsUnsynced()); 124 EXPECT_TRUE(entity->UpdateIsReflection(11)); 125 EXPECT_FALSE(entity->UpdateIsReflection(12)); 126 } 127 128 TEST_F(ModelTypeEntityTest, LocalChange) { 129 scoped_ptr<ModelTypeEntity> entity( 130 ModelTypeEntity::FromServerUpdate(kServerId, 131 kClientTagHash, 132 kClientTag, // As non-unique name. 133 10, 134 specifics, 135 false, 136 kCtime, 137 kMtime, 138 std::string())); 139 140 sync_pb::EntitySpecifics specifics2; 141 specifics2.CopyFrom(specifics); 142 specifics2.mutable_preference()->set_value("new.pref.value"); 143 144 entity->MakeLocalChange(specifics2); 145 EXPECT_TRUE(entity->IsWriteRequired()); 146 EXPECT_TRUE(entity->IsUnsynced()); 147 148 EXPECT_TRUE(entity->UpdateIsReflection(10)); 149 EXPECT_FALSE(entity->UpdateIsInConflict(10)); 150 151 EXPECT_FALSE(entity->UpdateIsReflection(11)); 152 EXPECT_TRUE(entity->UpdateIsInConflict(11)); 153 } 154 155 TEST_F(ModelTypeEntityTest, LocalDeletion) { 156 scoped_ptr<ModelTypeEntity> entity( 157 ModelTypeEntity::FromServerUpdate(kServerId, 158 kClientTagHash, 159 kClientTag, // As non-unique name. 160 10, 161 specifics, 162 false, 163 kCtime, 164 kMtime, 165 std::string())); 166 167 entity->Delete(); 168 169 EXPECT_TRUE(entity->IsWriteRequired()); 170 EXPECT_TRUE(entity->IsUnsynced()); 171 172 EXPECT_TRUE(entity->UpdateIsReflection(10)); 173 EXPECT_FALSE(entity->UpdateIsInConflict(10)); 174 175 EXPECT_FALSE(entity->UpdateIsReflection(11)); 176 EXPECT_TRUE(entity->UpdateIsInConflict(11)); 177 } 178 179 } // namespace syncer 180