blob: 7ecef784b1d3296d68972fcdab6b76cb11054862 [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"
Mikel Astizfa6c7e62020-11-06 10:29:2516#include "components/sync/base/client_tag_hash.h"
Mohamed Amir Yosefc80bdd02018-06-18 12:26:3217#include "components/sync/base/time.h"
Mohamed Amir Yosefe1f51a22018-06-25 08:59:5718#include "components/sync/base/unique_position.h"
Victor Hugo Vianna Silvaa0a7abb2021-01-29 19:25:2419#include "components/sync/engine/entity_data.h"
Victor Hugo Vianna Silvae92e3002021-07-26 14:38:5020#include "components/sync/protocol/bookmark_model_metadata.pb.h"
21#include "components/sync/protocol/entity_specifics.pb.h"
22#include "components/sync/protocol/model_type_state.pb.h"
Rushan Suleymanovcacaf582020-06-26 19:31:3223#include "components/sync_bookmarks/switches.h"
Mohamed Amir Yosefb0664a82018-05-09 12:19:2524#include "testing/gmock/include/gmock/gmock.h"
25#include "testing/gtest/include/gtest/gtest.h"
26
27using testing::Eq;
28using testing::IsNull;
29using testing::NotNull;
30
31namespace sync_bookmarks {
32
33namespace {
34
Mikel Astiz7eb326e2020-01-31 17:34:3935constexpr int kNumPermanentNodes = 3;
36
37const char kBookmarkBarId[] = "bookmark_bar_id";
38const char kMobileBookmarksId[] = "synced_bookmarks_id";
39const char kOtherBookmarksId[] = "other_bookmarks_id";
40
Mohamed Amir Yosef05fa2162018-11-09 22:42:2041// Redefinition of |enum CorruptionReason| in synced_bookmark_tracker.cc to be
42// used in tests.
43enum class ExpectedCorruptionReason {
44 NO_CORRUPTION = 0,
45 MISSING_SERVER_ID = 1,
46 BOOKMARK_ID_IN_TOMBSTONE = 2,
47 MISSING_BOOKMARK_ID = 3,
Mikel Astiz7eb326e2020-01-31 17:34:3948 DEPRECATED_COUNT_MISMATCH = 4,
49 DEPRECATED_IDS_MISMATCH = 5,
50 DUPLICATED_SERVER_ID = 6,
51 UNKNOWN_BOOKMARK_ID = 7,
52 UNTRACKED_BOOKMARK = 8,
53 BOOKMARK_GUID_MISMATCH = 9,
Rushan Suleymanov7bd510e2020-04-28 15:45:1354 DUPLICATED_CLIENT_TAG_HASH = 10,
Rushan Suleymanov25241382020-06-10 11:53:5355 TRACKED_MANAGED_NODE = 11,
Mikel Astizb78eadcf2020-07-02 13:35:1456 MISSING_CLIENT_TAG_HASH = 12,
Rushan Suleymanov25241382020-06-10 11:53:5357
Mikel Astizb78eadcf2020-07-02 13:35:1458 kMaxValue = MISSING_CLIENT_TAG_HASH
Mohamed Amir Yosef05fa2162018-11-09 22:42:2059};
60
Mohamed Amir Yosefc80bdd02018-06-18 12:26:3261sync_pb::EntitySpecifics GenerateSpecifics(const std::string& title,
62 const std::string& url) {
63 sync_pb::EntitySpecifics specifics;
Rushan Suleymanov09192192020-03-12 23:00:5964 specifics.mutable_bookmark()->set_legacy_canonicalized_title(title);
Mohamed Amir Yosefc80bdd02018-06-18 12:26:3265 specifics.mutable_bookmark()->set_url(url);
Mikel Astiza08d9662021-07-28 17:10:3466 *specifics.mutable_bookmark()->mutable_unique_position() =
67 syncer::UniquePosition::InitialPosition(
68 syncer::UniquePosition::RandomSuffix())
69 .ToProto();
Mohamed Amir Yosefc80bdd02018-06-18 12:26:3270 return specifics;
71}
72
Mikel Astizfa6c7e62020-11-06 10:29:2573// |node| must not be nullptr.
74sync_pb::BookmarkMetadata CreateNodeMetadata(
75 const bookmarks::BookmarkNode* node,
76 const std::string& server_id) {
Mikel Astiz7eb326e2020-01-31 17:34:3977 sync_pb::BookmarkMetadata bookmark_metadata;
Mikel Astizfa6c7e62020-11-06 10:29:2578 bookmark_metadata.set_id(node->id());
Mikel Astiz7eb326e2020-01-31 17:34:3979 bookmark_metadata.mutable_metadata()->set_server_id(server_id);
Mikel Astizfa6c7e62020-11-06 10:29:2580 bookmark_metadata.mutable_metadata()->set_client_tag_hash(
Daniel Hosseinian6de24fa2020-11-17 19:19:5381 syncer::ClientTagHash::FromUnhashed(syncer::BOOKMARKS,
82 node->guid().AsLowercaseString())
Mikel Astizfa6c7e62020-11-06 10:29:2583 .value());
Mikel Astiz7eb326e2020-01-31 17:34:3984 return bookmark_metadata;
85}
86
87sync_pb::BookmarkMetadata CreateTombstoneMetadata(
Mikel Astizfa6c7e62020-11-06 10:29:2588 const std::string& server_id,
89 const syncer::ClientTagHash& client_tag_hash) {
Mikel Astiz7eb326e2020-01-31 17:34:3990 sync_pb::BookmarkMetadata bookmark_metadata;
91 bookmark_metadata.mutable_metadata()->set_server_id(server_id);
92 bookmark_metadata.mutable_metadata()->set_is_deleted(true);
Mikel Astiz7a924872020-07-14 14:05:4993 bookmark_metadata.mutable_metadata()->set_sequence_number(1);
Mikel Astizfa6c7e62020-11-06 10:29:2594 bookmark_metadata.mutable_metadata()->set_client_tag_hash(
95 client_tag_hash.value());
Mikel Astiz7eb326e2020-01-31 17:34:3996 return bookmark_metadata;
97}
98
99sync_pb::BookmarkModelMetadata CreateMetadataForPermanentNodes(
100 const bookmarks::BookmarkModel* bookmark_model) {
101 sync_pb::BookmarkModelMetadata model_metadata;
102 model_metadata.mutable_model_type_state()->set_initial_sync_done(true);
103
104 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25105 CreateNodeMetadata(bookmark_model->bookmark_bar_node(),
Mikel Astiz7eb326e2020-01-31 17:34:39106 /*server_id=*/kBookmarkBarId);
107 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25108 CreateNodeMetadata(bookmark_model->mobile_node(),
Mikel Astiz7eb326e2020-01-31 17:34:39109 /*server_id=*/kMobileBookmarksId);
110 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25111 CreateNodeMetadata(bookmark_model->other_node(),
Mikel Astiz7eb326e2020-01-31 17:34:39112 /*server_id=*/kOtherBookmarksId);
113
114 CHECK_EQ(kNumPermanentNodes, model_metadata.bookmarks_metadata_size());
115 return model_metadata;
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22116}
117
Mikel Astiz219dce72021-02-16 12:47:32118TEST(SyncedBookmarkTrackerTest, ShouldAddEntity) {
Mikel Astiz7eb326e2020-01-31 17:34:39119 std::unique_ptr<SyncedBookmarkTracker> tracker =
120 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
121
Mohamed Amir Yosefb0664a82018-05-09 12:19:25122 const std::string kSyncId = "SYNC_ID";
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32123 const std::string kTitle = "Title";
124 const GURL kUrl("http://www.foo.com");
Mohamed Amir Yosefb0664a82018-05-09 12:19:25125 const int64_t kId = 1;
Mikel Astiz219dce72021-02-16 12:47:32126 const base::GUID kGuid = base::GUID::GenerateRandomV4();
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32127 const int64_t kServerVersion = 1000;
128 const base::Time kCreationTime(base::Time::Now() -
129 base::TimeDelta::FromSeconds(1));
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32130 const sync_pb::EntitySpecifics specifics =
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46131 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32132
Mikel Astiz219dce72021-02-16 12:47:32133 bookmarks::BookmarkNode node(kId, kGuid, kUrl);
Mohamed Amir Yosefb0664a82018-05-09 12:19:25134 const SyncedBookmarkTracker::Entity* entity =
Mikel Astiza08d9662021-07-28 17:10:34135 tracker->Add(&node, kSyncId, kServerVersion, kCreationTime, specifics);
Mohamed Amir Yosefb0664a82018-05-09 12:19:25136 ASSERT_THAT(entity, NotNull());
137 EXPECT_THAT(entity->bookmark_node(), Eq(&node));
Mikel Astiz219dce72021-02-16 12:47:32138 EXPECT_THAT(entity->GetClientTagHash(),
139 Eq(syncer::ClientTagHash::FromUnhashed(
140 syncer::BOOKMARKS, kGuid.AsLowercaseString())));
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32141 EXPECT_THAT(entity->metadata()->server_id(), Eq(kSyncId));
142 EXPECT_THAT(entity->metadata()->server_version(), Eq(kServerVersion));
143 EXPECT_THAT(entity->metadata()->creation_time(),
144 Eq(syncer::TimeToProtoTime(kCreationTime)));
Mohamed Amir Yosefe1f51a22018-06-25 08:59:57145 EXPECT_TRUE(
146 syncer::UniquePosition::FromProto(entity->metadata()->unique_position())
Mikel Astiza08d9662021-07-28 17:10:34147 .Equals(syncer::UniquePosition::FromProto(
148 specifics.bookmark().unique_position())));
Mikel Astiz219dce72021-02-16 12:47:32149 EXPECT_THAT(tracker->GetEntityForSyncId(kSyncId), Eq(entity));
150 EXPECT_THAT(tracker->GetEntityForBookmarkNode(&node), Eq(entity));
151 EXPECT_THAT(
152 tracker->GetEntityForClientTagHash(syncer::ClientTagHash::FromUnhashed(
153 syncer::BOOKMARKS, kGuid.AsLowercaseString())),
154 Eq(entity));
Mohamed Amir Yosefe1f51a22018-06-25 08:59:57155
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32156 syncer::EntityData data;
157 *data.specifics.mutable_bookmark() = specifics.bookmark();
Mikel Astiz8d2dce42021-07-26 19:05:36158 EXPECT_TRUE(entity->MatchesDataPossiblyIncludingParent(data));
Mikel Astiz219dce72021-02-16 12:47:32159
Mikel Astiz7eb326e2020-01-31 17:34:39160 EXPECT_THAT(tracker->GetEntityForSyncId("unknown id"), IsNull());
Mohamed Amir Yosefb0664a82018-05-09 12:19:25161}
162
Mikel Astiz219dce72021-02-16 12:47:32163TEST(SyncedBookmarkTrackerTest, ShouldRemoveEntity) {
Mikel Astiz7eb326e2020-01-31 17:34:39164 std::unique_ptr<SyncedBookmarkTracker> tracker =
165 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
166
Mohamed Amir Yosefb2895112018-05-18 15:32:38167 const std::string kSyncId = "SYNC_ID";
168 const int64_t kId = 1;
Mikel Astiz219dce72021-02-16 12:47:32169 const base::GUID kGuid = base::GUID::GenerateRandomV4();
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32170 const int64_t kServerVersion = 1000;
171 const base::Time kModificationTime(base::Time::Now() -
172 base::TimeDelta::FromSeconds(1));
Mohamed Amir Yosefc80bdd02018-06-18 12:26:32173 const sync_pb::EntitySpecifics specifics =
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46174 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Mikel Astiz219dce72021-02-16 12:47:32175 bookmarks::BookmarkNode node(kId, kGuid, GURL());
Mikel Astiza08d9662021-07-28 17:10:34176 const SyncedBookmarkTracker::Entity* entity = tracker->Add(
177 &node, kSyncId, kServerVersion, kModificationTime, specifics);
Mikel Astizf12d87912020-03-10 14:40:06178 ASSERT_THAT(entity, NotNull());
179 ASSERT_THAT(tracker->GetEntityForSyncId(kSyncId), Eq(entity));
Mikel Astiz219dce72021-02-16 12:47:32180 ASSERT_THAT(tracker->GetEntityForBookmarkNode(&node), Eq(entity));
181 ASSERT_THAT(
182 tracker->GetEntityForClientTagHash(syncer::ClientTagHash::FromUnhashed(
183 syncer::BOOKMARKS, kGuid.AsLowercaseString())),
184 Eq(entity));
185
Mikel Astizf12d87912020-03-10 14:40:06186 tracker->Remove(entity);
Mikel Astiz219dce72021-02-16 12:47:32187
Mikel Astiz7eb326e2020-01-31 17:34:39188 EXPECT_THAT(tracker->GetEntityForSyncId(kSyncId), IsNull());
Mikel Astiz219dce72021-02-16 12:47:32189 EXPECT_THAT(tracker->GetEntityForBookmarkNode(&node), IsNull());
190 EXPECT_THAT(
191 tracker->GetEntityForClientTagHash(syncer::ClientTagHash::FromUnhashed(
192 syncer::BOOKMARKS, kGuid.AsLowercaseString())),
193 IsNull());
Mohamed Amir Yosefb2895112018-05-18 15:32:38194}
195
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34196TEST(SyncedBookmarkTrackerTest, ShouldBuildBookmarkModelMetadata) {
Mikel Astiz7eb326e2020-01-31 17:34:39197 std::unique_ptr<SyncedBookmarkTracker> tracker =
198 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
199
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34200 const std::string kSyncId = "SYNC_ID";
201 const std::string kTitle = "Title";
202 const GURL kUrl("http://www.foo.com");
203 const int64_t kId = 1;
204 const int64_t kServerVersion = 1000;
205 const base::Time kCreationTime(base::Time::Now() -
206 base::TimeDelta::FromSeconds(1));
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34207 const sync_pb::EntitySpecifics specifics =
208 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
209
Daniel Hosseinian26cb15fe2020-11-14 01:14:36210 bookmarks::BookmarkNode node(kId, base::GUID::GenerateRandomV4(), kUrl);
Mikel Astiza08d9662021-07-28 17:10:34211 tracker->Add(&node, kSyncId, kServerVersion, kCreationTime, specifics);
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34212
213 sync_pb::BookmarkModelMetadata bookmark_model_metadata =
Mikel Astiz7eb326e2020-01-31 17:34:39214 tracker->BuildBookmarkModelMetadata();
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34215
216 ASSERT_THAT(bookmark_model_metadata.bookmarks_metadata().size(), Eq(1));
217 EXPECT_THAT(
218 bookmark_model_metadata.bookmarks_metadata(0).metadata().server_id(),
219 Eq(kSyncId));
Mikel Astize69b34a2020-07-20 10:34:37220 EXPECT_TRUE(bookmark_model_metadata.has_last_sync_time());
Mohamed Amir Yosefa0aa7ae82018-07-23 20:14:34221}
222
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46223TEST(SyncedBookmarkTrackerTest,
224 ShouldRequireCommitRequestWhenSequenceNumberIsIncremented) {
Mikel Astiz7eb326e2020-01-31 17:34:39225 std::unique_ptr<SyncedBookmarkTracker> tracker =
226 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
227
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46228 const std::string kSyncId = "SYNC_ID";
229 const int64_t kId = 1;
230 const int64_t kServerVersion = 1000;
231 const base::Time kModificationTime(base::Time::Now() -
232 base::TimeDelta::FromSeconds(1));
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46233 const sync_pb::EntitySpecifics specifics =
234 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Daniel Hosseinian26cb15fe2020-11-14 01:14:36235 bookmarks::BookmarkNode node(kId, base::GUID::GenerateRandomV4(), GURL());
Mikel Astiza08d9662021-07-28 17:10:34236 const SyncedBookmarkTracker::Entity* entity = tracker->Add(
237 &node, kSyncId, kServerVersion, kModificationTime, specifics);
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46238
Mikel Astiz7eb326e2020-01-31 17:34:39239 EXPECT_THAT(tracker->HasLocalChanges(), Eq(false));
Mikel Astizf12d87912020-03-10 14:40:06240 tracker->IncrementSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39241 EXPECT_THAT(tracker->HasLocalChanges(), Eq(true));
Mohamed Amir Yosef77ac6fbe2018-06-20 10:48:46242 // TODO(crbug.com/516866): Test HasLocalChanges after submitting commit
243 // request in a separate test probably.
244}
245
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48246TEST(SyncedBookmarkTrackerTest, ShouldAckSequenceNumber) {
Mikel Astiz7eb326e2020-01-31 17:34:39247 std::unique_ptr<SyncedBookmarkTracker> tracker =
248 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
249
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48250 const std::string kSyncId = "SYNC_ID";
251 const int64_t kId = 1;
252 const int64_t kServerVersion = 1000;
253 const base::Time kModificationTime(base::Time::Now() -
254 base::TimeDelta::FromSeconds(1));
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48255 const sync_pb::EntitySpecifics specifics =
256 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Daniel Hosseinian26cb15fe2020-11-14 01:14:36257 bookmarks::BookmarkNode node(kId, base::GUID::GenerateRandomV4(), GURL());
Mikel Astiza08d9662021-07-28 17:10:34258 const SyncedBookmarkTracker::Entity* entity = tracker->Add(
259 &node, kSyncId, kServerVersion, kModificationTime, specifics);
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48260
261 // Test simple scenario of ack'ing an incrememented sequence number.
Mikel Astiz7eb326e2020-01-31 17:34:39262 EXPECT_THAT(tracker->HasLocalChanges(), Eq(false));
Mikel Astizf12d87912020-03-10 14:40:06263 tracker->IncrementSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39264 EXPECT_THAT(tracker->HasLocalChanges(), Eq(true));
Mikel Astizf12d87912020-03-10 14:40:06265 tracker->AckSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39266 EXPECT_THAT(tracker->HasLocalChanges(), Eq(false));
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48267
Mikel Astiz7eb326e2020-01-31 17:34:39268 // Test ack'ing of a multiple times incremented sequence number.
Mikel Astizf12d87912020-03-10 14:40:06269 tracker->IncrementSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39270 EXPECT_THAT(tracker->HasLocalChanges(), Eq(true));
Mikel Astizf12d87912020-03-10 14:40:06271 tracker->IncrementSequenceNumber(entity);
272 tracker->IncrementSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39273 EXPECT_THAT(tracker->HasLocalChanges(), Eq(true));
Mikel Astizf12d87912020-03-10 14:40:06274 tracker->AckSequenceNumber(entity);
Mikel Astiz7eb326e2020-01-31 17:34:39275 EXPECT_THAT(tracker->HasLocalChanges(), Eq(false));
Mohamed Amir Yosef88d36bf2018-08-06 18:03:48276}
277
Mohamed Amir Yosefc7097a12018-07-02 18:24:16278TEST(SyncedBookmarkTrackerTest, ShouldUpdateUponCommitResponseWithNewId) {
Mikel Astiz7eb326e2020-01-31 17:34:39279 std::unique_ptr<SyncedBookmarkTracker> tracker =
280 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
281
Mohamed Amir Yosefc7097a12018-07-02 18:24:16282 const std::string kSyncId = "SYNC_ID";
283 const std::string kNewSyncId = "NEW_SYNC_ID";
284 const int64_t kId = 1;
285 const int64_t kServerVersion = 1000;
286 const int64_t kNewServerVersion = 1001;
287 const base::Time kModificationTime(base::Time::Now() -
288 base::TimeDelta::FromSeconds(1));
Mohamed Amir Yosefc7097a12018-07-02 18:24:16289 const sync_pb::EntitySpecifics specifics =
290 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Daniel Hosseinian26cb15fe2020-11-14 01:14:36291 bookmarks::BookmarkNode node(kId, base::GUID::GenerateRandomV4(), GURL());
Mikel Astiza08d9662021-07-28 17:10:34292 const SyncedBookmarkTracker::Entity* entity = tracker->Add(
293 &node, kSyncId, kServerVersion, kModificationTime, specifics);
Mohamed Amir Yosefc7097a12018-07-02 18:24:16294 ASSERT_THAT(entity, NotNull());
Mikel Astizf12d87912020-03-10 14:40:06295
296 // Initially only the old ID should be tracked.
297 ASSERT_THAT(tracker->GetEntityForSyncId(kSyncId), Eq(entity));
298 ASSERT_THAT(tracker->GetEntityForSyncId(kNewSyncId), IsNull());
299
300 // Receive a commit response with a changed id.
301 tracker->UpdateUponCommitResponse(entity, kNewSyncId, kNewServerVersion,
302 /*acked_sequence_number=*/1);
303
304 // Old id shouldn't be there, but the new one should.
305 EXPECT_THAT(tracker->GetEntityForSyncId(kSyncId), IsNull());
306 EXPECT_THAT(tracker->GetEntityForSyncId(kNewSyncId), Eq(entity));
307
Mohamed Amir Yosefc7097a12018-07-02 18:24:16308 EXPECT_THAT(entity->metadata()->server_id(), Eq(kNewSyncId));
309 EXPECT_THAT(entity->bookmark_node(), Eq(&node));
310 EXPECT_THAT(entity->metadata()->server_version(), Eq(kNewServerVersion));
311}
312
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45313TEST(SyncedBookmarkTrackerTest, ShouldUpdateId) {
Mikel Astiz7eb326e2020-01-31 17:34:39314 std::unique_ptr<SyncedBookmarkTracker> tracker =
315 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
316
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45317 const std::string kSyncId = "SYNC_ID";
318 const std::string kNewSyncId = "NEW_SYNC_ID";
319 const int64_t kServerVersion = 1000;
320 const base::Time kModificationTime(base::Time::Now() -
321 base::TimeDelta::FromSeconds(1));
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45322 const sync_pb::EntitySpecifics specifics =
323 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Daniel Hosseinian26cb15fe2020-11-14 01:14:36324 bookmarks::BookmarkNode node(/*id=*/1, base::GUID::GenerateRandomV4(),
325 GURL());
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45326 // Track a sync entity.
Mikel Astiza08d9662021-07-28 17:10:34327 const SyncedBookmarkTracker::Entity* entity = tracker->Add(
328 &node, kSyncId, kServerVersion, kModificationTime, specifics);
Mikel Astizf12d87912020-03-10 14:40:06329
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45330 ASSERT_THAT(entity, NotNull());
Mikel Astizf12d87912020-03-10 14:40:06331 // Update the sync id.
Rushan Suleymanov634fd052021-08-03 16:57:28332 tracker->UpdateSyncIdIfNeeded(entity, kNewSyncId);
Mikel Astizf12d87912020-03-10 14:40:06333
334 // Old id shouldn't be there, but the new one should.
335 EXPECT_THAT(tracker->GetEntityForSyncId(kSyncId), IsNull());
336 EXPECT_THAT(tracker->GetEntityForSyncId(kNewSyncId), Eq(entity));
337
Mohamed Amir Yosefbc7cbfb2018-10-16 10:39:45338 EXPECT_THAT(entity->metadata()->server_id(), Eq(kNewSyncId));
339 EXPECT_THAT(entity->bookmark_node(), Eq(&node));
340 EXPECT_THAT(entity->metadata()->server_version(), Eq(kServerVersion));
341}
342
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51343TEST(SyncedBookmarkTrackerTest,
344 ShouldMaintainTombstoneOrderBetweenCtorAndBuildBookmarkModelMetadata) {
345 // Feed a metadata batch of 5 entries to the constructor of the tracker.
346 // First 2 are for node, and the last 4 are for tombstones.
347
348 // Server ids.
349 const std::string kId0 = "id0";
350 const std::string kId1 = "id1";
351 const std::string kId2 = "id2";
352 const std::string kId3 = "id3";
353 const std::string kId4 = "id4";
354
Mikel Astiz7eb326e2020-01-31 17:34:39355 std::unique_ptr<bookmarks::BookmarkModel> bookmark_model =
356 bookmarks::TestBookmarkClient::CreateModel();
357 const bookmarks::BookmarkNode* bookmark_bar_node =
358 bookmark_model->bookmark_bar_node();
359 const bookmarks::BookmarkNode* node0 = bookmark_model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24360 /*parent=*/bookmark_bar_node, /*index=*/0, u"node0");
Mikel Astiz7eb326e2020-01-31 17:34:39361 const bookmarks::BookmarkNode* node1 = bookmark_model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24362 /*parent=*/bookmark_bar_node, /*index=*/0, u"node1");
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51363
Mikel Astiz7eb326e2020-01-31 17:34:39364 sync_pb::BookmarkModelMetadata initial_model_metadata =
365 CreateMetadataForPermanentNodes(bookmark_model.get());
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51366
Mikel Astiz7eb326e2020-01-31 17:34:39367 *initial_model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25368 CreateNodeMetadata(node0, /*server_id=*/kId0);
Mikel Astiz7eb326e2020-01-31 17:34:39369 *initial_model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25370 CreateNodeMetadata(node1, /*server_id=*/kId1);
371 *initial_model_metadata.add_bookmarks_metadata() = CreateTombstoneMetadata(
372 /*server_id=*/kId2, syncer::ClientTagHash::FromHashed("clienttaghash2"));
373 *initial_model_metadata.add_bookmarks_metadata() = CreateTombstoneMetadata(
374 /*server_id=*/kId3, syncer::ClientTagHash::FromHashed("clienttaghash3"));
375 *initial_model_metadata.add_bookmarks_metadata() = CreateTombstoneMetadata(
376 /*server_id=*/kId4, syncer::ClientTagHash::FromHashed("clienttaghash4"));
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51377
Mikel Astiz7eb326e2020-01-31 17:34:39378 std::unique_ptr<SyncedBookmarkTracker> tracker =
379 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
380 bookmark_model.get(), std::move(initial_model_metadata));
381 ASSERT_THAT(tracker, NotNull());
382
383 const sync_pb::BookmarkModelMetadata output_model_metadata =
384 tracker->BuildBookmarkModelMetadata();
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51385
386 // Tombstones should be the last 3 entries in the metadata and in the same
387 // order as given to the constructor.
Mikel Astiz7eb326e2020-01-31 17:34:39388 ASSERT_THAT(output_model_metadata.bookmarks_metadata().size(),
389 Eq(kNumPermanentNodes + 5));
390 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 2)
391 .metadata()
392 .server_id(),
393 Eq(kId2));
394 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 3)
395 .metadata()
396 .server_id(),
397 Eq(kId3));
398 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 4)
399 .metadata()
400 .server_id(),
401 Eq(kId4));
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51402}
403
404TEST(SyncedBookmarkTrackerTest,
405 ShouldMaintainOrderOfMarkDeletedCallsWhenBuildBookmarkModelMetadata) {
406 // Server ids.
407 const std::string kId0 = "id0";
408 const std::string kId1 = "id1";
409 const std::string kId2 = "id2";
410 const std::string kId3 = "id3";
411 const std::string kId4 = "id4";
412
Mikel Astiz7eb326e2020-01-31 17:34:39413 std::unique_ptr<bookmarks::BookmarkModel> bookmark_model =
414 bookmarks::TestBookmarkClient::CreateModel();
415 const bookmarks::BookmarkNode* bookmark_bar_node =
416 bookmark_model->bookmark_bar_node();
417 const bookmarks::BookmarkNode* node0 = bookmark_model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24418 /*parent=*/bookmark_bar_node, /*index=*/0, u"node0");
Mikel Astiz7eb326e2020-01-31 17:34:39419 const bookmarks::BookmarkNode* node1 = bookmark_model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24420 /*parent=*/bookmark_bar_node, /*index=*/0, u"node1");
Mikel Astiz7eb326e2020-01-31 17:34:39421 const bookmarks::BookmarkNode* node2 = bookmark_model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24422 /*parent=*/bookmark_bar_node, /*index=*/0, u"node2");
Mikel Astiz7eb326e2020-01-31 17:34:39423 const bookmarks::BookmarkNode* node3 = bookmark_model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24424 /*parent=*/bookmark_bar_node, /*index=*/0, u"node3");
Mikel Astiz7eb326e2020-01-31 17:34:39425 const bookmarks::BookmarkNode* node4 = bookmark_model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24426 /*parent=*/bookmark_bar_node, /*index=*/0, u"node4");
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51427
Mikel Astiz7eb326e2020-01-31 17:34:39428 sync_pb::BookmarkModelMetadata initial_model_metadata =
429 CreateMetadataForPermanentNodes(bookmark_model.get());
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51430
Mikel Astiz7eb326e2020-01-31 17:34:39431 *initial_model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25432 CreateNodeMetadata(node0, /*server_id=*/kId0);
Mikel Astiz7eb326e2020-01-31 17:34:39433 *initial_model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25434 CreateNodeMetadata(node1, /*server_id=*/kId1);
Mikel Astiz7eb326e2020-01-31 17:34:39435 *initial_model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25436 CreateNodeMetadata(node2, /*server_id=*/kId2);
Mikel Astiz7eb326e2020-01-31 17:34:39437 *initial_model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25438 CreateNodeMetadata(node3, /*server_id=*/kId3);
Mikel Astiz7eb326e2020-01-31 17:34:39439 *initial_model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25440 CreateNodeMetadata(node4, /*server_id=*/kId4);
Mikel Astiz7eb326e2020-01-31 17:34:39441
442 std::unique_ptr<SyncedBookmarkTracker> tracker =
443 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
444 bookmark_model.get(), std::move(initial_model_metadata));
445 ASSERT_THAT(tracker, NotNull());
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51446
447 // Mark entities deleted in that order kId2, kId4, kId1
Mikel Astizf12d87912020-03-10 14:40:06448 tracker->MarkDeleted(tracker->GetEntityForSyncId(kId2));
449 tracker->MarkDeleted(tracker->GetEntityForSyncId(kId4));
450 tracker->MarkDeleted(tracker->GetEntityForSyncId(kId1));
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51451
Mikel Astiz7eb326e2020-01-31 17:34:39452 const sync_pb::BookmarkModelMetadata output_model_metadata =
453 tracker->BuildBookmarkModelMetadata();
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51454
455 // Tombstones should be the last 3 entries in the metadata and in the same as
456 // calling MarkDeleted().
Mikel Astiz7eb326e2020-01-31 17:34:39457 ASSERT_THAT(output_model_metadata.bookmarks_metadata().size(),
458 Eq(kNumPermanentNodes + 5));
459 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 2)
460 .metadata()
461 .server_id(),
462 Eq(kId2));
463 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 3)
464 .metadata()
465 .server_id(),
466 Eq(kId4));
467 EXPECT_THAT(output_model_metadata.bookmarks_metadata(kNumPermanentNodes + 4)
468 .metadata()
469 .server_id(),
470 Eq(kId1));
Mohamed Amir Yosef3fd347d2018-07-18 13:37:51471}
472
Mikel Astiz219dce72021-02-16 12:47:32473TEST(SyncedBookmarkTrackerTest, ShouldMarkDeleted) {
Mikel Astiz83da4262020-06-24 12:59:58474 std::unique_ptr<SyncedBookmarkTracker> tracker =
475 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
476
477 const std::string kSyncId = "SYNC_ID";
478 const int64_t kId = 1;
Mikel Astiz219dce72021-02-16 12:47:32479 const base::GUID kGuid = base::GUID::GenerateRandomV4();
Mikel Astiz83da4262020-06-24 12:59:58480 const int64_t kServerVersion = 1000;
481 const base::Time kModificationTime(base::Time::Now() -
482 base::TimeDelta::FromSeconds(1));
Mikel Astiz83da4262020-06-24 12:59:58483 const sync_pb::EntitySpecifics specifics =
484 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
Mikel Astiz219dce72021-02-16 12:47:32485 bookmarks::BookmarkNode node(kId, kGuid, GURL());
Mikel Astiza08d9662021-07-28 17:10:34486 const SyncedBookmarkTracker::Entity* entity = tracker->Add(
487 &node, kSyncId, kServerVersion, kModificationTime, specifics);
Mikel Astiz83da4262020-06-24 12:59:58488
Victor Hugo Vianna Silva8bc33c162020-10-29 17:15:15489 ASSERT_THAT(tracker->TrackedUncommittedTombstonesCount(), Eq(0U));
Mikel Astiz219dce72021-02-16 12:47:32490 ASSERT_THAT(tracker->GetEntityForSyncId(kSyncId), Eq(entity));
491 ASSERT_THAT(tracker->GetEntityForBookmarkNode(&node), Eq(entity));
492 ASSERT_THAT(
493 tracker->GetEntityForClientTagHash(syncer::ClientTagHash::FromUnhashed(
494 syncer::BOOKMARKS, kGuid.AsLowercaseString())),
495 Eq(entity));
496 ASSERT_FALSE(entity->metadata()->is_deleted());
497 ASSERT_THAT(entity->bookmark_node(), Eq(&node));
Mikel Astiz83da4262020-06-24 12:59:58498
499 // Delete the bookmark, leading to a pending deletion (local tombstone).
Mikel Astiz219dce72021-02-16 12:47:32500 tracker->MarkDeleted(entity);
501
502 EXPECT_THAT(tracker->TrackedUncommittedTombstonesCount(), Eq(1U));
503 EXPECT_THAT(tracker->GetEntityForSyncId(kSyncId), Eq(entity));
504 EXPECT_THAT(tracker->GetEntityForBookmarkNode(&node), IsNull());
505 EXPECT_THAT(
506 tracker->GetEntityForClientTagHash(syncer::ClientTagHash::FromUnhashed(
507 syncer::BOOKMARKS, kGuid.AsLowercaseString())),
508 Eq(entity));
509 EXPECT_TRUE(entity->metadata()->is_deleted());
510 EXPECT_THAT(entity->bookmark_node(), IsNull());
511}
512
513TEST(SyncedBookmarkTrackerTest, ShouldUndeleteTombstone) {
514 std::unique_ptr<SyncedBookmarkTracker> tracker =
515 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
516
517 const std::string kSyncId = "SYNC_ID";
518 const int64_t kId = 1;
519 const base::GUID kGuid = base::GUID::GenerateRandomV4();
520 const int64_t kServerVersion = 1000;
521 const base::Time kModificationTime(base::Time::Now() -
522 base::TimeDelta::FromSeconds(1));
Mikel Astiz219dce72021-02-16 12:47:32523 const sync_pb::EntitySpecifics specifics =
524 GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string());
525 bookmarks::BookmarkNode node(kId, kGuid, GURL());
Mikel Astiza08d9662021-07-28 17:10:34526 const SyncedBookmarkTracker::Entity* entity = tracker->Add(
527 &node, kSyncId, kServerVersion, kModificationTime, specifics);
Mikel Astiz219dce72021-02-16 12:47:32528
529 ASSERT_THAT(tracker->TrackedUncommittedTombstonesCount(), Eq(0U));
530 ASSERT_THAT(tracker->GetEntityForSyncId(kSyncId), Eq(entity));
531
532 // Delete the bookmark, leading to a pending deletion (local tombstone).
533 tracker->MarkDeleted(entity);
Mikel Astiz83da4262020-06-24 12:59:58534 ASSERT_THAT(entity->bookmark_node(), IsNull());
535 ASSERT_TRUE(entity->metadata()->is_deleted());
Victor Hugo Vianna Silva8bc33c162020-10-29 17:15:15536 ASSERT_THAT(tracker->TrackedUncommittedTombstonesCount(), Eq(1U));
Mikel Astiz219dce72021-02-16 12:47:32537 ASSERT_THAT(tracker->GetEntityForBookmarkNode(&node), IsNull());
538 ASSERT_THAT(
539 tracker->GetEntityForClientTagHash(syncer::ClientTagHash::FromUnhashed(
540 syncer::BOOKMARKS, kGuid.AsLowercaseString())),
541 Eq(entity));
Mikel Astiz83da4262020-06-24 12:59:58542
543 // Undelete it.
544 tracker->UndeleteTombstoneForBookmarkNode(entity, &node);
545
546 EXPECT_THAT(entity->bookmark_node(), NotNull());
547 EXPECT_FALSE(entity->metadata()->is_deleted());
Victor Hugo Vianna Silva8bc33c162020-10-29 17:15:15548 EXPECT_THAT(tracker->TrackedUncommittedTombstonesCount(), Eq(0U));
Mikel Astiz219dce72021-02-16 12:47:32549 ASSERT_THAT(tracker->GetEntityForBookmarkNode(&node), Eq(entity));
550 EXPECT_THAT(
551 tracker->GetEntityForClientTagHash(syncer::ClientTagHash::FromUnhashed(
552 syncer::BOOKMARKS, kGuid.AsLowercaseString())),
553 Eq(entity));
Mikel Astiz83da4262020-06-24 12:59:58554}
555
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22556TEST(SyncedBookmarkTrackerTest,
557 ShouldOrderParentUpdatesBeforeChildUpdatesAndDeletionsComeLast) {
558 const size_t kMaxEntries = 1000;
559
560 // Construct this structure:
561 // bookmark_bar
562 // |- node0
563 // |- node1
564 // |- node2
565
566 std::unique_ptr<bookmarks::BookmarkModel> bookmark_model =
567 bookmarks::TestBookmarkClient::CreateModel();
568
569 const bookmarks::BookmarkNode* bookmark_bar_node =
570 bookmark_model->bookmark_bar_node();
571 const bookmarks::BookmarkNode* node0 = bookmark_model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24572 /*parent=*/bookmark_bar_node, /*index=*/0, u"node0");
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22573 const bookmarks::BookmarkNode* node1 = bookmark_model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24574 /*parent=*/node0, /*index=*/0, u"node1");
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22575 const bookmarks::BookmarkNode* node2 = bookmark_model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24576 /*parent=*/node1, /*index=*/0, u"node2");
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22577
578 // Server ids.
579 const std::string kId0 = "id0";
580 const std::string kId1 = "id1";
581 const std::string kId2 = "id2";
582 const std::string kId3 = "id3";
583
584 // Prepare the metadata with shuffled order.
Mikel Astiz7eb326e2020-01-31 17:34:39585 sync_pb::BookmarkModelMetadata model_metadata =
586 CreateMetadataForPermanentNodes(bookmark_model.get());
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22587
Mikel Astiz7eb326e2020-01-31 17:34:39588 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25589 CreateNodeMetadata(node1, /*server_id=*/kId1);
590 *model_metadata.add_bookmarks_metadata() = CreateTombstoneMetadata(
591 /*server_id=*/kId3, syncer::ClientTagHash::FromHashed("clienttaghash3"));
Mikel Astiz7eb326e2020-01-31 17:34:39592 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25593 CreateNodeMetadata(node2, /*server_id=*/kId2);
Mikel Astiz7eb326e2020-01-31 17:34:39594 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25595 CreateNodeMetadata(node0, /*server_id=*/kId0);
Mikel Astiz7eb326e2020-01-31 17:34:39596
597 std::unique_ptr<SyncedBookmarkTracker> tracker =
598 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
599 bookmark_model.get(), std::move(model_metadata));
600 ASSERT_THAT(tracker, NotNull());
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22601
602 // Mark the entities that they have local changes. (in shuffled order just to
603 // verify the tracker doesn't simply maintain the order of updates similar to
604 // with deletions).
Mikel Astizf12d87912020-03-10 14:40:06605 tracker->IncrementSequenceNumber(tracker->GetEntityForSyncId(kId3));
606 tracker->IncrementSequenceNumber(tracker->GetEntityForSyncId(kId1));
607 tracker->IncrementSequenceNumber(tracker->GetEntityForSyncId(kId2));
608 tracker->IncrementSequenceNumber(tracker->GetEntityForSyncId(kId0));
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22609
610 std::vector<const SyncedBookmarkTracker::Entity*> entities_with_local_change =
Mikel Astiz7eb326e2020-01-31 17:34:39611 tracker->GetEntitiesWithLocalChanges(kMaxEntries);
Mohamed Amir Yosef74ec6ceca2018-07-20 15:21:22612
613 ASSERT_THAT(entities_with_local_change.size(), Eq(4U));
614 // Verify updates are in parent before child order node0 --> node1 --> node2.
615 EXPECT_THAT(entities_with_local_change[0]->metadata()->server_id(), Eq(kId0));
616 EXPECT_THAT(entities_with_local_change[1]->metadata()->server_id(), Eq(kId1));
617 EXPECT_THAT(entities_with_local_change[2]->metadata()->server_id(), Eq(kId2));
618 // Verify that deletion is the last entry.
619 EXPECT_THAT(entities_with_local_change[3]->metadata()->server_id(), Eq(kId3));
620}
621
Mikel Astiz7a924872020-07-14 14:05:49622TEST(SyncedBookmarkTrackerTest, ShouldNotInvalidateMetadata) {
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17623 std::unique_ptr<bookmarks::BookmarkModel> model =
624 bookmarks::TestBookmarkClient::CreateModel();
625
626 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
627 const bookmarks::BookmarkNode* node = model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24628 /*parent=*/bookmark_bar_node, /*index=*/0, u"node0");
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17629
Mikel Astiz7eb326e2020-01-31 17:34:39630 sync_pb::BookmarkModelMetadata model_metadata =
631 CreateMetadataForPermanentNodes(model.get());
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17632
Mohamed Amir Yoseffb617fde2019-07-16 09:08:54633 // Add entry for the managed node.
Mikel Astiz7eb326e2020-01-31 17:34:39634 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25635 CreateNodeMetadata(node, /*server_id=*/"NodeId");
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17636
637 // Add a tombstone entry.
Mikel Astizfa6c7e62020-11-06 10:29:25638 *model_metadata.add_bookmarks_metadata() = CreateTombstoneMetadata(
639 /*server_id=*/"tombstoneId",
640 syncer::ClientTagHash::FromHashed("clienttaghash"));
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17641
Mohamed Amir Yosef05fa2162018-11-09 22:42:20642 base::HistogramTester histogram_tester;
Mikel Astiz7eb326e2020-01-31 17:34:39643
644 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
645 model.get(), std::move(model_metadata)),
646 NotNull());
647
Mohamed Amir Yosef05fa2162018-11-09 22:42:20648 histogram_tester.ExpectUniqueSample(
649 "Sync.BookmarksModelMetadataCorruptionReason",
George Burgess IVa6852eb2020-10-09 09:28:41650 /*sample=*/ExpectedCorruptionReason::NO_CORRUPTION, /*expected_count=*/1);
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17651}
652
Mikel Astiz925b3b5e2021-02-25 20:24:50653TEST(SyncedBookmarkTrackerTest, ShouldNotRequireClientTagsForPermanentNodes) {
654 std::unique_ptr<bookmarks::BookmarkModel> model =
655 bookmarks::TestBookmarkClient::CreateModel();
656
657 sync_pb::BookmarkModelMetadata model_metadata =
658 CreateMetadataForPermanentNodes(model.get());
659
660 // Clear the client tag hash field in metadata, which is irrelevant for
661 // permanent nodes (and some older versions of the browser didn't populate).
662 for (sync_pb::BookmarkMetadata& bookmark_metadata :
663 *model_metadata.mutable_bookmarks_metadata()) {
664 bookmark_metadata.mutable_metadata()->clear_client_tag_hash();
665 }
666
667 std::unique_ptr<SyncedBookmarkTracker> tracker =
668 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
669 model.get(), std::move(model_metadata));
670 ASSERT_THAT(tracker, NotNull());
671 EXPECT_THAT(tracker->GetEntityForSyncId(kBookmarkBarId), NotNull());
672 EXPECT_THAT(tracker->GetEntityForSyncId(kMobileBookmarksId), NotNull());
673 EXPECT_THAT(tracker->GetEntityForSyncId(kOtherBookmarksId), NotNull());
674}
675
Mikel Astiz7a924872020-07-14 14:05:49676TEST(SyncedBookmarkTrackerTest, ShouldInvalidateMetadataIfMissingMobileFolder) {
Mohamed Amir Yosefb1117f742018-11-12 13:29:01677 std::unique_ptr<bookmarks::BookmarkModel> model =
678 bookmarks::TestBookmarkClient::CreateModel();
679
680 sync_pb::BookmarkModelMetadata model_metadata;
681 model_metadata.mutable_model_type_state()->set_initial_sync_done(true);
Mikel Astiz7eb326e2020-01-31 17:34:39682
Mohamed Amir Yosefb1117f742018-11-12 13:29:01683 // Add entries for all the permanent nodes except for the Mobile bookmarks
Mikel Astiz113dc1e2018-12-18 16:58:47684 // folder.
Mikel Astiz7eb326e2020-01-31 17:34:39685 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25686 CreateNodeMetadata(model->bookmark_bar_node(),
Mikel Astiz7eb326e2020-01-31 17:34:39687 /*server_id=*/kBookmarkBarId);
688 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25689 CreateNodeMetadata(model->other_node(),
Mikel Astiz7eb326e2020-01-31 17:34:39690 /*server_id=*/kOtherBookmarksId);
Mohamed Amir Yosefb1117f742018-11-12 13:29:01691
692 base::HistogramTester histogram_tester;
Mikel Astiz7eb326e2020-01-31 17:34:39693
694 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
695 model.get(), std::move(model_metadata)),
696 IsNull());
697
Mohamed Amir Yosefb1117f742018-11-12 13:29:01698 histogram_tester.ExpectUniqueSample(
699 "Sync.BookmarksModelMetadataCorruptionReason",
Mikel Astiz7eb326e2020-01-31 17:34:39700 /*sample=*/ExpectedCorruptionReason::UNTRACKED_BOOKMARK, /*count=*/1);
Mohamed Amir Yosefb1117f742018-11-12 13:29:01701}
702
Mikel Astiz7a924872020-07-14 14:05:49703TEST(SyncedBookmarkTrackerTest, ShouldInvalidateMetadataIfMissingServerId) {
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17704 std::unique_ptr<bookmarks::BookmarkModel> model =
705 bookmarks::TestBookmarkClient::CreateModel();
706
Mikel Astiz7eb326e2020-01-31 17:34:39707 sync_pb::BookmarkModelMetadata model_metadata =
708 CreateMetadataForPermanentNodes(model.get());
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17709
Mikel Astiz7eb326e2020-01-31 17:34:39710 // Remove a server ID to a permanent node.
711 model_metadata.mutable_bookmarks_metadata(0)
712 ->mutable_metadata()
713 ->clear_server_id();
Mikel Astiz113dc1e2018-12-18 16:58:47714
Mohamed Amir Yosef05fa2162018-11-09 22:42:20715 base::HistogramTester histogram_tester;
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17716
Mikel Astiz7eb326e2020-01-31 17:34:39717 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
718 model.get(), std::move(model_metadata)),
719 IsNull());
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17720
Mikel Astiz7eb326e2020-01-31 17:34:39721 histogram_tester.ExpectUniqueSample(
Mohamed Amir Yosef05fa2162018-11-09 22:42:20722 "Sync.BookmarksModelMetadataCorruptionReason",
723 /*sample=*/ExpectedCorruptionReason::MISSING_SERVER_ID, /*count=*/1);
Mikel Astiz7eb326e2020-01-31 17:34:39724}
Mohamed Amir Yosef05fa2162018-11-09 22:42:20725
Mikel Astiz7eb326e2020-01-31 17:34:39726TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49727 ShouldInvalidateMetadataIfMissingLocalBookmarkId) {
Mikel Astiz7eb326e2020-01-31 17:34:39728 std::unique_ptr<bookmarks::BookmarkModel> model =
729 bookmarks::TestBookmarkClient::CreateModel();
730
731 sync_pb::BookmarkModelMetadata model_metadata =
732 CreateMetadataForPermanentNodes(model.get());
733
734 const bookmarks::BookmarkNode* node = model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24735 /*parent=*/model->bookmark_bar_node(), /*index=*/0, u"node");
Mikel Astiz7eb326e2020-01-31 17:34:39736 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25737 CreateNodeMetadata(node, /*server_id=*/"serverid");
Mikel Astiz7eb326e2020-01-31 17:34:39738
739 // Remove the local bookmark ID.
740 model_metadata.mutable_bookmarks_metadata()->rbegin()->clear_id();
741
742 base::HistogramTester histogram_tester;
743
744 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
745 model.get(), std::move(model_metadata)),
746 IsNull());
747
748 histogram_tester.ExpectUniqueSample(
Mohamed Amir Yosef05fa2162018-11-09 22:42:20749 "Sync.BookmarksModelMetadataCorruptionReason",
750 /*sample=*/ExpectedCorruptionReason::MISSING_BOOKMARK_ID, /*count=*/1);
Mikel Astiz7eb326e2020-01-31 17:34:39751}
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17752
Mikel Astiz7eb326e2020-01-31 17:34:39753TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49754 ShouldInvalidateMetadataIfTombstoneHasBookmarkId) {
Mikel Astiz7eb326e2020-01-31 17:34:39755 std::unique_ptr<bookmarks::BookmarkModel> model =
756 bookmarks::TestBookmarkClient::CreateModel();
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17757
Mikel Astiz7eb326e2020-01-31 17:34:39758 sync_pb::BookmarkModelMetadata model_metadata =
759 CreateMetadataForPermanentNodes(model.get());
760
Mikel Astizfa6c7e62020-11-06 10:29:25761 *model_metadata.add_bookmarks_metadata() = CreateTombstoneMetadata(
762 /*server_id=*/"serverid",
763 syncer::ClientTagHash::FromHashed("clienttaghash"));
Mikel Astiz7eb326e2020-01-31 17:34:39764
765 // Add a node ID to the tombstone.
766 model_metadata.mutable_bookmarks_metadata()->rbegin()->set_id(1234);
767
768 base::HistogramTester histogram_tester;
769
770 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
771 model.get(), std::move(model_metadata)),
772 IsNull());
773
774 histogram_tester.ExpectUniqueSample(
Mohamed Amir Yosef05fa2162018-11-09 22:42:20775 "Sync.BookmarksModelMetadataCorruptionReason",
776 /*sample=*/ExpectedCorruptionReason::BOOKMARK_ID_IN_TOMBSTONE,
777 /*count=*/1);
Mohamed Amir Yoseffb7986d882018-10-12 05:42:17778}
779
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03780TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49781 ShouldInvalidateMetadataIfUnknownLocalBookmarkId) {
Mikel Astiz7eb326e2020-01-31 17:34:39782 std::unique_ptr<bookmarks::BookmarkModel> model =
783 bookmarks::TestBookmarkClient::CreateModel();
784
785 sync_pb::BookmarkModelMetadata model_metadata =
786 CreateMetadataForPermanentNodes(model.get());
787
788 const bookmarks::BookmarkNode* node = model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24789 /*parent=*/model->bookmark_bar_node(), /*index=*/0, u"node");
Mikel Astiz7eb326e2020-01-31 17:34:39790 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25791 CreateNodeMetadata(node, /*server_id=*/"serverid");
Mikel Astiz7eb326e2020-01-31 17:34:39792
793 // Set an arbitrary local node ID that won't match anything in BookmarkModel.
794 model_metadata.mutable_bookmarks_metadata()->rbegin()->set_id(123456);
795
796 base::HistogramTester histogram_tester;
797
798 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
799 model.get(), std::move(model_metadata)),
800 IsNull());
801
802 histogram_tester.ExpectUniqueSample(
803 "Sync.BookmarksModelMetadataCorruptionReason",
804 /*sample=*/ExpectedCorruptionReason::UNKNOWN_BOOKMARK_ID,
805 /*count=*/1);
806}
807
Mikel Astiz7a924872020-07-14 14:05:49808TEST(SyncedBookmarkTrackerTest, ShouldInvalidateMetadataIfGuidMismatch) {
Mikel Astiz7eb326e2020-01-31 17:34:39809 std::unique_ptr<bookmarks::BookmarkModel> model =
810 bookmarks::TestBookmarkClient::CreateModel();
811
812 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
813 const bookmarks::BookmarkNode* node0 = model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24814 /*parent=*/bookmark_bar_node, /*index=*/0, u"node0");
Mikel Astiz7eb326e2020-01-31 17:34:39815
816 sync_pb::BookmarkModelMetadata model_metadata =
817 CreateMetadataForPermanentNodes(model.get());
818 sync_pb::BookmarkMetadata* node0_metadata =
819 model_metadata.add_bookmarks_metadata();
Mikel Astizfa6c7e62020-11-06 10:29:25820 *node0_metadata = CreateNodeMetadata(node0, /*server_id=*/"id0");
Mikel Astiz7eb326e2020-01-31 17:34:39821
822 // Set a mismatching client tag hash.
823 node0_metadata->mutable_metadata()->set_client_tag_hash("corrupthash");
824
825 base::HistogramTester histogram_tester;
826
827 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
828 model.get(), std::move(model_metadata)),
829 IsNull());
830
831 histogram_tester.ExpectUniqueSample(
832 "Sync.BookmarksModelMetadataCorruptionReason",
833 /*sample=*/ExpectedCorruptionReason::BOOKMARK_GUID_MISMATCH, /*count=*/1);
834}
835
836TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49837 ShouldInvalidateMetadataIfTombstoneHasDuplicatedClientTagHash) {
Rushan Suleymanov7bd510e2020-04-28 15:45:13838 std::unique_ptr<bookmarks::BookmarkModel> model =
839 bookmarks::TestBookmarkClient::CreateModel();
840
841 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
842 const bookmarks::BookmarkNode* node0 = model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24843 /*parent=*/bookmark_bar_node, /*index=*/0, u"node0");
Rushan Suleymanov7bd510e2020-04-28 15:45:13844
845 sync_pb::BookmarkModelMetadata model_metadata =
846 CreateMetadataForPermanentNodes(model.get());
847 sync_pb::BookmarkMetadata* node0_metadata =
848 model_metadata.add_bookmarks_metadata();
Mikel Astizfa6c7e62020-11-06 10:29:25849 *node0_metadata = CreateNodeMetadata(node0, /*server_id=*/"id0");
Rushan Suleymanov7bd510e2020-04-28 15:45:13850
851 const syncer::ClientTagHash client_tag_hash =
Daniel Hosseinian6de24fa2020-11-17 19:19:53852 syncer::ClientTagHash::FromUnhashed(syncer::BOOKMARKS,
853 node0->guid().AsLowercaseString());
Rushan Suleymanov7bd510e2020-04-28 15:45:13854 node0_metadata->mutable_metadata()->set_client_tag_hash(
855 client_tag_hash.value());
856
857 // Add the duplicate tombstone with a different server id but same client tag
858 // hash.
859 sync_pb::BookmarkMetadata* tombstone_metadata =
860 model_metadata.add_bookmarks_metadata();
Mikel Astizfa6c7e62020-11-06 10:29:25861 *tombstone_metadata = CreateTombstoneMetadata(
862 "id1", syncer::ClientTagHash::FromHashed("clienttaghash1"));
Rushan Suleymanov7bd510e2020-04-28 15:45:13863 tombstone_metadata->mutable_metadata()->set_client_tag_hash(
864 client_tag_hash.value());
865
866 base::HistogramTester histogram_tester;
867
868 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
869 model.get(), std::move(model_metadata)),
870 IsNull());
871
872 histogram_tester.ExpectUniqueSample(
873 "Sync.BookmarksModelMetadataCorruptionReason",
874 /*sample=*/ExpectedCorruptionReason::DUPLICATED_CLIENT_TAG_HASH,
875 /*count=*/1);
876}
877
878TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49879 ShouldInvalidateMetadataIfMissingClientTagHashWhileClientInSync) {
880 std::unique_ptr<bookmarks::BookmarkModel> model =
881 bookmarks::TestBookmarkClient::CreateModel();
882
883 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
884 const bookmarks::BookmarkNode* node0 = model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24885 /*parent=*/bookmark_bar_node, /*index=*/0, u"node0");
Mikel Astiz7a924872020-07-14 14:05:49886
887 sync_pb::BookmarkModelMetadata model_metadata =
888 CreateMetadataForPermanentNodes(model.get());
889 // Sync happened 23 hours ago, which is considered recent enough.
890 model_metadata.set_last_sync_time(syncer::TimeToProtoTime(
891 base::Time::Now() - base::TimeDelta::FromHours(23)));
892
893 sync_pb::BookmarkMetadata* node0_metadata =
894 model_metadata.add_bookmarks_metadata();
Mikel Astizfa6c7e62020-11-06 10:29:25895 *node0_metadata = CreateNodeMetadata(node0, /*server_id=*/"id0");
Mikel Astiz7a924872020-07-14 14:05:49896
897 node0_metadata->mutable_metadata()->clear_client_tag_hash();
898
899 base::HistogramTester histogram_tester;
900 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
901 model.get(), std::move(model_metadata)),
902 IsNull());
903
904 histogram_tester.ExpectUniqueSample(
905 "Sync.BookmarksModelMetadataCorruptionReason",
906 /*sample=*/ExpectedCorruptionReason::MISSING_CLIENT_TAG_HASH,
907 /*count=*/1);
908}
909
Mikel Astiz7a924872020-07-14 14:05:49910TEST(SyncedBookmarkTrackerTest,
911 ShouldInvalidateMetadataIfMissingClientTagHash) {
Mikel Astizb78eadcf2020-07-02 13:35:14912 std::unique_ptr<bookmarks::BookmarkModel> model =
913 bookmarks::TestBookmarkClient::CreateModel();
914
915 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
916 const bookmarks::BookmarkNode* node0 = model->AddFolder(
Jan Wilken Dörrie2c470ea2021-03-22 22:26:24917 /*parent=*/bookmark_bar_node, /*index=*/0, u"node0");
Mikel Astizb78eadcf2020-07-02 13:35:14918
919 sync_pb::BookmarkModelMetadata model_metadata =
920 CreateMetadataForPermanentNodes(model.get());
921 sync_pb::BookmarkMetadata* node0_metadata =
922 model_metadata.add_bookmarks_metadata();
Mikel Astizfa6c7e62020-11-06 10:29:25923 *node0_metadata = CreateNodeMetadata(node0, /*server_id=*/"id0");
Mikel Astizb78eadcf2020-07-02 13:35:14924
925 node0_metadata->mutable_metadata()->clear_client_tag_hash();
926
927 base::HistogramTester histogram_tester;
928 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
929 model.get(), std::move(model_metadata)),
930 IsNull());
931
932 histogram_tester.ExpectUniqueSample(
933 "Sync.BookmarksModelMetadataCorruptionReason",
934 /*sample=*/ExpectedCorruptionReason::MISSING_CLIENT_TAG_HASH,
935 /*count=*/1);
936}
937
938TEST(SyncedBookmarkTrackerTest,
Mikel Astiz7a924872020-07-14 14:05:49939 ShouldInvalidateMetadataIfUnsyncableNodeIsTracked) {
Rushan Suleymanov25241382020-06-10 11:53:53940 auto client = std::make_unique<bookmarks::TestBookmarkClient>();
941 bookmarks::BookmarkNode* managed_node = client->EnableManagedNode();
942
943 std::unique_ptr<bookmarks::BookmarkModel> model =
944 bookmarks::TestBookmarkClient::CreateModelWithClient(std::move(client));
945
946 // The model should contain the managed node now.
Mikel Astiz0bf1b2d12020-07-02 14:18:51947 ASSERT_THAT(GetBookmarkNodeByID(model.get(), managed_node->id()),
Rushan Suleymanov25241382020-06-10 11:53:53948 Eq(managed_node));
949
950 // Add entries for all the permanent nodes. TestBookmarkClient creates all the
951 // 3 permanent nodes.
952 sync_pb::BookmarkModelMetadata model_metadata =
953 CreateMetadataForPermanentNodes(model.get());
954
955 // Add unsyncable node to metadata.
956 *model_metadata.add_bookmarks_metadata() =
Mikel Astizfa6c7e62020-11-06 10:29:25957 CreateNodeMetadata(managed_node,
Rushan Suleymanov25241382020-06-10 11:53:53958 /*server_id=*/"server_id");
959
960 base::HistogramTester histogram_tester;
961 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
962 model.get(), std::move(model_metadata)),
963 IsNull());
964 histogram_tester.ExpectUniqueSample(
965 "Sync.BookmarksModelMetadataCorruptionReason",
966 /*sample=*/ExpectedCorruptionReason::TRACKED_MANAGED_NODE, /*count=*/1);
967}
968
969TEST(SyncedBookmarkTrackerTest,
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03970 ShouldMatchModelWithUnsyncableNodesAndMetadata) {
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03971 auto client = std::make_unique<bookmarks::TestBookmarkClient>();
Mikel Astizf50a3272020-03-12 08:07:00972 bookmarks::BookmarkNode* managed_node = client->EnableManagedNode();
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03973
974 std::unique_ptr<bookmarks::BookmarkModel> model =
975 bookmarks::TestBookmarkClient::CreateModelWithClient(std::move(client));
976
977 // The model should contain the managed node now.
Mikel Astiz0bf1b2d12020-07-02 14:18:51978 ASSERT_THAT(GetBookmarkNodeByID(model.get(), managed_node->id()),
Mohamed Amir Yoseffb617fde2019-07-16 09:08:54979 Eq(managed_node));
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03980
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03981 // Add entries for all the permanent nodes. TestBookmarkClient creates all the
982 // 3 permanent nodes.
Mikel Astiz7eb326e2020-01-31 17:34:39983 sync_pb::BookmarkModelMetadata model_metadata =
984 CreateMetadataForPermanentNodes(model.get());
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03985
Mohamed Amir Yosef05fa2162018-11-09 22:42:20986 base::HistogramTester histogram_tester;
Mikel Astiz7eb326e2020-01-31 17:34:39987 EXPECT_THAT(SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
988 model.get(), std::move(model_metadata)),
989 NotNull());
Mohamed Amir Yosef05fa2162018-11-09 22:42:20990 histogram_tester.ExpectUniqueSample(
991 "Sync.BookmarksModelMetadataCorruptionReason",
992 /*sample=*/ExpectedCorruptionReason::NO_CORRUPTION, /*count=*/1);
Mohamed Amir Yosefb6a54aa72018-11-09 13:34:03993}
994
Mikel Astiza8afa1b2020-04-09 15:47:15995TEST(SyncedBookmarkTrackerTest,
996 ShouldPopulateFaviconHashForNewlyAddedEntities) {
997 std::unique_ptr<SyncedBookmarkTracker> tracker =
998 SyncedBookmarkTracker::CreateEmpty(sync_pb::ModelTypeState());
999
1000 const std::string kSyncId = "SYNC_ID";
1001 const std::string kTitle = "Title";
1002 const GURL kUrl("http://www.foo.com");
1003 const int64_t kId = 1;
1004 const int64_t kServerVersion = 1000;
1005 const base::Time kCreationTime = base::Time::Now();
Mikel Astiza8afa1b2020-04-09 15:47:151006 const std::string kFaviconPngBytes = "fakefaviconbytes";
1007
1008 sync_pb::EntitySpecifics specifics = GenerateSpecifics(kTitle, kUrl.spec());
1009 specifics.mutable_bookmark()->set_favicon(kFaviconPngBytes);
1010
Daniel Hosseinian26cb15fe2020-11-14 01:14:361011 bookmarks::BookmarkNode node(kId, base::GUID::GenerateRandomV4(), kUrl);
Mikel Astiza8afa1b2020-04-09 15:47:151012 const SyncedBookmarkTracker::Entity* entity =
Mikel Astiza08d9662021-07-28 17:10:341013 tracker->Add(&node, kSyncId, kServerVersion, kCreationTime, specifics);
Mikel Astiza8afa1b2020-04-09 15:47:151014
1015 EXPECT_TRUE(entity->metadata()->has_bookmark_favicon_hash());
1016 EXPECT_TRUE(entity->MatchesFaviconHash(kFaviconPngBytes));
1017 EXPECT_FALSE(entity->MatchesFaviconHash("otherhash"));
1018}
1019
1020TEST(SyncedBookmarkTrackerTest, ShouldPopulateFaviconHashUponUpdate) {
1021 const std::string kSyncId = "SYNC_ID";
1022 const std::string kTitle = "Title";
1023 const GURL kUrl("http://www.foo.com");
1024 const int64_t kServerVersion = 1000;
1025 const base::Time kModificationTime = base::Time::Now();
Mikel Astiza8afa1b2020-04-09 15:47:151026 const std::string kFaviconPngBytes = "fakefaviconbytes";
1027
1028 std::unique_ptr<bookmarks::BookmarkModel> model =
1029 bookmarks::TestBookmarkClient::CreateModel();
1030
1031 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
1032 const bookmarks::BookmarkNode* node =
Jan Wilken Dörrie756999e2021-03-23 15:05:241033 model->AddURL(/*parent=*/bookmark_bar_node, /*index=*/0, u"Title",
1034 GURL("http://www.url.com"));
Mikel Astiza8afa1b2020-04-09 15:47:151035
1036 sync_pb::BookmarkModelMetadata model_metadata =
1037 CreateMetadataForPermanentNodes(model.get());
1038
1039 // Add entry for the URL node.
Mikel Astizfa6c7e62020-11-06 10:29:251040 *model_metadata.add_bookmarks_metadata() = CreateNodeMetadata(node, kSyncId);
Mikel Astiza8afa1b2020-04-09 15:47:151041
1042 std::unique_ptr<SyncedBookmarkTracker> tracker =
1043 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
1044 model.get(), std::move(model_metadata));
1045 ASSERT_THAT(tracker, NotNull());
1046
1047 const SyncedBookmarkTracker::Entity* entity =
1048 tracker->GetEntityForSyncId(kSyncId);
1049 ASSERT_THAT(entity, NotNull());
1050 ASSERT_FALSE(entity->metadata()->has_bookmark_favicon_hash());
1051 ASSERT_FALSE(entity->MatchesFaviconHash(kFaviconPngBytes));
1052
1053 sync_pb::EntitySpecifics specifics = GenerateSpecifics(kTitle, kUrl.spec());
1054 specifics.mutable_bookmark()->set_favicon(kFaviconPngBytes);
1055
Mikel Astiza08d9662021-07-28 17:10:341056 tracker->Update(entity, kServerVersion, kModificationTime, specifics);
Mikel Astiza8afa1b2020-04-09 15:47:151057
1058 EXPECT_TRUE(entity->metadata()->has_bookmark_favicon_hash());
1059 EXPECT_TRUE(entity->MatchesFaviconHash(kFaviconPngBytes));
1060 EXPECT_FALSE(entity->MatchesFaviconHash("otherhash"));
1061}
1062
1063TEST(SyncedBookmarkTrackerTest, ShouldPopulateFaviconHashExplicitly) {
1064 const std::string kSyncId = "SYNC_ID";
1065 const std::string kFaviconPngBytes = "fakefaviconbytes";
1066
1067 std::unique_ptr<bookmarks::BookmarkModel> model =
1068 bookmarks::TestBookmarkClient::CreateModel();
1069
1070 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
1071 const bookmarks::BookmarkNode* node =
Jan Wilken Dörrie756999e2021-03-23 15:05:241072 model->AddURL(/*parent=*/bookmark_bar_node, /*index=*/0, u"Title",
1073 GURL("http://www.url.com"));
Mikel Astiza8afa1b2020-04-09 15:47:151074
1075 sync_pb::BookmarkModelMetadata model_metadata =
1076 CreateMetadataForPermanentNodes(model.get());
1077
1078 // Add entry for the URL node.
Mikel Astizfa6c7e62020-11-06 10:29:251079 *model_metadata.add_bookmarks_metadata() = CreateNodeMetadata(node, kSyncId);
Mikel Astiza8afa1b2020-04-09 15:47:151080
1081 std::unique_ptr<SyncedBookmarkTracker> tracker =
1082 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
1083 model.get(), std::move(model_metadata));
1084 ASSERT_THAT(tracker, NotNull());
1085
1086 const SyncedBookmarkTracker::Entity* entity =
1087 tracker->GetEntityForSyncId(kSyncId);
1088 ASSERT_THAT(entity, NotNull());
1089 ASSERT_FALSE(entity->metadata()->has_bookmark_favicon_hash());
1090 ASSERT_FALSE(entity->MatchesFaviconHash(kFaviconPngBytes));
1091
1092 tracker->PopulateFaviconHashIfUnset(entity, kFaviconPngBytes);
1093 EXPECT_TRUE(entity->metadata()->has_bookmark_favicon_hash());
1094 EXPECT_TRUE(entity->MatchesFaviconHash(kFaviconPngBytes));
1095 EXPECT_FALSE(entity->MatchesFaviconHash("otherhash"));
1096
1097 // Further calls should be ignored.
1098 tracker->PopulateFaviconHashIfUnset(entity, "otherpngbytes");
1099 EXPECT_TRUE(entity->MatchesFaviconHash(kFaviconPngBytes));
1100}
1101
Rushan Suleymanovcacaf582020-06-26 19:31:321102TEST(SyncedBookmarkTrackerTest, ShouldNotReuploadEntitiesAfterMergeAndRestart) {
1103 base::test::ScopedFeatureList override_features;
1104 override_features.InitAndEnableFeature(
1105 switches::kSyncReuploadBookmarkFullTitles);
1106 const std::string kTitle = "Title";
1107 const GURL kUrl("http://www.foo.com");
1108
1109 sync_pb::ModelTypeState model_type_state;
1110 model_type_state.set_initial_sync_done(true);
1111 std::unique_ptr<SyncedBookmarkTracker> tracker =
1112 SyncedBookmarkTracker::CreateEmpty(model_type_state);
1113 tracker->SetBookmarksFullTitleReuploaded();
1114
1115 std::unique_ptr<bookmarks::BookmarkModel> model =
1116 bookmarks::TestBookmarkClient::CreateModel();
1117 const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
1118 const bookmarks::BookmarkNode* node =
1119 model->AddURL(/*parent=*/bookmark_bar_node, /*index=*/0,
1120 base::UTF8ToUTF16(kTitle), kUrl);
1121
1122 const sync_pb::EntitySpecifics specifics =
1123 GenerateSpecifics(kTitle, kUrl.spec());
1124 tracker->Add(node, /*sync_id=*/"id", /*server_version=*/0,
1125 /*creation_time=*/base::Time::Now(),
Rushan Suleymanovcacaf582020-06-26 19:31:321126 specifics);
1127
1128 sync_pb::EntitySpecifics permanent_specifics;
1129 permanent_specifics.mutable_bookmark();
1130
1131 // Add permanent nodes to tracker.
1132 tracker->Add(model->bookmark_bar_node(), kBookmarkBarId, /*server_version=*/0,
1133 /*creation_time=*/base::Time::Now(),
Rushan Suleymanovcacaf582020-06-26 19:31:321134 permanent_specifics);
1135 tracker->Add(model->other_node(), kOtherBookmarksId, /*server_version=*/0,
1136 /*creation_time=*/base::Time::Now(),
Rushan Suleymanovcacaf582020-06-26 19:31:321137 permanent_specifics);
1138 tracker->Add(model->mobile_node(), kMobileBookmarksId, /*server_version=*/0,
1139 /*creation_time=*/base::Time::Now(),
Rushan Suleymanovcacaf582020-06-26 19:31:321140 permanent_specifics);
1141
1142 ASSERT_FALSE(tracker->HasLocalChanges());
1143
1144 // Simulate browser restart.
1145 tracker = SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
1146 model.get(), tracker->BuildBookmarkModelMetadata());
1147 ASSERT_THAT(tracker, NotNull());
1148 EXPECT_FALSE(tracker->HasLocalChanges());
1149 EXPECT_EQ(4u, tracker->TrackedEntitiesCountForTest());
1150}
1151
1152TEST(SyncedBookmarkTrackerTest,
1153 ShouldResetReuploadFlagOnDisabledFeatureToggle) {
1154 base::test::ScopedFeatureList override_features;
1155 override_features.InitAndDisableFeature(
1156 switches::kSyncReuploadBookmarkFullTitles);
1157
1158 const std::string kTitle = "Title";
1159 const GURL kUrl("http://www.foo.com");
1160
1161 std::unique_ptr<bookmarks::BookmarkModel> bookmark_model =
1162 bookmarks::TestBookmarkClient::CreateModel();
1163
1164 sync_pb::ModelTypeState model_type_state;
1165 model_type_state.set_initial_sync_done(true);
1166 sync_pb::BookmarkModelMetadata initial_model_metadata =
1167 CreateMetadataForPermanentNodes(bookmark_model.get());
1168 initial_model_metadata.set_bookmarks_full_title_reuploaded(true);
1169 std::unique_ptr<SyncedBookmarkTracker> tracker =
1170 SyncedBookmarkTracker::CreateFromBookmarkModelAndMetadata(
1171 bookmark_model.get(), std::move(initial_model_metadata));
1172 ASSERT_THAT(tracker, NotNull());
1173
1174 EXPECT_FALSE(
1175 tracker->BuildBookmarkModelMetadata().bookmarks_full_title_reuploaded());
1176}
1177
Mohamed Amir Yosefb0664a82018-05-09 12:19:251178} // namespace
1179
1180} // namespace sync_bookmarks