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_thread_sync_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
15namespace syncer {
16
17// Some simple sanity tests for the ModelThreadSyncEntity.
18//
19// A lot of the more complicated sync logic is implemented in the
20// NonBlockingTypeProcessor that owns the ModelThreadSyncEntity.  We
21// can't unit test it 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 NonBlockingTypeProcessor tests.
26class ModelThreadSyncEntityTest : public ::testing::Test {
27 public:
28  ModelThreadSyncEntityTest()
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
48TEST_F(ModelThreadSyncEntityTest, NewLocalItem) {
49  scoped_ptr<ModelThreadSyncEntity> entity(
50      ModelThreadSyncEntity::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
58TEST_F(ModelThreadSyncEntityTest, FromServerUpdate) {
59  scoped_ptr<ModelThreadSyncEntity> entity(
60      ModelThreadSyncEntity::FromServerUpdate(
61          kServerId,
62          kClientTagHash,
63          kClientTag,  // As non-unique name.
64          10,
65          specifics,
66          false,
67          kCtime,
68          kMtime));
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.
82TEST_F(ModelThreadSyncEntityTest, TombstoneUpdate) {
83  scoped_ptr<ModelThreadSyncEntity> entity(
84      ModelThreadSyncEntity::FromServerUpdate(
85          kServerId,
86          kClientTagHash,
87          kClientTag,  // As non-unique name.
88          10,
89          sync_pb::EntitySpecifics(),
90          true,
91          kCtime,
92          kMtime));
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.
103TEST_F(ModelThreadSyncEntityTest, ApplyUpdate) {
104  scoped_ptr<ModelThreadSyncEntity> entity(
105      ModelThreadSyncEntity::FromServerUpdate(
106          kServerId,
107          kClientTagHash,
108          kClientTag,  // As non-unique name.
109          10,
110          specifics,
111          false,
112          kCtime,
113          kMtime));
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
121  EXPECT_TRUE(entity->IsWriteRequired());
122  EXPECT_FALSE(entity->IsUnsynced());
123  EXPECT_TRUE(entity->UpdateIsReflection(11));
124  EXPECT_FALSE(entity->UpdateIsReflection(12));
125}
126
127TEST_F(ModelThreadSyncEntityTest, LocalChange) {
128  scoped_ptr<ModelThreadSyncEntity> entity(
129      ModelThreadSyncEntity::FromServerUpdate(
130          kServerId,
131          kClientTagHash,
132          kClientTag,  // As non-unique name.
133          10,
134          specifics,
135          false,
136          kCtime,
137          kMtime));
138
139  sync_pb::EntitySpecifics specifics2;
140  specifics2.CopyFrom(specifics);
141  specifics2.mutable_preference()->set_value("new.pref.value");
142
143  entity->MakeLocalChange(specifics2);
144  EXPECT_TRUE(entity->IsWriteRequired());
145  EXPECT_TRUE(entity->IsUnsynced());
146
147  EXPECT_TRUE(entity->UpdateIsReflection(10));
148  EXPECT_FALSE(entity->UpdateIsInConflict(10));
149
150  EXPECT_FALSE(entity->UpdateIsReflection(11));
151  EXPECT_TRUE(entity->UpdateIsInConflict(11));
152}
153
154TEST_F(ModelThreadSyncEntityTest, LocalDeletion) {
155  scoped_ptr<ModelThreadSyncEntity> entity(
156      ModelThreadSyncEntity::FromServerUpdate(
157          kServerId,
158          kClientTagHash,
159          kClientTag,  // As non-unique name.
160          10,
161          specifics,
162          false,
163          kCtime,
164          kMtime));
165
166  entity->Delete();
167
168  EXPECT_TRUE(entity->IsWriteRequired());
169  EXPECT_TRUE(entity->IsUnsynced());
170
171  EXPECT_TRUE(entity->UpdateIsReflection(10));
172  EXPECT_FALSE(entity->UpdateIsInConflict(10));
173
174  EXPECT_FALSE(entity->UpdateIsReflection(11));
175  EXPECT_TRUE(entity->UpdateIsInConflict(11));
176}
177
178}  // namespace syncer
179