blob: 165a4abd2c6c1356d0e1161308ade3af771cf845 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/sync_bookmarks/initial_account_bookmark_deduplicator.h"
#include <memory>
#include <string>
#include <vector>
#include "base/uuid.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/test/test_bookmark_client.h"
#include "components/sync_bookmarks/test_node_builders.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace sync_bookmarks {
namespace {
using sync_bookmarks::test::FolderBuilder;
using sync_bookmarks::test::UrlBuilder;
using testing::ElementsAre;
using testing::IsEmpty;
using testing::SizeIs;
class InitialAccountBookmarkDeduplicatorTest : public testing::Test {
public:
InitialAccountBookmarkDeduplicatorTest() {
bookmark_model_ = bookmarks::TestBookmarkClient::CreateModel();
// Enable account storage, which is where the deduplicator will look for
// the canonical version of the data.
bookmark_model_->CreateAccountPermanentFolders();
bookmark_deduplicator_ =
std::make_unique<InitialAccountBookmarkDeduplicator>(
bookmark_model_.get());
}
protected:
void AddLocalNodes(
const std::vector<FolderBuilder::FolderOrUrl>& children_of_bookmark_bar) {
FolderBuilder::AddChildrenTo(bookmark_model_.get(),
bookmark_model_->bookmark_bar_node(),
children_of_bookmark_bar);
}
void AddAccountNodes(
const std::vector<FolderBuilder::FolderOrUrl>& children_of_bookmark_bar) {
FolderBuilder::AddChildrenTo(bookmark_model_.get(),
bookmark_model_->account_bookmark_bar_node(),
children_of_bookmark_bar);
}
std::unique_ptr<bookmarks::BookmarkModel> bookmark_model_;
std::unique_ptr<InitialAccountBookmarkDeduplicator> bookmark_deduplicator_;
};
TEST_F(InitialAccountBookmarkDeduplicatorTest, ShouldDoNothingIfNoDuplicates) {
AddLocalNodes({UrlBuilder(u"Local", GURL("http://local.com"))});
AddAccountNodes({UrlBuilder(u"Account", GURL("http://account.com"))});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// No changes should have been made.
EXPECT_THAT(local_bar->children(), SizeIs(1));
EXPECT_THAT(account_bar->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest, ShouldRemoveDuplicateUrl) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
const GURL url("http://example.com");
const std::u16string title = u"Title";
AddLocalNodes({UrlBuilder(title, url).SetUuid(uuid)});
AddAccountNodes({UrlBuilder(title, url).SetUuid(uuid)});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// The local bookmark should have been removed.
EXPECT_THAT(local_bar->children(), IsEmpty());
EXPECT_THAT(account_bar->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest, ShouldRemoveDuplicateFolder) {
const base::Uuid folder_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid child_uuid = base::Uuid::GenerateRandomV4();
const GURL child_url("http://child.com");
const std::u16string folder_title = u"Folder";
const std::u16string child_title = u"Child";
AddLocalNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren(
{UrlBuilder(child_title, child_url).SetUuid(child_uuid)})});
AddAccountNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren(
{UrlBuilder(child_title, child_url).SetUuid(child_uuid)})});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
ASSERT_THAT(local_bar->children()[0]->children(), SizeIs(1));
ASSERT_THAT(account_bar->children()[0]->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// The local folder and its contents should have been removed.
EXPECT_THAT(local_bar->children(), IsEmpty());
EXPECT_THAT(account_bar->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
ShouldRemoveLocalFolderIfItIsASubgraphOfAccountFolder) {
const base::Uuid folder_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid child_uuid = base::Uuid::GenerateRandomV4();
const GURL child_url("http://child.com");
const std::u16string folder_title = u"Folder";
const std::u16string child_title = u"Child";
AddLocalNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren(
{UrlBuilder(child_title, child_url).SetUuid(child_uuid)})});
AddAccountNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren({UrlBuilder(child_title, child_url).SetUuid(child_uuid),
UrlBuilder(u"Extra", GURL("http://extra.com"))})});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
ASSERT_THAT(local_bar->children()[0]->children(), SizeIs(1));
ASSERT_THAT(account_bar->children()[0]->children(), SizeIs(2));
bookmark_deduplicator_->Deduplicate();
// The local folder should have been removed because it's a duplicate.
EXPECT_THAT(local_bar->children(), IsEmpty());
EXPECT_THAT(account_bar->children(), SizeIs(1));
EXPECT_THAT(account_bar->children()[0]->children(), SizeIs(2));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
ShouldNotRemoveLocalFolderIfChildUrlDiffers) {
const base::Uuid folder_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid child_uuid = base::Uuid::GenerateRandomV4();
const std::u16string folder_title = u"Folder";
const std::u16string child_title = u"Child";
AddLocalNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren({UrlBuilder(child_title, GURL("http://local-child.com"))
.SetUuid(child_uuid)})});
AddAccountNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren(
{UrlBuilder(child_title, GURL("http://account-child.com"))
.SetUuid(child_uuid)})});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// The local folder should NOT have been removed.
EXPECT_THAT(local_bar->children(), SizeIs(1));
EXPECT_THAT(account_bar->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
ShouldHandleVariousDuplicationScenarios) {
const base::Uuid social_folder_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid twitter_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid linkedin_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid shopping_folder_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid amazon_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid ebay_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid news_folder_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid nyt_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid bbc_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid email_uuid = base::Uuid::GenerateRandomV4();
// 1. Account Bookmarks
// 🗂️ Bookmarks Bar (Account)
// ├── 📁 Social
// │ ├── 🔖 Twitter
// │ └── 🔖 LinkedIn
// ├── 📁 Shopping
// │ ├── 🔖 Amazon
// │ └── 🔖 eBay
// ├── 📁 News
// │ ├── 🔖 NYT
// │ └── 🔖 BBC
// └── 🔖 Email
AddAccountNodes(
{FolderBuilder(u"Social")
.SetUuid(social_folder_uuid)
.SetChildren({UrlBuilder(u"Twitter", GURL("http://twitter.com"))
.SetUuid(twitter_uuid),
UrlBuilder(u"LinkedIn", GURL("http://linkedin.com"))
.SetUuid(linkedin_uuid)}),
FolderBuilder(u"Shopping")
.SetUuid(shopping_folder_uuid)
.SetChildren({UrlBuilder(u"Amazon", GURL("http://amazon.com"))
.SetUuid(amazon_uuid),
UrlBuilder(u"eBay", GURL("http://ebay.com"))
.SetUuid(ebay_uuid)}),
FolderBuilder(u"News")
.SetUuid(news_folder_uuid)
.SetChildren(
{UrlBuilder(u"NYT", GURL("http://nyt.com")).SetUuid(nyt_uuid),
UrlBuilder(u"BBC", GURL("http://bbc.com")).SetUuid(bbc_uuid)}),
UrlBuilder(u"Email", GURL("http://email.com")).SetUuid(email_uuid)});
// 2. Local Bookmarks (BEFORE Deduplication)
// 🗂️ Bookmarks Bar (Local)
// ├── 📁 Social
// │ ├── 🔖 LinkedIn
// │ └── 🔖 Twitter
// ├── 📁 Shopping
// │ ├── 🔖 Amazon
// │ ├── 🔖 eBay
// │ └── 🔖 Etsy
// ├── 📁 News
// │ └── 🔖 NYT
// ├── 📁 Finance
// │ └── 🔖 Bank
// ├── 🔖 Email
// └── 🔖 Maps
AddLocalNodes(
{FolderBuilder(u"Social")
.SetUuid(social_folder_uuid)
.SetChildren({UrlBuilder(u"LinkedIn", GURL("http://linkedin.com"))
.SetUuid(linkedin_uuid),
UrlBuilder(u"Twitter", GURL("http://twitter.com"))
.SetUuid(twitter_uuid)}),
FolderBuilder(u"Shopping")
.SetUuid(shopping_folder_uuid)
.SetChildren(
{UrlBuilder(u"Amazon", GURL("http://amazon.com"))
.SetUuid(amazon_uuid),
UrlBuilder(u"eBay", GURL("http://ebay.com")).SetUuid(ebay_uuid),
UrlBuilder(u"Etsy", GURL("http://etsy.com"))}),
FolderBuilder(u"News")
.SetUuid(news_folder_uuid)
.SetChildren(
{UrlBuilder(u"NYT", GURL("http://nyt.com")).SetUuid(nyt_uuid)}),
FolderBuilder(u"Finance")
.SetChildren({UrlBuilder(u"Bank", GURL("http://bank.com"))}),
UrlBuilder(u"Email", GURL("http://email.com")).SetUuid(email_uuid),
UrlBuilder(u"Maps", GURL("http://maps.com"))});
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
ASSERT_THAT(account_bar->children(), SizeIs(4));
ASSERT_THAT(local_bar->children(), SizeIs(6));
bookmark_deduplicator_->Deduplicate();
// Social folder (local) is identical to account -> removed.
// News folder (local) is a subset of account -> removed.
// Email bookmark (local) is identical to account -> removed.
// Shopping folder (local) is a superset of account -> kept.
// Finance folder (local) is unique -> kept.
// Maps bookmark (local) is unique -> kept.
//
// 3. Local Bookmarks (AFTER Deduplication)
// 🗂️ Bookmarks Bar (Local)
// ├── 📁 Shopping
// │ ├── 🔖 Amazon
// │ ├── 🔖 eBay
// │ └── 🔖 Etsy
// ├── 📁 Finance
// │ └── 🔖 Bank
// └── 🔖 Maps
EXPECT_THAT(local_bar->children(), SizeIs(3));
EXPECT_EQ(u"Shopping", local_bar->children()[0]->GetTitle());
EXPECT_EQ(u"Finance", local_bar->children()[1]->GetTitle());
EXPECT_EQ(u"Maps", local_bar->children()[2]->GetTitle());
// Children of the kept local folders should be untouched.
EXPECT_THAT(local_bar->children()[0]->children(), SizeIs(3));
EXPECT_THAT(local_bar->children()[1]->children(), SizeIs(1));
// Account bookmarks should be untouched.
EXPECT_THAT(account_bar->children(), SizeIs(4));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
ShouldNotRemoveIfUuidMatchesButTypeIsDifferentUrlVsFolder) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
const std::u16string title = u"Title";
AddLocalNodes({UrlBuilder(title, GURL("http://example.com")).SetUuid(uuid)});
AddAccountNodes({FolderBuilder(title).SetUuid(uuid)});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// No changes should have been made.
EXPECT_THAT(local_bar->children(), SizeIs(1));
EXPECT_THAT(account_bar->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
ShouldNotRemoveIfUuidMatchesButTypeIsDifferentFolderVsUrl) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
const std::u16string title = u"Title";
AddLocalNodes({FolderBuilder(title).SetUuid(uuid)});
AddAccountNodes(
{UrlBuilder(title, GURL("http://example.com")).SetUuid(uuid)});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// No changes should have been made.
EXPECT_THAT(local_bar->children(), SizeIs(1));
EXPECT_THAT(account_bar->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
ShouldNotRemoveIfUrlUuidMatchesButUrlIsDifferent) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
const std::u16string title = u"Title";
AddLocalNodes({UrlBuilder(title, GURL("http://local.com")).SetUuid(uuid)});
AddAccountNodes(
{UrlBuilder(title, GURL("http://account.com")).SetUuid(uuid)});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// No changes should have been made.
EXPECT_THAT(local_bar->children(), SizeIs(1));
EXPECT_THAT(account_bar->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
ShouldNotRemoveIfFolderUuidMatchesButTitleIsDifferent) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
AddLocalNodes({FolderBuilder(u"Local Title").SetUuid(uuid)});
AddAccountNodes({FolderBuilder(u"Account Title").SetUuid(uuid)});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// No changes should have been made.
EXPECT_THAT(local_bar->children(), SizeIs(1));
EXPECT_THAT(account_bar->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
ShouldRemoveDuplicateEmptyFolder) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
const std::u16string title = u"Empty Folder";
AddLocalNodes({FolderBuilder(title).SetUuid(uuid)});
AddAccountNodes({FolderBuilder(title).SetUuid(uuid)});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// The local folder should have been removed.
EXPECT_THAT(local_bar->children(), IsEmpty());
EXPECT_THAT(account_bar->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
ShouldRemoveDuplicatesUnderOtherAndMobileNodes) {
const base::Uuid other_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid mobile_uuid = base::Uuid::GenerateRandomV4();
const GURL url("http://example.com");
const std::u16string title = u"Title";
FolderBuilder::AddChildrenTo(bookmark_model_.get(),
bookmark_model_->other_node(),
{UrlBuilder(title, url).SetUuid(other_uuid)});
FolderBuilder::AddChildrenTo(bookmark_model_.get(),
bookmark_model_->account_other_node(),
{UrlBuilder(title, url).SetUuid(other_uuid)});
FolderBuilder::AddChildrenTo(bookmark_model_.get(),
bookmark_model_->mobile_node(),
{UrlBuilder(title, url).SetUuid(mobile_uuid)});
FolderBuilder::AddChildrenTo(bookmark_model_.get(),
bookmark_model_->account_mobile_node(),
{UrlBuilder(title, url).SetUuid(mobile_uuid)});
ASSERT_THAT(bookmark_model_->other_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_other_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->mobile_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_mobile_node()->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// The local bookmarks should have been removed.
EXPECT_THAT(bookmark_model_->other_node()->children(), IsEmpty());
EXPECT_THAT(bookmark_model_->mobile_node()->children(), IsEmpty());
EXPECT_THAT(bookmark_model_->account_other_node()->children(), SizeIs(1));
EXPECT_THAT(bookmark_model_->account_mobile_node()->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
ShouldNotRemoveIfAccountNodeHasDifferentParent) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
const GURL url("http://example.com");
const std::u16string title = u"Title";
AddLocalNodes({UrlBuilder(title, url).SetUuid(uuid)});
// Add the "duplicate" to a different folder in the account model.
const bookmarks::BookmarkNode* account_folder = bookmark_model_->AddFolder(
bookmark_model_->account_bookmark_bar_node(), 0, u"Some Folder");
FolderBuilder::AddChildrenTo(bookmark_model_.get(), account_folder,
{UrlBuilder(title, url).SetUuid(uuid)});
const bookmarks::BookmarkNode* local_bar =
bookmark_model_->bookmark_bar_node();
const bookmarks::BookmarkNode* account_bar =
bookmark_model_->account_bookmark_bar_node();
ASSERT_THAT(local_bar->children(), SizeIs(1));
ASSERT_THAT(account_bar->children(), SizeIs(1));
bookmark_deduplicator_->Deduplicate();
// No changes should have been made because the parent doesn't match.
EXPECT_THAT(local_bar->children(), SizeIs(1));
EXPECT_THAT(account_bar->children(), SizeIs(1));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
DoesAccountSubgraphContainLocalSubgraphWithIdenticalUrls) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
const GURL url("http://example.com");
const std::u16string title = u"Title";
AddLocalNodes({UrlBuilder(title, url).SetUuid(uuid)});
AddAccountNodes({UrlBuilder(title, url).SetUuid(uuid)});
ASSERT_THAT(bookmark_model_->bookmark_bar_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_bookmark_bar_node()->children(),
SizeIs(1));
const bookmarks::BookmarkNode* local_node =
bookmark_model_->bookmark_bar_node()->children()[0].get();
const bookmarks::BookmarkNode* account_node =
bookmark_model_->account_bookmark_bar_node()->children()[0].get();
EXPECT_TRUE(
bookmark_deduplicator_->DoesAccountSubgraphContainLocalSubgraphForTest(
local_node, account_node));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
DoesAccountSubgraphContainLocalSubgraphWithDifferentUrls) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
const std::u16string title = u"Title";
AddLocalNodes({UrlBuilder(title, GURL("http://local.com")).SetUuid(uuid)});
AddAccountNodes(
{UrlBuilder(title, GURL("http://account.com")).SetUuid(uuid)});
ASSERT_THAT(bookmark_model_->bookmark_bar_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_bookmark_bar_node()->children(),
SizeIs(1));
const bookmarks::BookmarkNode* local_node =
bookmark_model_->bookmark_bar_node()->children()[0].get();
const bookmarks::BookmarkNode* account_node =
bookmark_model_->account_bookmark_bar_node()->children()[0].get();
EXPECT_FALSE(
bookmark_deduplicator_->DoesAccountSubgraphContainLocalSubgraphForTest(
local_node, account_node));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
DoesAccountSubgraphContainLocalSubgraphWithDifferentTypes) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
const std::u16string title = u"Title";
AddLocalNodes({UrlBuilder(title, GURL("http://example.com")).SetUuid(uuid)});
AddAccountNodes({FolderBuilder(title).SetUuid(uuid)});
ASSERT_THAT(bookmark_model_->bookmark_bar_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_bookmark_bar_node()->children(),
SizeIs(1));
const bookmarks::BookmarkNode* local_node =
bookmark_model_->bookmark_bar_node()->children()[0].get();
const bookmarks::BookmarkNode* account_node =
bookmark_model_->account_bookmark_bar_node()->children()[0].get();
EXPECT_FALSE(
bookmark_deduplicator_->DoesAccountSubgraphContainLocalSubgraphForTest(
local_node, account_node));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
DoesAccountSubgraphContainLocalSubgraphWithIdenticalFolders) {
const base::Uuid folder_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid child_uuid = base::Uuid::GenerateRandomV4();
const GURL child_url("http://child.com");
const std::u16string folder_title = u"Folder";
const std::u16string child_title = u"Child";
AddLocalNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren(
{UrlBuilder(child_title, child_url).SetUuid(child_uuid)})});
AddAccountNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren(
{UrlBuilder(child_title, child_url).SetUuid(child_uuid)})});
ASSERT_THAT(bookmark_model_->bookmark_bar_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_bookmark_bar_node()->children(),
SizeIs(1));
const bookmarks::BookmarkNode* local_node =
bookmark_model_->bookmark_bar_node()->children()[0].get();
const bookmarks::BookmarkNode* account_node =
bookmark_model_->account_bookmark_bar_node()->children()[0].get();
EXPECT_TRUE(
bookmark_deduplicator_->DoesAccountSubgraphContainLocalSubgraphForTest(
local_node, account_node));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
DoesAccountSubgraphContainLocalSubgraphWithIdenticalEmptyFolders) {
const base::Uuid folder_uuid = base::Uuid::GenerateRandomV4();
const std::u16string folder_title = u"Folder";
AddLocalNodes({FolderBuilder(folder_title).SetUuid(folder_uuid)});
AddAccountNodes({FolderBuilder(folder_title).SetUuid(folder_uuid)});
ASSERT_THAT(bookmark_model_->bookmark_bar_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_bookmark_bar_node()->children(),
SizeIs(1));
const bookmarks::BookmarkNode* local_node =
bookmark_model_->bookmark_bar_node()->children()[0].get();
const bookmarks::BookmarkNode* account_node =
bookmark_model_->account_bookmark_bar_node()->children()[0].get();
EXPECT_TRUE(
bookmark_deduplicator_->DoesAccountSubgraphContainLocalSubgraphForTest(
local_node, account_node));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
DoesAccountSubgraphContainLocalSubgraphWhenLocalIsSubgraph) {
const base::Uuid folder_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid child_uuid = base::Uuid::GenerateRandomV4();
const GURL child_url("http://child.com");
const std::u16string folder_title = u"Folder";
const std::u16string child_title = u"Child";
AddLocalNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren(
{UrlBuilder(child_title, child_url).SetUuid(child_uuid)})});
AddAccountNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren({UrlBuilder(child_title, child_url).SetUuid(child_uuid),
UrlBuilder(u"Extra", GURL("http://extra.com"))})});
ASSERT_THAT(bookmark_model_->bookmark_bar_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_bookmark_bar_node()->children(),
SizeIs(1));
const bookmarks::BookmarkNode* local_node =
bookmark_model_->bookmark_bar_node()->children()[0].get();
const bookmarks::BookmarkNode* account_node =
bookmark_model_->account_bookmark_bar_node()->children()[0].get();
EXPECT_TRUE(
bookmark_deduplicator_->DoesAccountSubgraphContainLocalSubgraphForTest(
local_node, account_node));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
DoesAccountSubgraphContainLocalSubgraphWhenAccountIsSubgraph) {
const base::Uuid folder_uuid = base::Uuid::GenerateRandomV4();
const base::Uuid child_uuid = base::Uuid::GenerateRandomV4();
const GURL child_url("http://child.com");
const std::u16string folder_title = u"Folder";
const std::u16string child_title = u"Child";
AddLocalNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren({UrlBuilder(child_title, child_url).SetUuid(child_uuid),
UrlBuilder(u"Extra", GURL("http://extra.com"))})});
AddAccountNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren(
{UrlBuilder(child_title, child_url).SetUuid(child_uuid)})});
ASSERT_THAT(bookmark_model_->bookmark_bar_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_bookmark_bar_node()->children(),
SizeIs(1));
const bookmarks::BookmarkNode* local_node =
bookmark_model_->bookmark_bar_node()->children()[0].get();
const bookmarks::BookmarkNode* account_node =
bookmark_model_->account_bookmark_bar_node()->children()[0].get();
EXPECT_FALSE(
bookmark_deduplicator_->DoesAccountSubgraphContainLocalSubgraphForTest(
local_node, account_node));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
DoesAccountSubgraphContainLocalSubgraphWithDifferentFolderTitles) {
const base::Uuid uuid = base::Uuid::GenerateRandomV4();
AddLocalNodes({FolderBuilder(u"Local Title").SetUuid(uuid)});
AddAccountNodes({FolderBuilder(u"Account Title").SetUuid(uuid)});
ASSERT_THAT(bookmark_model_->bookmark_bar_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_bookmark_bar_node()->children(),
SizeIs(1));
const bookmarks::BookmarkNode* local_node =
bookmark_model_->bookmark_bar_node()->children()[0].get();
const bookmarks::BookmarkNode* account_node =
bookmark_model_->account_bookmark_bar_node()->children()[0].get();
EXPECT_FALSE(
bookmark_deduplicator_->DoesAccountSubgraphContainLocalSubgraphForTest(
local_node, account_node));
}
TEST_F(InitialAccountBookmarkDeduplicatorTest,
DoesAccountSubgraphContainLocalSubgraphWithDifferentChildUuid) {
const base::Uuid folder_uuid = base::Uuid::GenerateRandomV4();
const GURL child_url("http://child.com");
const std::u16string folder_title = u"Folder";
const std::u16string child_title = u"Child";
AddLocalNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren({UrlBuilder(child_title, child_url)
.SetUuid(base::Uuid::GenerateRandomV4())})});
AddAccountNodes(
{FolderBuilder(folder_title)
.SetUuid(folder_uuid)
.SetChildren({UrlBuilder(child_title, child_url)
.SetUuid(base::Uuid::GenerateRandomV4())})});
ASSERT_THAT(bookmark_model_->bookmark_bar_node()->children(), SizeIs(1));
ASSERT_THAT(bookmark_model_->account_bookmark_bar_node()->children(),
SizeIs(1));
const bookmarks::BookmarkNode* local_node =
bookmark_model_->bookmark_bar_node()->children()[0].get();
const bookmarks::BookmarkNode* account_node =
bookmark_model_->account_bookmark_bar_node()->children()[0].get();
EXPECT_FALSE(
bookmark_deduplicator_->DoesAccountSubgraphContainLocalSubgraphForTest(
local_node, account_node));
}
} // namespace
} // namespace sync_bookmarks