diff options
Diffstat (limited to 'sync/engine/model_type_entity_unittest.cc')
-rw-r--r-- | sync/engine/model_type_entity_unittest.cc | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/sync/engine/model_type_entity_unittest.cc b/sync/engine/model_type_entity_unittest.cc new file mode 100644 index 0000000..c605732 --- /dev/null +++ b/sync/engine/model_type_entity_unittest.cc @@ -0,0 +1,173 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sync/engine/model_type_entity.h" + +#include "base/memory/scoped_ptr.h" +#include "base/time/time.h" +#include "sync/internal_api/public/base/model_type.h" +#include "sync/protocol/sync.pb.h" +#include "sync/syncable/syncable_util.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace syncer { + +// Some simple sanity tests for the ModelTypeEntity. +// +// A lot of the more complicated sync logic is implemented in the +// ModelTypeSyncProxyImpl that owns the ModelTypeEntity. We can't unit test it +// here. +// +// Instead, we focus on simple tests to make sure that variables are getting +// properly intialized and flags properly set. Anything more complicated would +// be a redundant and incomplete version of the ModelTypeSyncProxyImpl tests. +class ModelTypeEntityTest : public ::testing::Test { + public: + ModelTypeEntityTest() + : kServerId("ServerID"), + kClientTag("sample.pref.name"), + kClientTagHash(syncable::GenerateSyncableHash(PREFERENCES, kClientTag)), + kCtime(base::Time::UnixEpoch() + base::TimeDelta::FromDays(10)), + kMtime(base::Time::UnixEpoch() + base::TimeDelta::FromDays(20)) { + sync_pb::PreferenceSpecifics* pref_specifics = + specifics.mutable_preference(); + pref_specifics->set_name(kClientTag); + pref_specifics->set_value("pref.value"); + } + + const std::string kServerId; + const std::string kClientTag; + const std::string kClientTagHash; + const base::Time kCtime; + const base::Time kMtime; + sync_pb::EntitySpecifics specifics; +}; + +TEST_F(ModelTypeEntityTest, NewLocalItem) { + scoped_ptr<ModelTypeEntity> entity( + ModelTypeEntity::NewLocalItem("asdf", specifics, kCtime)); + + EXPECT_TRUE(entity->IsWriteRequired()); + EXPECT_TRUE(entity->IsUnsynced()); + EXPECT_FALSE(entity->UpdateIsReflection(1)); + EXPECT_TRUE(entity->UpdateIsInConflict(1)); +} + +TEST_F(ModelTypeEntityTest, FromServerUpdate) { + scoped_ptr<ModelTypeEntity> entity( + ModelTypeEntity::FromServerUpdate(kServerId, + kClientTagHash, + kClientTag, // As non-unique name. + 10, + specifics, + false, + kCtime, + kMtime)); + + EXPECT_TRUE(entity->IsWriteRequired()); + EXPECT_FALSE(entity->IsUnsynced()); + EXPECT_TRUE(entity->UpdateIsReflection(9)); + EXPECT_TRUE(entity->UpdateIsReflection(10)); + EXPECT_FALSE(entity->UpdateIsReflection(11)); + EXPECT_FALSE(entity->UpdateIsInConflict(11)); +} + +// Tombstones should behave just like regular updates. Mostly. The strangest +// thing about them is that they don't have specifics, so it can be hard to +// detect their type. Fortunately, this class doesn't care about types in +// received updates. +TEST_F(ModelTypeEntityTest, TombstoneUpdate) { + scoped_ptr<ModelTypeEntity> entity( + ModelTypeEntity::FromServerUpdate(kServerId, + kClientTagHash, + kClientTag, // As non-unique name. + 10, + sync_pb::EntitySpecifics(), + true, + kCtime, + kMtime)); + + EXPECT_TRUE(entity->IsWriteRequired()); + EXPECT_FALSE(entity->IsUnsynced()); + EXPECT_TRUE(entity->UpdateIsReflection(9)); + EXPECT_TRUE(entity->UpdateIsReflection(10)); + EXPECT_FALSE(entity->UpdateIsReflection(11)); + EXPECT_FALSE(entity->UpdateIsInConflict(11)); +} + +// Apply a deletion update. +TEST_F(ModelTypeEntityTest, ApplyUpdate) { + scoped_ptr<ModelTypeEntity> entity( + ModelTypeEntity::FromServerUpdate(kServerId, + kClientTagHash, + kClientTag, // As non-unique name. + 10, + specifics, + false, + kCtime, + kMtime)); + + // A deletion update one version later. + entity->ApplyUpdateFromServer(11, + true, + sync_pb::EntitySpecifics(), + kMtime + base::TimeDelta::FromSeconds(10)); + + EXPECT_TRUE(entity->IsWriteRequired()); + EXPECT_FALSE(entity->IsUnsynced()); + EXPECT_TRUE(entity->UpdateIsReflection(11)); + EXPECT_FALSE(entity->UpdateIsReflection(12)); +} + +TEST_F(ModelTypeEntityTest, LocalChange) { + scoped_ptr<ModelTypeEntity> entity( + ModelTypeEntity::FromServerUpdate(kServerId, + kClientTagHash, + kClientTag, // As non-unique name. + 10, + specifics, + false, + kCtime, + kMtime)); + + sync_pb::EntitySpecifics specifics2; + specifics2.CopyFrom(specifics); + specifics2.mutable_preference()->set_value("new.pref.value"); + + entity->MakeLocalChange(specifics2); + EXPECT_TRUE(entity->IsWriteRequired()); + EXPECT_TRUE(entity->IsUnsynced()); + + EXPECT_TRUE(entity->UpdateIsReflection(10)); + EXPECT_FALSE(entity->UpdateIsInConflict(10)); + + EXPECT_FALSE(entity->UpdateIsReflection(11)); + EXPECT_TRUE(entity->UpdateIsInConflict(11)); +} + +TEST_F(ModelTypeEntityTest, LocalDeletion) { + scoped_ptr<ModelTypeEntity> entity( + ModelTypeEntity::FromServerUpdate(kServerId, + kClientTagHash, + kClientTag, // As non-unique name. + 10, + specifics, + false, + kCtime, + kMtime)); + + entity->Delete(); + + EXPECT_TRUE(entity->IsWriteRequired()); + EXPECT_TRUE(entity->IsUnsynced()); + + EXPECT_TRUE(entity->UpdateIsReflection(10)); + EXPECT_FALSE(entity->UpdateIsInConflict(10)); + + EXPECT_FALSE(entity->UpdateIsReflection(11)); + EXPECT_TRUE(entity->UpdateIsInConflict(11)); +} + +} // namespace syncer |