blob: 49e916815597fad316ff00e8e947aaa8df37bf12 [file] [log] [blame]
Mohamed Amir Yosefb0664a82018-05-09 12:19:251// Copyright 2018 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 "components/sync_bookmarks/synced_bookmark_tracker.h"
6
Mohamed Amir Yosefc80bdd02018-06-18 12:26:327#include "base/base64.h"
Pauline Leitao44f5a812019-07-30 10:49:518#include "base/guid.h"
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:229#include "base/strings/utf_string_conversions.h"
Mohamed Amir Yosef05fa2162018-11-09 22:42:2010#include "base/test/metrics/histogram_tester.h"
Mikel Astiz7eb326e2020-01-31 17:34:3911#include "base/test/scoped_feature_list.h"
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:2212#include "components/bookmarks/browser/bookmark_model.h"
Mohamed Amir Yosefb0664a82018-05-09 12:19:2513#include "components/bookmarks/browser/bookmark_node.h"
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:0314#include "components/bookmarks/browser/bookmark_utils.h"
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:2215#include "components/bookmarks/test/test_bookmark_client.h"
Mohamed Amir Yosefc80bdd02018-06-18 12:26:3216#include "components/sync/base/time.h"
Mohamed Amir Yosefe1f51a22018-06-25 08:59:5717#include "components/sync/base/unique_position.h"
Mohamed Amir Yosefc80bdd02018-06-18 12:26:3218#include "components/sync/model/entity_data.h"
Rushan Suleymanovcacaf582020-06-26 19:31:3219#include "components/sync_bookmarks/switches.h"
Mohamed Amir Yosefb0664a82018-05-09 12:19:2520#include "testing/gmock/include/gmock/gmock.h"
21#include "testing/gtest/include/gtest/gtest.h"
22
23using testing::Eq;
24using testing::IsNull;
25using testing::NotNull;
26
27namespace sync_bookmarks {
28
29namespace {
30
Mikel Astiz7eb326e2020-01-31 17:34:3931constexpr int kNumPermanentNodes = 3;
32
33const char kBookmarkBarId[] = "bookmark_bar_id";
34const char kMobileBookmarksId[] = "synced_bookmarks_id";
35const char kOtherBookmarksId[] = "other_bookmarks_id";
36
Mohamed Amir Yosef05fa2162018-11-09 22:42:2037// Redefinition of |enum CorruptionReason| in synced_bookmark_tracker.cc to be
38// used in tests.
39enum class ExpectedCorruptionReason {
40 NO_CORRUPTION = 0,
41 MISSING_SERVER_ID = 1,
42 BOOKMARK_ID_IN_TOMBSTONE = 2,
43 MISSING_BOOKMARK_ID = 3,
Mikel Astiz7eb326e2020-01-31 17:34:3944 DEPRECATED_COUNT_MISMATCH = 4,
45 DEPRECATED_IDS_MISMATCH = 5,
46 DUPLICATED_SERVER_ID = 6,
47 UNKNOWN_BOOKMARK_ID = 7,
48 UNTRACKED_BOOKMARK = 8,
49 BOOKMARK_GUID_MISMATCH = 9,
Rushan Suleymanov7bd510e2020-04-28 15:45:1350 DUPLICATED_CLIENT_TAG_HASH = 10,
Rushan Suleymanov25241382020-06-10 11:53:5351 TRACKED_MANAGED_NODE = 11,
Mikel Astizb78eadcf2020-07-02 13:35:1452 MISSING_CLIENT_TAG_HASH = 12,
Rushan Suleymanov25241382020-06-10 11:53:5353
Mikel Astizb78eadcf2020-07-02 13:35:1454 kMaxValue = MISSING_CLIENT_TAG_HASH
Mohamed Amir Yosef05fa2162018-11-09 22:42:2055};
56
Mohamed Amir Yosefc80bdd02018-06-18 12:26:3257sync_pb::EntitySpecifics GenerateSpecifics(const std::string& title,
58 const std::string& url) {
59 sync_pb::EntitySpecifics specifics;
Rushan Suleymanov09192192020-03-12 23:00:5960 specifics.mutable_bookmark()->set_legacy_canonicalized_title(title);
Mohamed Amir Yosefc80bdd02018-06-18 12:26:3261 specifics.mutable_bookmark()->set_url(url);
62 return specifics;
63}
64
Mikel Astiz7eb326e2020-01-31 17:34:3965sync_pb::BookmarkMetadata CreateNodeMetadata(int64_t node_id,
66 const std::string& server_id) {
67 sync_pb::BookmarkMetadata bookmark_metadata;
68 bookmark_metadata.set_id(node_id);
69 bookmark_metadata.mutable_metadata()->set_server_id(server_id);
70 return bookmark_metadata;
71}
72
73sync_pb::BookmarkMetadata CreateTombstoneMetadata(
74 const std::string& server_id) {
75 sync_pb::BookmarkMetadata bookmark_metadata;
76 bookmark_metadata.mutable_metadata()->set_server_id(server_id);
77 bookmark_metadata.mutable_metadata()->set_is_deleted(true);
Mikel Astiz7a924872020-07-14 14:05:4978 bookmark_metadata.mutable_metadata()->set_sequence_number(1);
Mikel Astiz7eb326e2020-01-31 17:34:3979 return bookmark_metadata;
80}
81
82sync_pb::BookmarkModelMetadata CreateMetadataForPermanentNodes(
83 const bookmarks::BookmarkModel* bookmark_model) {
84 sync_pb::BookmarkModelMetadata model_metadata;
85 model_metadata.mutable_model_type_state()->set_initial_sync_done(true);
86
87 *model_metadata.add_bookmarks_metadata() =
88 CreateNodeMetadata(bookmark_model->bookmark_bar_node()->id(),
89 /*server_id=*/kBookmarkBarId);
90 *model_metadata.add_bookmarks_metadata() =
91 CreateNodeMetadata(bookmark_model->mobile_node()->id(),
92 /*server_id=*/kMobileBookmarksId);
93 *model_metadata.add_bookmarks_metadata() =
94 CreateNodeMetadata(bookmark_model->other_node()->id(),
95 /*server_id=*/kOtherBookmarksId);
96
97 CHECK_EQ(kNumPermanentNodes, model_metadata.bookmarks_metadata_size());
98 return model_metadata;
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:2299}
100
Mohamed Amir Yosefb0664a82018-05-09 12:19:25101TEST(SyncedBookmarkTrackerTest, ShouldGetAssociatedNodes) {
Mikel Astiz7eb326e2020-01-31 17:34:39102 std::unique_ptr<SyncedBookmarkTracker> tracker =
103 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
104
Mohamed Amir Yosefb0664a82018-05-09 12:19:25105 const std::string kSyncId = "SYNC_ID";
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32106 const std::string kTitle = "Title";
107 const GURL kUrl("http://www.foo.com");
Mohamed Amir Yosefb0664a82018-05-09 12:19:25108 const int64_t kId = 1;
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32109 const int64_t kServerVersion = 1000;
110 const base::Time kCreationTime(base::Time::Now() -
111 base::TimeDelta::FromSeconds(1));
Mohamed Amir Yosefe1f51a22018-06-25 08:59:57112 const syncer::UniquePosition unique_position =
113 syncer::UniquePosition::InitialPosition(
114 syncer::UniquePosition::RandomSuffix());
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32115 const sync_pb::EntitySpecifics specifics =
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46116 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32117
Pauline Leitao44f5a812019-07-30 10:49:51118 bookmarks::BookmarkNode node(kId, base::GenerateGUID(), kUrl);
Mohamed Amir Yosefb0664a82018-05-09 12:19:25119 const SyncedBookmarkTracker::Entity* entity =
Mikel Astizf12d87912020-03-10 14:40:06120 tracker->Add(&node, kSyncId, kServerVersion, kCreationTime,
121 unique_position.ToProto(), specifics);
Mohamed Amir Yosefb0664a82018-05-09 12:19:25122 ASSERT_THAT(entity, NotNull());
123 EXPECT_THAT(entity->bookmark_node(), Eq(&node));
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32124 EXPECT_THAT(entity->metadata()->server_id(), Eq(kSyncId));
125 EXPECT_THAT(entity->metadata()->server_version(), Eq(kServerVersion));
126 EXPECT_THAT(entity->metadata()->creation_time(),
127 Eq(syncer::TimeToProtoTime(kCreationTime)));
Mohamed Amir Yosefe1f51a22018-06-25 08:59:57128 EXPECT_TRUE(
129 syncer::UniquePosition::FromProto(entity->metadata()->unique_position())
130 .Equals(unique_position));
131
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32132 syncer::EntityData data;
133 *data.specifics.mutable_bookmark() = specifics.bookmark();
Mohamed Amir Yosef812618f2018-07-26 13:25:49134 data.unique_position = unique_position.ToProto();
135 EXPECT_TRUE(entity->MatchesDataIgnoringParent(data));
Mikel Astiz7eb326e2020-01-31 17:34:39136 EXPECT_THAT(tracker->GetEntityForSyncId("unknown id"), IsNull());
Mohamed Amir Yosefb0664a82018-05-09 12:19:25137}
138
Mohamed Amir Yosefb2895112018-05-18 15:32:38139TEST(SyncedBookmarkTrackerTest, ShouldReturnNullForDisassociatedNodes) {
Mikel Astiz7eb326e2020-01-31 17:34:39140 std::unique_ptr<SyncedBookmarkTracker> tracker =
141 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
142
Mohamed Amir Yosefb2895112018-05-18 15:32:38143 const std::string kSyncId = "SYNC_ID";
144 const int64_t kId = 1;
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32145 const int64_t kServerVersion = 1000;
146 const base::Time kModificationTime(base::Time::Now() -
147 base::TimeDelta::FromSeconds(1));
Mohamed Amir Yosefe1f51a22018-06-25 08:59:57148 const sync_pb::UniquePosition unique_position;
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32149 const sync_pb::EntitySpecifics specifics =
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46150 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Pauline Leitao44f5a812019-07-30 10:49:51151 bookmarks::BookmarkNode node(kId, base::GenerateGUID(), GURL());
Mikel Astizf12d87912020-03-10 14:40:06152 const SyncedBookmarkTracker::Entity* entity =
153 tracker->Add(&node, kSyncId, kServerVersion, kModificationTime,
154 unique_position, specifics);
155 ASSERT_THAT(entity, NotNull());
156 ASSERT_THAT(tracker->GetEntityForSyncId(kSyncId), Eq(entity));
157 tracker->Remove(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39158 EXPECT_THAT(tracker->GetEntityForSyncId(kSyncId), IsNull());
Mohamed Amir Yosefb2895112018-05-18 15:32:38159}
160
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34161TEST(SyncedBookmarkTrackerTest, ShouldBuildBookmarkModelMetadata) {
Mikel Astiz7eb326e2020-01-31 17:34:39162 std::unique_ptr<SyncedBookmarkTracker> tracker =
163 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
164
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34165 const std::string kSyncId = "SYNC_ID";
166 const std::string kTitle = "Title";
167 const GURL kUrl("http://www.foo.com");
168 const int64_t kId = 1;
169 const int64_t kServerVersion = 1000;
170 const base::Time kCreationTime(base::Time::Now() -
171 base::TimeDelta::FromSeconds(1));
172 const syncer::UniquePosition unique_position =
173 syncer::UniquePosition::InitialPosition(
174 syncer::UniquePosition::RandomSuffix());
175 const sync_pb::EntitySpecifics specifics =
176 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
177
Pauline Leitao44f5a812019-07-30 10:49:51178 bookmarks::BookmarkNode node(kId, base::GenerateGUID(), kUrl);
Mikel Astizf12d87912020-03-10 14:40:06179 tracker->Add(&node, kSyncId, kServerVersion, kCreationTime,
Mikel Astiz7eb326e2020-01-31 17:34:39180 unique_position.ToProto(), specifics);
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34181
182 sync_pb::BookmarkModelMetadata bookmark_model_metadata =
Mikel Astiz7eb326e2020-01-31 17:34:39183 tracker->BuildBookmarkModelMetadata();
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34184
185 ASSERT_THAT(bookmark_model_metadata.bookmarks_metadata().size(), Eq(1));
186 EXPECT_THAT(
187 bookmark_model_metadata.bookmarks_metadata(0).metadata().server_id(),
188 Eq(kSyncId));
Mikel Astize69b34a2020-07-20 10:34:37189 EXPECT_TRUE(bookmark_model_metadata.has_last_sync_time());
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34190}
191
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46192TEST(SyncedBookmarkTrackerTest,
193 ShouldRequireCommitRequestWhenSequenceNumberIsIncremented) {
Mikel Astiz7eb326e2020-01-31 17:34:39194 std::unique_ptr<SyncedBookmarkTracker> tracker =
195 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
196
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46197 const std::string kSyncId = "SYNC_ID";
198 const int64_t kId = 1;
199 const int64_t kServerVersion = 1000;
200 const base::Time kModificationTime(base::Time::Now() -
201 base::TimeDelta::FromSeconds(1));
Mohamed Amir Yosefe1f51a22018-06-25 08:59:57202 const sync_pb::UniquePosition unique_position;
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46203 const sync_pb::EntitySpecifics specifics =
204 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Pauline Leitao44f5a812019-07-30 10:49:51205 bookmarks::BookmarkNode node(kId, base::GenerateGUID(), GURL());
Mikel Astizf12d87912020-03-10 14:40:06206 const SyncedBookmarkTracker::Entity* entity =
207 tracker->Add(&node, kSyncId, kServerVersion, kModificationTime,
208 unique_position, specifics);
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46209
Mikel Astiz7eb326e2020-01-31 17:34:39210 EXPECT_THAT(tracker->HasLocalChanges(), Eq(false));
Mikel Astizf12d87912020-03-10 14:40:06211 tracker->IncrementSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39212 EXPECT_THAT(tracker->HasLocalChanges(), Eq(true));
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46213 // TODO(crbug.com/516866): Test HasLocalChanges after submitting commit
214 // request in a separate test probably.
215}
216
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48217TEST(SyncedBookmarkTrackerTest, ShouldAckSequenceNumber) {
Mikel Astiz7eb326e2020-01-31 17:34:39218 std::unique_ptr<SyncedBookmarkTracker> tracker =
219 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
220
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48221 const std::string kSyncId = "SYNC_ID";
222 const int64_t kId = 1;
223 const int64_t kServerVersion = 1000;
224 const base::Time kModificationTime(base::Time::Now() -
225 base::TimeDelta::FromSeconds(1));
226 const sync_pb::UniquePosition unique_position;
227 const sync_pb::EntitySpecifics specifics =
228 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Pauline Leitao44f5a812019-07-30 10:49:51229 bookmarks::BookmarkNode node(kId, base::GenerateGUID(), GURL());
Mikel Astizf12d87912020-03-10 14:40:06230 const SyncedBookmarkTracker::Entity* entity =
231 tracker->Add(&node, kSyncId, kServerVersion, kModificationTime,
232 unique_position, specifics);
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48233
234 // Test simple scenario of ack'ing an incrememented sequence number.
Mikel Astiz7eb326e2020-01-31 17:34:39235 EXPECT_THAT(tracker->HasLocalChanges(), Eq(false));
Mikel Astizf12d87912020-03-10 14:40:06236 tracker->IncrementSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39237 EXPECT_THAT(tracker->HasLocalChanges(), Eq(true));
Mikel Astizf12d87912020-03-10 14:40:06238 tracker->AckSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39239 EXPECT_THAT(tracker->HasLocalChanges(), Eq(false));
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48240
Mikel Astiz7eb326e2020-01-31 17:34:39241 // Test ack'ing of a multiple times incremented sequence number.
Mikel Astizf12d87912020-03-10 14:40:06242 tracker->IncrementSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39243 EXPECT_THAT(tracker->HasLocalChanges(), Eq(true));
Mikel Astizf12d87912020-03-10 14:40:06244 tracker->IncrementSequenceNumber(entity);
245 tracker->IncrementSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39246 EXPECT_THAT(tracker->HasLocalChanges(), Eq(true));
Mikel Astizf12d87912020-03-10 14:40:06247 tracker->AckSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39248 EXPECT_THAT(tracker->HasLocalChanges(), Eq(false));
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48249}
250
Mohamed Amir Yosefc7097a12018-07-02 18:24:16251TEST(SyncedBookmarkTrackerTest, ShouldUpdateUponCommitResponseWithNewId) {
Mikel Astiz7eb326e2020-01-31 17:34:39252 std::unique_ptr<SyncedBookmarkTracker> tracker =
253 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
254
Mohamed Amir Yosefc7097a12018-07-02 18:24:16255 const std::string kSyncId = "SYNC_ID";
256 const std::string kNewSyncId = "NEW_SYNC_ID";
257 const int64_t kId = 1;
258 const int64_t kServerVersion = 1000;
259 const int64_t kNewServerVersion = 1001;
260 const base::Time kModificationTime(base::Time::Now() -
261 base::TimeDelta::FromSeconds(1));
262 const sync_pb::UniquePosition unique_position;
263 const sync_pb::EntitySpecifics specifics =
264 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Pauline Leitao44f5a812019-07-30 10:49:51265 bookmarks::BookmarkNode node(kId, base::GenerateGUID(), GURL());
Mohamed Amir Yosefc7097a12018-07-02 18:24:16266 const SyncedBookmarkTracker::Entity* entity =
Mikel Astizf12d87912020-03-10 14:40:06267 tracker->Add(&node, kSyncId, kServerVersion, kModificationTime,
268 unique_position, specifics);
Mohamed Amir Yosefc7097a12018-07-02 18:24:16269 ASSERT_THAT(entity, NotNull());
Mikel Astizf12d87912020-03-10 14:40:06270
271 // Initially only the old ID should be tracked.
272 ASSERT_THAT(tracker->GetEntityForSyncId(kSyncId), Eq(entity));
273 ASSERT_THAT(tracker->GetEntityForSyncId(kNewSyncId), IsNull());
274
275 // Receive a commit response with a changed id.
276 tracker->UpdateUponCommitResponse(entity, kNewSyncId, kNewServerVersion,
277 /*acked_sequence_number=*/1);
278
279 // Old id shouldn't be there, but the new one should.
280 EXPECT_THAT(tracker->GetEntityForSyncId(kSyncId), IsNull());
281 EXPECT_THAT(tracker->GetEntityForSyncId(kNewSyncId), Eq(entity));
282
Mohamed Amir Yosefc7097a12018-07-02 18:24:16283 EXPECT_THAT(entity->metadata()->server_id(), Eq(kNewSyncId));
284 EXPECT_THAT(entity->bookmark_node(), Eq(&node));
285 EXPECT_THAT(entity->metadata()->server_version(), Eq(kNewServerVersion));
286}
287
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45288TEST(SyncedBookmarkTrackerTest, ShouldUpdateId) {
Mikel Astiz7eb326e2020-01-31 17:34:39289 std::unique_ptr<SyncedBookmarkTracker> tracker =
290 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
291
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45292 const std::string kSyncId = "SYNC_ID";
293 const std::string kNewSyncId = "NEW_SYNC_ID";
294 const int64_t kServerVersion = 1000;
295 const base::Time kModificationTime(base::Time::Now() -
296 base::TimeDelta::FromSeconds(1));
297 const sync_pb::UniquePosition unique_position;
298 const sync_pb::EntitySpecifics specifics =
299 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Pauline Leitao44f5a812019-07-30 10:49:51300 bookmarks::BookmarkNode node(/*id=*/1, base::GenerateGUID(), GURL());
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45301 // Track a sync entity.
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45302 const SyncedBookmarkTracker::Entity* entity =
Mikel Astizf12d87912020-03-10 14:40:06303 tracker->Add(&node, kSyncId, kServerVersion, kModificationTime,
304 unique_position, specifics);
305
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45306 ASSERT_THAT(entity, NotNull());
Mikel Astizf12d87912020-03-10 14:40:06307 // Update the sync id.
308 tracker->UpdateSyncIdForLocalCreationIfNeeded(entity, kNewSyncId);
309
310 // Old id shouldn't be there, but the new one should.
311 EXPECT_THAT(tracker->GetEntityForSyncId(kSyncId), IsNull());
312 EXPECT_THAT(tracker->GetEntityForSyncId(kNewSyncId), Eq(entity));
313
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45314 EXPECT_THAT(entity->metadata()->server_id(), Eq(kNewSyncId));
315 EXPECT_THAT(entity->bookmark_node(), Eq(&node));
316 EXPECT_THAT(entity->metadata()->server_version(), Eq(kServerVersion));
317}
318
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51319TEST(SyncedBookmarkTrackerTest,
320 ShouldMaintainTombstoneOrderBetweenCtorAndBuildBookmarkModelMetadata) {
321 // Feed a metadata batch of 5 entries to the constructor of the tracker.
322 // First 2 are for node, and the last 4 are for tombstones.
323
324 // Server ids.
325 const std::string kId0 = "id0";
326 const std::string kId1 = "id1";
327 const std::string kId2 = "id2";
328 const std::string kId3 = "id3";
329 const std::string kId4 = "id4";
330
Mikel Astiz7eb326e2020-01-31 17:34:39331 std::unique_ptr<bookmarks::BookmarkModel> bookmark_model =
332 bookmarks::TestBookmarkClient::CreateModel();
333 const bookmarks::BookmarkNode* bookmark_bar_node =
334 bookmark_model->bookmark_bar_node();
335 const bookmarks::BookmarkNode* node0 = bookmark_model->AddFolder(
336 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
337 const bookmarks::BookmarkNode* node1 = bookmark_model->AddFolder(
338 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node1"));
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51339
Mikel Astiz7eb326e2020-01-31 17:34:39340 sync_pb::BookmarkModelMetadata initial_model_metadata =
341 CreateMetadataForPermanentNodes(bookmark_model.get());
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51342
Mikel Astiz7eb326e2020-01-31 17:34:39343 *initial_model_metadata.add_bookmarks_metadata() =
344 CreateNodeMetadata(node0->id(), /*server_id=*/kId0);
345 *initial_model_metadata.add_bookmarks_metadata() =
346 CreateNodeMetadata(node1->id(), /*server_id=*/kId1);
347 *initial_model_metadata.add_bookmarks_metadata() =
348 CreateTombstoneMetadata(/*server_id=*/kId2);
349 *initial_model_metadata.add_bookmarks_metadata() =
350 CreateTombstoneMetadata(/*server_id=*/kId3);
351 *initial_model_metadata.add_bookmarks_metadata() =
352 CreateTombstoneMetadata(/*server_id=*/kId4);
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51353
Mikel Astiz7eb326e2020-01-31 17:34:39354 std::unique_ptr<SyncedBookmarkTracker> tracker =
355 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
356 bookmark_model.get(), std::move(initial_model_metadata));
357 ASSERT_THAT(tracker, NotNull());
358
359 const sync_pb::BookmarkModelMetadata output_model_metadata =
360 tracker->BuildBookmarkModelMetadata();
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51361
362 // Tombstones should be the last 3 entries in the metadata and in the same
363 // order as given to the constructor.
Mikel Astiz7eb326e2020-01-31 17:34:39364 ASSERT_THAT(output_model_metadata.bookmarks_metadata().size(),
365 Eq(kNumPermanentNodes + 5));
366 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 2)
367 .metadata()
368 .server_id(),
369 Eq(kId2));
370 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 3)
371 .metadata()
372 .server_id(),
373 Eq(kId3));
374 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 4)
375 .metadata()
376 .server_id(),
377 Eq(kId4));
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51378}
379
380TEST(SyncedBookmarkTrackerTest,
381 ShouldMaintainOrderOfMarkDeletedCallsWhenBuildBookmarkModelMetadata) {
382 // Server ids.
383 const std::string kId0 = "id0";
384 const std::string kId1 = "id1";
385 const std::string kId2 = "id2";
386 const std::string kId3 = "id3";
387 const std::string kId4 = "id4";
388
Mikel Astiz7eb326e2020-01-31 17:34:39389 std::unique_ptr<bookmarks::BookmarkModel> bookmark_model =
390 bookmarks::TestBookmarkClient::CreateModel();
391 const bookmarks::BookmarkNode* bookmark_bar_node =
392 bookmark_model->bookmark_bar_node();
393 const bookmarks::BookmarkNode* node0 = bookmark_model->AddFolder(
394 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
395 const bookmarks::BookmarkNode* node1 = bookmark_model->AddFolder(
396 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node1"));
397 const bookmarks::BookmarkNode* node2 = bookmark_model->AddFolder(
398 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node2"));
399 const bookmarks::BookmarkNode* node3 = bookmark_model->AddFolder(
400 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node3"));
401 const bookmarks::BookmarkNode* node4 = bookmark_model->AddFolder(
402 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node4"));
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51403
Mikel Astiz7eb326e2020-01-31 17:34:39404 sync_pb::BookmarkModelMetadata initial_model_metadata =
405 CreateMetadataForPermanentNodes(bookmark_model.get());
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51406
Mikel Astiz7eb326e2020-01-31 17:34:39407 *initial_model_metadata.add_bookmarks_metadata() =
408 CreateNodeMetadata(node0->id(), /*server_id=*/kId0);
409 *initial_model_metadata.add_bookmarks_metadata() =
410 CreateNodeMetadata(node1->id(), /*server_id=*/kId1);
411 *initial_model_metadata.add_bookmarks_metadata() =
412 CreateNodeMetadata(node2->id(), /*server_id=*/kId2);
413 *initial_model_metadata.add_bookmarks_metadata() =
414 CreateNodeMetadata(node3->id(), /*server_id=*/kId3);
415 *initial_model_metadata.add_bookmarks_metadata() =
416 CreateNodeMetadata(node4->id(), /*server_id=*/kId4);
417
418 std::unique_ptr<SyncedBookmarkTracker> tracker =
419 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
420 bookmark_model.get(), std::move(initial_model_metadata));
421 ASSERT_THAT(tracker, NotNull());
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51422
423 // Mark entities deleted in that order kId2, kId4, kId1
Mikel Astizf12d87912020-03-10 14:40:06424 tracker->MarkDeleted(tracker->GetEntityForSyncId(kId2));
425 tracker->MarkDeleted(tracker->GetEntityForSyncId(kId4));
426 tracker->MarkDeleted(tracker->GetEntityForSyncId(kId1));
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51427
Mikel Astiz7eb326e2020-01-31 17:34:39428 const sync_pb::BookmarkModelMetadata output_model_metadata =
429 tracker->BuildBookmarkModelMetadata();
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51430
431 // Tombstones should be the last 3 entries in the metadata and in the same as
432 // calling MarkDeleted().
Mikel Astiz7eb326e2020-01-31 17:34:39433 ASSERT_THAT(output_model_metadata.bookmarks_metadata().size(),
434 Eq(kNumPermanentNodes + 5));
435 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 2)
436 .metadata()
437 .server_id(),
438 Eq(kId2));
439 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 3)
440 .metadata()
441 .server_id(),
442 Eq(kId4));
443 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 4)
444 .metadata()
445 .server_id(),
446 Eq(kId1));
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51447}
448
Mikel Astiz83da4262020-06-24 12:59:58449TEST(SyncedBookmarkTrackerTest, ShouldUndeleteTombstone) {
450 std::unique_ptr<SyncedBookmarkTracker> tracker =
451 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
452
453 const std::string kSyncId = "SYNC_ID";
454 const int64_t kId = 1;
455 const int64_t kServerVersion = 1000;
456 const base::Time kModificationTime(base::Time::Now() -
457 base::TimeDelta::FromSeconds(1));
458 const sync_pb::UniquePosition unique_position;
459 const sync_pb::EntitySpecifics specifics =
460 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
461 bookmarks::BookmarkNode node(kId, base::GenerateGUID(), GURL());
462 const SyncedBookmarkTracker::Entity* entity =
463 tracker->Add(&node, kSyncId, kServerVersion, kModificationTime,
464 unique_position, specifics);
465
466 ASSERT_THAT(tracker->TrackedUncommittedTombstonesCountForDebugging(), Eq(0U));
467
468 // Delete the bookmark, leading to a pending deletion (local tombstone).
469 tracker->MarkDeleted(tracker->GetEntityForSyncId(kSyncId));
470 ASSERT_THAT(entity->bookmark_node(), IsNull());
471 ASSERT_TRUE(entity->metadata()->is_deleted());
472 ASSERT_THAT(tracker->TrackedUncommittedTombstonesCountForDebugging(), Eq(1U));
473
474 // Undelete it.
475 tracker->UndeleteTombstoneForBookmarkNode(entity, &node);
476
477 EXPECT_THAT(entity->bookmark_node(), NotNull());
478 EXPECT_FALSE(entity->metadata()->is_deleted());
479 EXPECT_THAT(tracker->TrackedUncommittedTombstonesCountForDebugging(), Eq(0U));
480}
481
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22482TEST(SyncedBookmarkTrackerTest,
483 ShouldOrderParentUpdatesBeforeChildUpdatesAndDeletionsComeLast) {
484 const size_t kMaxEntries = 1000;
485
486 // Construct this structure:
487 // bookmark_bar
488 // |- node0
489 // |- node1
490 // |- node2
491
492 std::unique_ptr<bookmarks::BookmarkModel> bookmark_model =
493 bookmarks::TestBookmarkClient::CreateModel();
494
495 const bookmarks::BookmarkNode* bookmark_bar_node =
496 bookmark_model->bookmark_bar_node();
497 const bookmarks::BookmarkNode* node0 = bookmark_model->AddFolder(
498 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
499 const bookmarks::BookmarkNode* node1 = bookmark_model->AddFolder(
500 /*parent=*/node0, /*index=*/0, base::UTF8ToUTF16("node1"));
501 const bookmarks::BookmarkNode* node2 = bookmark_model->AddFolder(
502 /*parent=*/node1, /*index=*/0, base::UTF8ToUTF16("node2"));
503
504 // Server ids.
505 const std::string kId0 = "id0";
506 const std::string kId1 = "id1";
507 const std::string kId2 = "id2";
508 const std::string kId3 = "id3";
509
510 // Prepare the metadata with shuffled order.
Mikel Astiz7eb326e2020-01-31 17:34:39511 sync_pb::BookmarkModelMetadata model_metadata =
512 CreateMetadataForPermanentNodes(bookmark_model.get());
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22513
Mikel Astiz7eb326e2020-01-31 17:34:39514 *model_metadata.add_bookmarks_metadata() =
515 CreateNodeMetadata(node1->id(), /*server_id=*/kId1);
516 *model_metadata.add_bookmarks_metadata() =
517 CreateTombstoneMetadata(/*server_id=*/kId3);
518 *model_metadata.add_bookmarks_metadata() =
519 CreateNodeMetadata(node2->id(), /*server_id=*/kId2);
520 *model_metadata.add_bookmarks_metadata() =
521 CreateNodeMetadata(node0->id(), /*server_id=*/kId0);
522
523 std::unique_ptr<SyncedBookmarkTracker> tracker =
524 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
525 bookmark_model.get(), std::move(model_metadata));
526 ASSERT_THAT(tracker, NotNull());
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22527
528 // Mark the entities that they have local changes. (in shuffled order just to
529 // verify the tracker doesn't simply maintain the order of updates similar to
530 // with deletions).
Mikel Astizf12d87912020-03-10 14:40:06531 tracker->IncrementSequenceNumber(tracker->GetEntityForSyncId(kId3));
532 tracker->IncrementSequenceNumber(tracker->GetEntityForSyncId(kId1));
533 tracker->IncrementSequenceNumber(tracker->GetEntityForSyncId(kId2));
534 tracker->IncrementSequenceNumber(tracker->GetEntityForSyncId(kId0));
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22535
536 std::vector<const SyncedBookmarkTracker::Entity*> entities_with_local_change =
Mikel Astiz7eb326e2020-01-31 17:34:39537 tracker->GetEntitiesWithLocalChanges(kMaxEntries);
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22538
539 ASSERT_THAT(entities_with_local_change.size(), Eq(4U));
540 // Verify updates are in parent before child order node0 --> node1 --> node2.
541 EXPECT_THAT(entities_with_local_change[0]->metadata()->server_id(), Eq(kId0));
542 EXPECT_THAT(entities_with_local_change[1]->metadata()->server_id(), Eq(kId1));
543 EXPECT_THAT(entities_with_local_change[2]->metadata()->server_id(), Eq(kId2));
544 // Verify that deletion is the last entry.
545 EXPECT_THAT(entities_with_local_change[3]->metadata()->server_id(), Eq(kId3));
546}
547
Mikel Astiz7a924872020-07-14 14:05:49548TEST(SyncedBookmarkTrackerTest, ShouldNotInvalidateMetadata) {
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17549 std::unique_ptr<bookmarks::BookmarkModel> model =
550 bookmarks::TestBookmarkClient::CreateModel();
551
552 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
553 const bookmarks::BookmarkNode* node = model->AddFolder(
554 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
555
Mikel Astiz7eb326e2020-01-31 17:34:39556 sync_pb::BookmarkModelMetadata model_metadata =
557 CreateMetadataForPermanentNodes(model.get());
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17558
Mohamed Amir Yoseffb617fde2019-07-16 09:08:54559 // Add entry for the managed node.
Mikel Astiz7eb326e2020-01-31 17:34:39560 *model_metadata.add_bookmarks_metadata() =
561 CreateNodeMetadata(node->id(), /*server_id=*/"NodeId");
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17562
563 // Add a tombstone entry.
Mikel Astiz7eb326e2020-01-31 17:34:39564 *model_metadata.add_bookmarks_metadata() =
565 CreateTombstoneMetadata(/*server_id=*/"tombstoneId");
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17566
Mohamed Amir Yosef05fa2162018-11-09 22:42:20567 base::HistogramTester histogram_tester;
Mikel Astiz7eb326e2020-01-31 17:34:39568
569 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
570 model.get(), std::move(model_metadata)),
571 NotNull());
572
Mohamed Amir Yosef05fa2162018-11-09 22:42:20573 histogram_tester.ExpectUniqueSample(
574 "Sync.BookmarksModelMetadataCorruptionReason",
George Burgess IVa6852eb2020-10-09 09:28:41575 /*sample=*/ExpectedCorruptionReason::NO_CORRUPTION, /*expected_count=*/1);
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17576}
577
Mikel Astiz7a924872020-07-14 14:05:49578TEST(SyncedBookmarkTrackerTest, ShouldInvalidateMetadataIfMissingMobileFolder) {
Mohamed Amir Yosefb1117f742018-11-12 13:29:01579 std::unique_ptr<bookmarks::BookmarkModel> model =
580 bookmarks::TestBookmarkClient::CreateModel();
581
582 sync_pb::BookmarkModelMetadata model_metadata;
583 model_metadata.mutable_model_type_state()->set_initial_sync_done(true);
Mikel Astiz7eb326e2020-01-31 17:34:39584
Mohamed Amir Yosefb1117f742018-11-12 13:29:01585 // Add entries for all the permanent nodes except for the Mobile bookmarks
Mikel Astiz113dc1e2018-12-18 16:58:47586 // folder.
Mikel Astiz7eb326e2020-01-31 17:34:39587 *model_metadata.add_bookmarks_metadata() =
588 CreateNodeMetadata(model->bookmark_bar_node()->id(),
589 /*server_id=*/kBookmarkBarId);
590 *model_metadata.add_bookmarks_metadata() =
591 CreateNodeMetadata(model->other_node()->id(),
592 /*server_id=*/kOtherBookmarksId);
Mohamed Amir Yosefb1117f742018-11-12 13:29:01593
594 base::HistogramTester histogram_tester;
Mikel Astiz7eb326e2020-01-31 17:34:39595
596 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
597 model.get(), std::move(model_metadata)),
598 IsNull());
599
Mohamed Amir Yosefb1117f742018-11-12 13:29:01600 histogram_tester.ExpectUniqueSample(
601 "Sync.BookmarksModelMetadataCorruptionReason",
Mikel Astiz7eb326e2020-01-31 17:34:39602 /*sample=*/ExpectedCorruptionReason::UNTRACKED_BOOKMARK, /*count=*/1);
Mohamed Amir Yosefb1117f742018-11-12 13:29:01603}
604
Mikel Astiz7a924872020-07-14 14:05:49605TEST(SyncedBookmarkTrackerTest, ShouldInvalidateMetadataIfMissingServerId) {
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17606 std::unique_ptr<bookmarks::BookmarkModel> model =
607 bookmarks::TestBookmarkClient::CreateModel();
608
Mikel Astiz7eb326e2020-01-31 17:34:39609 sync_pb::BookmarkModelMetadata model_metadata =
610 CreateMetadataForPermanentNodes(model.get());
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17611
Mikel Astiz7eb326e2020-01-31 17:34:39612 // Remove a server ID to a permanent node.
613 model_metadata.mutable_bookmarks_metadata(0)
614 ->mutable_metadata()
615 ->clear_server_id();
Mikel Astiz113dc1e2018-12-18 16:58:47616
Mohamed Amir Yosef05fa2162018-11-09 22:42:20617 base::HistogramTester histogram_tester;
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17618
Mikel Astiz7eb326e2020-01-31 17:34:39619 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
620 model.get(), std::move(model_metadata)),
621 IsNull());
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17622
Mikel Astiz7eb326e2020-01-31 17:34:39623 histogram_tester.ExpectUniqueSample(
Mohamed Amir Yosef05fa2162018-11-09 22:42:20624 "Sync.BookmarksModelMetadataCorruptionReason",
625 /*sample=*/ExpectedCorruptionReason::MISSING_SERVER_ID, /*count=*/1);
Mikel Astiz7eb326e2020-01-31 17:34:39626}
Mohamed Amir Yosef05fa2162018-11-09 22:42:20627
Mikel Astiz7eb326e2020-01-31 17:34:39628TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49629 ShouldInvalidateMetadataIfMissingLocalBookmarkId) {
Mikel Astiz7eb326e2020-01-31 17:34:39630 std::unique_ptr<bookmarks::BookmarkModel> model =
631 bookmarks::TestBookmarkClient::CreateModel();
632
633 sync_pb::BookmarkModelMetadata model_metadata =
634 CreateMetadataForPermanentNodes(model.get());
635
636 const bookmarks::BookmarkNode* node = model->AddFolder(
637 /*parent=*/model->bookmark_bar_node(), /*index=*/0,
638 base::UTF8ToUTF16("node"));
639 *model_metadata.add_bookmarks_metadata() =
640 CreateNodeMetadata(node->id(), /*server_id=*/"serverid");
641
642 // Remove the local bookmark ID.
643 model_metadata.mutable_bookmarks_metadata()->rbegin()->clear_id();
644
645 base::HistogramTester histogram_tester;
646
647 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
648 model.get(), std::move(model_metadata)),
649 IsNull());
650
651 histogram_tester.ExpectUniqueSample(
Mohamed Amir Yosef05fa2162018-11-09 22:42:20652 "Sync.BookmarksModelMetadataCorruptionReason",
653 /*sample=*/ExpectedCorruptionReason::MISSING_BOOKMARK_ID, /*count=*/1);
Mikel Astiz7eb326e2020-01-31 17:34:39654}
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17655
Mikel Astiz7eb326e2020-01-31 17:34:39656TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49657 ShouldInvalidateMetadataIfTombstoneHasBookmarkId) {
Mikel Astiz7eb326e2020-01-31 17:34:39658 std::unique_ptr<bookmarks::BookmarkModel> model =
659 bookmarks::TestBookmarkClient::CreateModel();
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17660
Mikel Astiz7eb326e2020-01-31 17:34:39661 sync_pb::BookmarkModelMetadata model_metadata =
662 CreateMetadataForPermanentNodes(model.get());
663
664 *model_metadata.add_bookmarks_metadata() =
665 CreateTombstoneMetadata(/*server_id=*/"serverid");
666
667 // Add a node ID to the tombstone.
668 model_metadata.mutable_bookmarks_metadata()->rbegin()->set_id(1234);
669
670 base::HistogramTester histogram_tester;
671
672 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
673 model.get(), std::move(model_metadata)),
674 IsNull());
675
676 histogram_tester.ExpectUniqueSample(
Mohamed Amir Yosef05fa2162018-11-09 22:42:20677 "Sync.BookmarksModelMetadataCorruptionReason",
678 /*sample=*/ExpectedCorruptionReason::BOOKMARK_ID_IN_TOMBSTONE,
679 /*count=*/1);
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17680}
681
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03682TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49683 ShouldInvalidateMetadataIfUnknownLocalBookmarkId) {
Mikel Astiz7eb326e2020-01-31 17:34:39684 std::unique_ptr<bookmarks::BookmarkModel> model =
685 bookmarks::TestBookmarkClient::CreateModel();
686
687 sync_pb::BookmarkModelMetadata model_metadata =
688 CreateMetadataForPermanentNodes(model.get());
689
690 const bookmarks::BookmarkNode* node = model->AddFolder(
691 /*parent=*/model->bookmark_bar_node(), /*index=*/0,
692 base::UTF8ToUTF16("node"));
693 *model_metadata.add_bookmarks_metadata() =
694 CreateNodeMetadata(node->id(), /*server_id=*/"serverid");
695
696 // Set an arbitrary local node ID that won't match anything in BookmarkModel.
697 model_metadata.mutable_bookmarks_metadata()->rbegin()->set_id(123456);
698
699 base::HistogramTester histogram_tester;
700
701 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
702 model.get(), std::move(model_metadata)),
703 IsNull());
704
705 histogram_tester.ExpectUniqueSample(
706 "Sync.BookmarksModelMetadataCorruptionReason",
707 /*sample=*/ExpectedCorruptionReason::UNKNOWN_BOOKMARK_ID,
708 /*count=*/1);
709}
710
Mikel Astiz7a924872020-07-14 14:05:49711TEST(SyncedBookmarkTrackerTest, ShouldInvalidateMetadataIfGuidMismatch) {
Mikel Astiz7eb326e2020-01-31 17:34:39712 base::test::ScopedFeatureList override_features;
713 override_features.InitAndEnableFeature(
714 kInvalidateBookmarkSyncMetadataIfMismatchingGuid);
715
716 std::unique_ptr<bookmarks::BookmarkModel> model =
717 bookmarks::TestBookmarkClient::CreateModel();
718
719 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
720 const bookmarks::BookmarkNode* node0 = model->AddFolder(
721 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
722
723 sync_pb::BookmarkModelMetadata model_metadata =
724 CreateMetadataForPermanentNodes(model.get());
725 sync_pb::BookmarkMetadata* node0_metadata =
726 model_metadata.add_bookmarks_metadata();
727 *node0_metadata = CreateNodeMetadata(node0->id(), /*server_id=*/"id0");
728
729 // Set a mismatching client tag hash.
730 node0_metadata->mutable_metadata()->set_client_tag_hash("corrupthash");
731
732 base::HistogramTester histogram_tester;
733
734 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
735 model.get(), std::move(model_metadata)),
736 IsNull());
737
738 histogram_tester.ExpectUniqueSample(
739 "Sync.BookmarksModelMetadataCorruptionReason",
740 /*sample=*/ExpectedCorruptionReason::BOOKMARK_GUID_MISMATCH, /*count=*/1);
741}
742
743TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49744 ShouldInvalidateMetadataIfTombstoneHasDuplicatedClientTagHash) {
Rushan Suleymanov7bd510e2020-04-28 15:45:13745 std::unique_ptr<bookmarks::BookmarkModel> model =
746 bookmarks::TestBookmarkClient::CreateModel();
747
748 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
749 const bookmarks::BookmarkNode* node0 = model->AddFolder(
750 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
751
752 sync_pb::BookmarkModelMetadata model_metadata =
753 CreateMetadataForPermanentNodes(model.get());
754 sync_pb::BookmarkMetadata* node0_metadata =
755 model_metadata.add_bookmarks_metadata();
756 *node0_metadata = CreateNodeMetadata(node0->id(), /*server_id=*/"id0");
757
758 const syncer::ClientTagHash client_tag_hash =
759 syncer::ClientTagHash::FromUnhashed(syncer::BOOKMARKS, node0->guid());
760 node0_metadata->mutable_metadata()->set_client_tag_hash(
761 client_tag_hash.value());
762
763 // Add the duplicate tombstone with a different server id but same client tag
764 // hash.
765 sync_pb::BookmarkMetadata* tombstone_metadata =
766 model_metadata.add_bookmarks_metadata();
767 *tombstone_metadata = CreateTombstoneMetadata("id1");
768 tombstone_metadata->mutable_metadata()->set_client_tag_hash(
769 client_tag_hash.value());
770
771 base::HistogramTester histogram_tester;
772
773 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
774 model.get(), std::move(model_metadata)),
775 IsNull());
776
777 histogram_tester.ExpectUniqueSample(
778 "Sync.BookmarksModelMetadataCorruptionReason",
779 /*sample=*/ExpectedCorruptionReason::DUPLICATED_CLIENT_TAG_HASH,
780 /*count=*/1);
781}
782
783TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49784 ShouldInvalidateMetadataIfMissingClientTagHashWhileClientInSync) {
785 std::unique_ptr<bookmarks::BookmarkModel> model =
786 bookmarks::TestBookmarkClient::CreateModel();
787
788 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
789 const bookmarks::BookmarkNode* node0 = model->AddFolder(
790 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
791
792 sync_pb::BookmarkModelMetadata model_metadata =
793 CreateMetadataForPermanentNodes(model.get());
794 // Sync happened 23 hours ago, which is considered recent enough.
795 model_metadata.set_last_sync_time(syncer::TimeToProtoTime(
796 base::Time::Now() - base::TimeDelta::FromHours(23)));
797
798 sync_pb::BookmarkMetadata* node0_metadata =
799 model_metadata.add_bookmarks_metadata();
800 *node0_metadata = CreateNodeMetadata(node0->id(), /*server_id=*/"id0");
801
802 node0_metadata->mutable_metadata()->clear_client_tag_hash();
803
804 base::HistogramTester histogram_tester;
805 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
806 model.get(), std::move(model_metadata)),
807 IsNull());
808
809 histogram_tester.ExpectUniqueSample(
810 "Sync.BookmarksModelMetadataCorruptionReason",
811 /*sample=*/ExpectedCorruptionReason::MISSING_CLIENT_TAG_HASH,
812 /*count=*/1);
813}
814
815TEST(
816 SyncedBookmarkTrackerTest,
817 ShouldNotInvalidateMetadataDespiteMissingClientTagHashIfLastSyncedLongAgo) {
818 std::unique_ptr<bookmarks::BookmarkModel> model =
819 bookmarks::TestBookmarkClient::CreateModel();
820
821 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
822 const bookmarks::BookmarkNode* node0 = model->AddFolder(
823 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
824
825 sync_pb::BookmarkModelMetadata model_metadata =
826 CreateMetadataForPermanentNodes(model.get());
827 // Sync happened 10 days ago, which is too long ago to invalidate metadata.
828 model_metadata.set_last_sync_time(syncer::TimeToProtoTime(
829 base::Time::Now() - base::TimeDelta::FromDays(10)));
830
831 sync_pb::BookmarkMetadata* node0_metadata =
832 model_metadata.add_bookmarks_metadata();
833 *node0_metadata = CreateNodeMetadata(node0->id(), /*server_id=*/"id0");
834
835 node0_metadata->mutable_metadata()->clear_client_tag_hash();
836
837 base::HistogramTester histogram_tester;
838 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
839 model.get(), std::move(model_metadata)),
840 NotNull());
841
842 histogram_tester.ExpectUniqueSample(
843 "Sync.BookmarksModelMetadataCorruptionReason",
844 /*sample=*/ExpectedCorruptionReason::NO_CORRUPTION, /*count=*/1);
845}
846
847TEST(SyncedBookmarkTrackerTest,
848 ShouldNotInvalidateMetadataDespiteMissingClientTagIfPendingLocalChanges) {
849 std::unique_ptr<bookmarks::BookmarkModel> model =
850 bookmarks::TestBookmarkClient::CreateModel();
851
852 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
853 const bookmarks::BookmarkNode* node0 = model->AddFolder(
854 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
855
856 sync_pb::BookmarkModelMetadata model_metadata =
857 CreateMetadataForPermanentNodes(model.get());
858 // Sync 1 hour ago, which is very recent. However, there is a pending local
859 // tombstone that prevents sync metadata from being invalidated.
860 model_metadata.set_last_sync_time(syncer::TimeToProtoTime(
861 base::Time::Now() - base::TimeDelta::FromHours(1)));
862 *model_metadata.add_bookmarks_metadata() =
863 CreateTombstoneMetadata(/*server_id=*/"id0");
864
865 sync_pb::BookmarkMetadata* node0_metadata =
866 model_metadata.add_bookmarks_metadata();
867 *node0_metadata = CreateNodeMetadata(node0->id(), /*server_id=*/"id1");
868
869 node0_metadata->mutable_metadata()->clear_client_tag_hash();
870
871 base::HistogramTester histogram_tester;
872 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
873 model.get(), std::move(model_metadata)),
874 NotNull());
875
876 histogram_tester.ExpectUniqueSample(
877 "Sync.BookmarksModelMetadataCorruptionReason",
878 /*sample=*/ExpectedCorruptionReason::NO_CORRUPTION, /*count=*/1);
879}
880
881TEST(SyncedBookmarkTrackerTest,
882 ShouldInvalidateMetadataIfMissingClientTagHash) {
Mikel Astizb78eadcf2020-07-02 13:35:14883 base::test::ScopedFeatureList override_features;
884 override_features.InitAndEnableFeature(
885 kInvalidateBookmarkSyncMetadataIfClientTagMissing);
886
887 std::unique_ptr<bookmarks::BookmarkModel> model =
888 bookmarks::TestBookmarkClient::CreateModel();
889
890 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
891 const bookmarks::BookmarkNode* node0 = model->AddFolder(
892 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
893
894 sync_pb::BookmarkModelMetadata model_metadata =
895 CreateMetadataForPermanentNodes(model.get());
896 sync_pb::BookmarkMetadata* node0_metadata =
897 model_metadata.add_bookmarks_metadata();
898 *node0_metadata = CreateNodeMetadata(node0->id(), /*server_id=*/"id0");
899
900 node0_metadata->mutable_metadata()->clear_client_tag_hash();
901
902 base::HistogramTester histogram_tester;
903 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
904 model.get(), std::move(model_metadata)),
905 IsNull());
906
907 histogram_tester.ExpectUniqueSample(
908 "Sync.BookmarksModelMetadataCorruptionReason",
909 /*sample=*/ExpectedCorruptionReason::MISSING_CLIENT_TAG_HASH,
910 /*count=*/1);
911}
912
913TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49914 ShouldInvalidateMetadataIfUnsyncableNodeIsTracked) {
Rushan Suleymanov25241382020-06-10 11:53:53915 auto client = std::make_unique<bookmarks::TestBookmarkClient>();
916 bookmarks::BookmarkNode* managed_node = client->EnableManagedNode();
917
918 std::unique_ptr<bookmarks::BookmarkModel> model =
919 bookmarks::TestBookmarkClient::CreateModelWithClient(std::move(client));
920
921 // The model should contain the managed node now.
Mikel Astiz0bf1b2d12020-07-02 14:18:51922 ASSERT_THAT(GetBookmarkNodeByID(model.get(), managed_node->id()),
Rushan Suleymanov25241382020-06-10 11:53:53923 Eq(managed_node));
924
925 // Add entries for all the permanent nodes. TestBookmarkClient creates all the
926 // 3 permanent nodes.
927 sync_pb::BookmarkModelMetadata model_metadata =
928 CreateMetadataForPermanentNodes(model.get());
929
930 // Add unsyncable node to metadata.
931 *model_metadata.add_bookmarks_metadata() =
932 CreateNodeMetadata(managed_node->id(),
933 /*server_id=*/"server_id");
934
935 base::HistogramTester histogram_tester;
936 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
937 model.get(), std::move(model_metadata)),
938 IsNull());
939 histogram_tester.ExpectUniqueSample(
940 "Sync.BookmarksModelMetadataCorruptionReason",
941 /*sample=*/ExpectedCorruptionReason::TRACKED_MANAGED_NODE, /*count=*/1);
942}
943
944TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49945 ShouldNotInvalidateMetadataDespiteGuidMismatch) {
Mikel Astiz7eb326e2020-01-31 17:34:39946 base::test::ScopedFeatureList override_features;
947 override_features.InitAndDisableFeature(
948 kInvalidateBookmarkSyncMetadataIfMismatchingGuid);
949
950 std::unique_ptr<bookmarks::BookmarkModel> model =
951 bookmarks::TestBookmarkClient::CreateModel();
952
953 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
954 const bookmarks::BookmarkNode* node0 = model->AddFolder(
955 /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16("node0"));
956
957 sync_pb::BookmarkModelMetadata model_metadata =
958 CreateMetadataForPermanentNodes(model.get());
959 sync_pb::BookmarkMetadata* node0_metadata =
960 model_metadata.add_bookmarks_metadata();
961 *node0_metadata = CreateNodeMetadata(node0->id(), /*server_id=*/"id0");
962
963 // Set a mismatching client tag hash.
964 node0_metadata->mutable_metadata()->set_client_tag_hash("corrupthash");
965
966 base::HistogramTester histogram_tester;
967
968 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
969 model.get(), std::move(model_metadata)),
970 NotNull());
971
972 histogram_tester.ExpectUniqueSample(
973 "Sync.BookmarkModelMetadataClientTagState",
974 /*sample=*/0, /*count=*/1);
975}
976
977TEST(SyncedBookmarkTrackerTest,
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03978 ShouldMatchModelWithUnsyncableNodesAndMetadata) {
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03979 auto client = std::make_unique<bookmarks::TestBookmarkClient>();
Mikel Astizf50a3272020-03-12 08:07:00980 bookmarks::BookmarkNode* managed_node = client->EnableManagedNode();
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03981
982 std::unique_ptr<bookmarks::BookmarkModel> model =
983 bookmarks::TestBookmarkClient::CreateModelWithClient(std::move(client));
984
985 // The model should contain the managed node now.
Mikel Astiz0bf1b2d12020-07-02 14:18:51986 ASSERT_THAT(GetBookmarkNodeByID(model.get(), managed_node->id()),
Mohamed Amir Yoseffb617fde2019-07-16 09:08:54987 Eq(managed_node));
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03988
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03989 // Add entries for all the permanent nodes. TestBookmarkClient creates all the
990 // 3 permanent nodes.
Mikel Astiz7eb326e2020-01-31 17:34:39991 sync_pb::BookmarkModelMetadata model_metadata =
992 CreateMetadataForPermanentNodes(model.get());
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03993
Mohamed Amir Yosef05fa2162018-11-09 22:42:20994 base::HistogramTester histogram_tester;
Mikel Astiz7eb326e2020-01-31 17:34:39995 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
996 model.get(), std::move(model_metadata)),
997 NotNull());
Mohamed Amir Yosef05fa2162018-11-09 22:42:20998 histogram_tester.ExpectUniqueSample(
999 "Sync.BookmarksModelMetadataCorruptionReason",
1000 /*sample=*/ExpectedCorruptionReason::NO_CORRUPTION, /*count=*/1);
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:031001}
1002
Mikel Astiza8afa1b2020-04-09 15:47:151003TEST(SyncedBookmarkTrackerTest,
1004 ShouldPopulateFaviconHashForNewlyAddedEntities) {
1005 std::unique_ptr<SyncedBookmarkTracker> tracker =
1006 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
1007
1008 const std::string kSyncId = "SYNC_ID";
1009 const std::string kTitle = "Title";
1010 const GURL kUrl("http://www.foo.com");
1011 const int64_t kId = 1;
1012 const int64_t kServerVersion = 1000;
1013 const base::Time kCreationTime = base::Time::Now();
1014 const syncer::UniquePosition kUniquePosition =
1015 syncer::UniquePosition::InitialPosition(
1016 syncer::UniquePosition::RandomSuffix());
1017 const std::string kFaviconPngBytes = "fakefaviconbytes";
1018
1019 sync_pb::EntitySpecifics specifics = GenerateSpecifics(kTitle, kUrl.spec());
1020 specifics.mutable_bookmark()->set_favicon(kFaviconPngBytes);
1021
1022 bookmarks::BookmarkNode node(kId, base::GenerateGUID(), kUrl);
1023 const SyncedBookmarkTracker::Entity* entity =
1024 tracker->Add(&node, kSyncId, kServerVersion, kCreationTime,
1025 kUniquePosition.ToProto(), specifics);
1026
1027 EXPECT_TRUE(entity->metadata()->has_bookmark_favicon_hash());
1028 EXPECT_TRUE(entity->MatchesFaviconHash(kFaviconPngBytes));
1029 EXPECT_FALSE(entity->MatchesFaviconHash("otherhash"));
1030}
1031
1032TEST(SyncedBookmarkTrackerTest, ShouldPopulateFaviconHashUponUpdate) {
1033 const std::string kSyncId = "SYNC_ID";
1034 const std::string kTitle = "Title";
1035 const GURL kUrl("http://www.foo.com");
1036 const int64_t kServerVersion = 1000;
1037 const base::Time kModificationTime = base::Time::Now();
1038 const syncer::UniquePosition kUniquePosition =
1039 syncer::UniquePosition::InitialPosition(
1040 syncer::UniquePosition::RandomSuffix());
1041 const std::string kFaviconPngBytes = "fakefaviconbytes";
1042
1043 std::unique_ptr<bookmarks::BookmarkModel> model =
1044 bookmarks::TestBookmarkClient::CreateModel();
1045
1046 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
1047 const bookmarks::BookmarkNode* node =
1048 model->AddURL(/*parent=*/bookmark_bar_node, /*index=*/0,
1049 base::ASCIIToUTF16("Title"), GURL("http://www.url.com"));
1050
1051 sync_pb::BookmarkModelMetadata model_metadata =
1052 CreateMetadataForPermanentNodes(model.get());
1053
1054 // Add entry for the URL node.
1055 *model_metadata.add_bookmarks_metadata() =
1056 CreateNodeMetadata(node->id(), kSyncId);
1057
1058 std::unique_ptr<SyncedBookmarkTracker> tracker =
1059 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
1060 model.get(), std::move(model_metadata));
1061 ASSERT_THAT(tracker, NotNull());
1062
1063 const SyncedBookmarkTracker::Entity* entity =
1064 tracker->GetEntityForSyncId(kSyncId);
1065 ASSERT_THAT(entity, NotNull());
1066 ASSERT_FALSE(entity->metadata()->has_bookmark_favicon_hash());
1067 ASSERT_FALSE(entity->MatchesFaviconHash(kFaviconPngBytes));
1068
1069 sync_pb::EntitySpecifics specifics = GenerateSpecifics(kTitle, kUrl.spec());
1070 specifics.mutable_bookmark()->set_favicon(kFaviconPngBytes);
1071
1072 tracker->Update(entity, kServerVersion, kModificationTime,
1073 kUniquePosition.ToProto(), specifics);
1074
1075 EXPECT_TRUE(entity->metadata()->has_bookmark_favicon_hash());
1076 EXPECT_TRUE(entity->MatchesFaviconHash(kFaviconPngBytes));
1077 EXPECT_FALSE(entity->MatchesFaviconHash("otherhash"));
1078}
1079
1080TEST(SyncedBookmarkTrackerTest, ShouldPopulateFaviconHashExplicitly) {
1081 const std::string kSyncId = "SYNC_ID";
1082 const std::string kFaviconPngBytes = "fakefaviconbytes";
1083
1084 std::unique_ptr<bookmarks::BookmarkModel> model =
1085 bookmarks::TestBookmarkClient::CreateModel();
1086
1087 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
1088 const bookmarks::BookmarkNode* node =
1089 model->AddURL(/*parent=*/bookmark_bar_node, /*index=*/0,
1090 base::ASCIIToUTF16("Title"), GURL("http://www.url.com"));
1091
1092 sync_pb::BookmarkModelMetadata model_metadata =
1093 CreateMetadataForPermanentNodes(model.get());
1094
1095 // Add entry for the URL node.
1096 *model_metadata.add_bookmarks_metadata() =
1097 CreateNodeMetadata(node->id(), kSyncId);
1098
1099 std::unique_ptr<SyncedBookmarkTracker> tracker =
1100 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
1101 model.get(), std::move(model_metadata));
1102 ASSERT_THAT(tracker, NotNull());
1103
1104 const SyncedBookmarkTracker::Entity* entity =
1105 tracker->GetEntityForSyncId(kSyncId);
1106 ASSERT_THAT(entity, NotNull());
1107 ASSERT_FALSE(entity->metadata()->has_bookmark_favicon_hash());
1108 ASSERT_FALSE(entity->MatchesFaviconHash(kFaviconPngBytes));
1109
1110 tracker->PopulateFaviconHashIfUnset(entity, kFaviconPngBytes);
1111 EXPECT_TRUE(entity->metadata()->has_bookmark_favicon_hash());
1112 EXPECT_TRUE(entity->MatchesFaviconHash(kFaviconPngBytes));
1113 EXPECT_FALSE(entity->MatchesFaviconHash("otherhash"));
1114
1115 // Further calls should be ignored.
1116 tracker->PopulateFaviconHashIfUnset(entity, "otherpngbytes");
1117 EXPECT_TRUE(entity->MatchesFaviconHash(kFaviconPngBytes));
1118}
1119
Rushan Suleymanovcacaf582020-06-26 19:31:321120TEST(SyncedBookmarkTrackerTest, ShouldNotReuploadEntitiesAfterMergeAndRestart) {
1121 base::test::ScopedFeatureList override_features;
1122 override_features.InitAndEnableFeature(
1123 switches::kSyncReuploadBookmarkFullTitles);
1124 const std::string kTitle = "Title";
1125 const GURL kUrl("http://www.foo.com");
1126
1127 sync_pb::ModelTypeState model_type_state;
1128 model_type_state.set_initial_sync_done(true);
1129 std::unique_ptr<SyncedBookmarkTracker> tracker =
1130 SyncedBookmarkTracker::CreateEmpty(model_type_state);
1131 tracker->SetBookmarksFullTitleReuploaded();
1132
1133 std::unique_ptr<bookmarks::BookmarkModel> model =
1134 bookmarks::TestBookmarkClient::CreateModel();
1135 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
1136 const bookmarks::BookmarkNode* node =
1137 model->AddURL(/*parent=*/bookmark_bar_node, /*index=*/0,
1138 base::UTF8ToUTF16(kTitle), kUrl);
1139
1140 const sync_pb::EntitySpecifics specifics =
1141 GenerateSpecifics(kTitle, kUrl.spec());
1142 tracker->Add(node, /*sync_id=*/"id", /*server_version=*/0,
1143 /*creation_time=*/base::Time::Now(),
1144 syncer::UniquePosition::InitialPosition(
1145 syncer::UniquePosition::RandomSuffix())
1146 .ToProto(),
1147 specifics);
1148
1149 sync_pb::EntitySpecifics permanent_specifics;
1150 permanent_specifics.mutable_bookmark();
1151
1152 // Add permanent nodes to tracker.
1153 tracker->Add(model->bookmark_bar_node(), kBookmarkBarId, /*server_version=*/0,
1154 /*creation_time=*/base::Time::Now(),
1155 syncer::UniquePosition::InitialPosition(
1156 syncer::UniquePosition::RandomSuffix())
1157 .ToProto(),
1158 permanent_specifics);
1159 tracker->Add(model->other_node(), kOtherBookmarksId, /*server_version=*/0,
1160 /*creation_time=*/base::Time::Now(),
1161 syncer::UniquePosition::InitialPosition(
1162 syncer::UniquePosition::RandomSuffix())
1163 .ToProto(),
1164 permanent_specifics);
1165 tracker->Add(model->mobile_node(), kMobileBookmarksId, /*server_version=*/0,
1166 /*creation_time=*/base::Time::Now(),
1167 syncer::UniquePosition::InitialPosition(
1168 syncer::UniquePosition::RandomSuffix())
1169 .ToProto(),
1170 permanent_specifics);
1171
1172 ASSERT_FALSE(tracker->HasLocalChanges());
1173
1174 // Simulate browser restart.
1175 tracker = SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
1176 model.get(), tracker->BuildBookmarkModelMetadata());
1177 ASSERT_THAT(tracker, NotNull());
1178 EXPECT_FALSE(tracker->HasLocalChanges());
1179 EXPECT_EQ(4u, tracker->TrackedEntitiesCountForTest());
1180}
1181
1182TEST(SyncedBookmarkTrackerTest,
1183 ShouldResetReuploadFlagOnDisabledFeatureToggle) {
1184 base::test::ScopedFeatureList override_features;
1185 override_features.InitAndDisableFeature(
1186 switches::kSyncReuploadBookmarkFullTitles);
1187
1188 const std::string kTitle = "Title";
1189 const GURL kUrl("http://www.foo.com");
1190
1191 std::unique_ptr<bookmarks::BookmarkModel> bookmark_model =
1192 bookmarks::TestBookmarkClient::CreateModel();
1193
1194 sync_pb::ModelTypeState model_type_state;
1195 model_type_state.set_initial_sync_done(true);
1196 sync_pb::BookmarkModelMetadata initial_model_metadata =
1197 CreateMetadataForPermanentNodes(bookmark_model.get());
1198 initial_model_metadata.set_bookmarks_full_title_reuploaded(true);
1199 std::unique_ptr<SyncedBookmarkTracker> tracker =
1200 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
1201 bookmark_model.get(), std::move(initial_model_metadata));
1202 ASSERT_THAT(tracker, NotNull());
1203
1204 EXPECT_FALSE(
1205 tracker->BuildBookmarkModelMetadata().bookmarks_full_title_reuploaded());
1206}
1207
Mohamed Amir Yosefb0664a82018-05-09 12:19:251208} // namespace
1209
1210} // namespace sync_bookmarks