blob: 4e8272356f1941ca5167993c7526956f0463cac4 [file] [log] [blame]
// Copyright 2023 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/bookmark_model_view.h"
#include <memory>
#include <utility>
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "base/uuid.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_uuids.h"
#include "components/bookmarks/test/test_bookmark_client.h"
#include "components/sync/base/features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace sync_bookmarks {
namespace {
using testing::Eq;
using testing::IsNull;
using testing::NotNull;
class BookmarkModelViewTest : public testing::Test {
protected:
BookmarkModelViewTest() {
// Enable all possible permanent folders to verify how BookmarkModelView
// does the filtering.
auto client = std::make_unique<bookmarks::TestBookmarkClient>();
managed_node_ = client->EnableManagedNode();
model_ =
bookmarks::TestBookmarkClient::CreateModelWithClient(std::move(client));
model_->CreateAccountPermanentFolders();
EXPECT_THAT(model_->bookmark_bar_node(), NotNull());
EXPECT_THAT(model_->other_node(), NotNull());
EXPECT_THAT(model_->mobile_node(), NotNull());
EXPECT_THAT(model_->account_bookmark_bar_node(), NotNull());
EXPECT_THAT(model_->account_other_node(), NotNull());
EXPECT_THAT(model_->account_mobile_node(), NotNull());
EXPECT_THAT(managed_node_, NotNull());
EXPECT_NE(model_->bookmark_bar_node(), model_->account_bookmark_bar_node());
EXPECT_NE(model_->other_node(), model_->account_other_node());
EXPECT_NE(model_->mobile_node(), model_->account_mobile_node());
}
~BookmarkModelViewTest() override = default;
base::test::ScopedFeatureList features_{
syncer::kSyncEnableBookmarksInTransportMode};
std::unique_ptr<bookmarks::BookmarkModel> model_;
raw_ptr<bookmarks::BookmarkNode> managed_node_;
};
TEST_F(BookmarkModelViewTest, ShouldExposeLocalOrSyncablePermanentFolders) {
BookmarkModelViewUsingLocalOrSyncableNodes view(model_.get());
EXPECT_THAT(view.bookmark_bar_node(), Eq(model_->bookmark_bar_node()));
EXPECT_THAT(view.other_node(), Eq(model_->other_node()));
EXPECT_THAT(view.mobile_node(), Eq(model_->mobile_node()));
}
TEST_F(BookmarkModelViewTest, ShouldExposeAccountPermanentFolders) {
BookmarkModelViewUsingAccountNodes view(model_.get());
EXPECT_THAT(view.bookmark_bar_node(),
Eq(model_->account_bookmark_bar_node()));
EXPECT_THAT(view.other_node(), Eq(model_->account_other_node()));
EXPECT_THAT(view.mobile_node(), Eq(model_->account_mobile_node()));
}
TEST_F(BookmarkModelViewTest, ShouldIdentifySyncableNodes) {
// Create some nodes to exercise the predicate on non-permanent folders.
const bookmarks::BookmarkNode* folder1 = model_->AddFolder(
/*parent=*/model_->bookmark_bar_node(), /*index=*/0, u"Title 1");
const bookmarks::BookmarkNode* folder2 = model_->AddFolder(
/*parent=*/model_->account_bookmark_bar_node(), /*index=*/0, u"Title 2");
const bookmarks::BookmarkNode* nested_folder1 = model_->AddFolder(
/*parent=*/folder1, /*index=*/0, u"Title 3");
const bookmarks::BookmarkNode* nested_folder2 = model_->AddFolder(
/*parent=*/folder2, /*index=*/0, u"Title 4");
const bookmarks::BookmarkNode* managed_folder = model_->AddFolder(
/*parent=*/managed_node_, /*index=*/0, u"Managed Title");
BookmarkModelViewUsingLocalOrSyncableNodes view1(model_.get());
BookmarkModelViewUsingAccountNodes view2(model_.get());
// In `view1`, which uses local-or-syncable data, only the local-or-syncable
// permanent folders and their descendants should be considered syncable.
EXPECT_TRUE(view1.IsNodeSyncable(model_->bookmark_bar_node()));
EXPECT_TRUE(view1.IsNodeSyncable(model_->other_node()));
EXPECT_TRUE(view1.IsNodeSyncable(model_->mobile_node()));
EXPECT_TRUE(view1.IsNodeSyncable(folder1));
EXPECT_TRUE(view1.IsNodeSyncable(nested_folder1));
EXPECT_FALSE(view1.IsNodeSyncable(model_->account_bookmark_bar_node()));
EXPECT_FALSE(view1.IsNodeSyncable(model_->account_other_node()));
EXPECT_FALSE(view1.IsNodeSyncable(model_->account_mobile_node()));
EXPECT_FALSE(view1.IsNodeSyncable(folder2));
EXPECT_FALSE(view1.IsNodeSyncable(nested_folder2));
// In `view2`, which uses pure account data, only the corresponding
// permanent folders and their descendants should be considered syncable,
// which is the exact opposite.
EXPECT_FALSE(view2.IsNodeSyncable(model_->bookmark_bar_node()));
EXPECT_FALSE(view2.IsNodeSyncable(model_->other_node()));
EXPECT_FALSE(view2.IsNodeSyncable(model_->mobile_node()));
EXPECT_FALSE(view2.IsNodeSyncable(folder1));
EXPECT_FALSE(view2.IsNodeSyncable(nested_folder1));
EXPECT_TRUE(view2.IsNodeSyncable(model_->account_bookmark_bar_node()));
EXPECT_TRUE(view2.IsNodeSyncable(model_->account_other_node()));
EXPECT_TRUE(view2.IsNodeSyncable(model_->account_mobile_node()));
EXPECT_TRUE(view2.IsNodeSyncable(folder2));
EXPECT_TRUE(view2.IsNodeSyncable(nested_folder2));
// Managed nodes should be excluded in all cases.
EXPECT_FALSE(view1.IsNodeSyncable(managed_node_));
EXPECT_FALSE(view1.IsNodeSyncable(managed_folder));
EXPECT_FALSE(view2.IsNodeSyncable(managed_node_));
EXPECT_FALSE(view2.IsNodeSyncable(managed_folder));
}
TEST_F(BookmarkModelViewTest, ShouldGetNodeByUuid) {
const bookmarks::BookmarkNode* folder1 = model_->AddFolder(
/*parent=*/model_->bookmark_bar_node(), /*index=*/0, u"Title 1");
const bookmarks::BookmarkNode* folder2 = model_->AddFolder(
/*parent=*/model_->account_bookmark_bar_node(), /*index=*/0, u"Title 2");
ASSERT_NE(folder1->uuid(), folder2->uuid());
BookmarkModelViewUsingLocalOrSyncableNodes view1(model_.get());
BookmarkModelViewUsingAccountNodes view2(model_.get());
EXPECT_THAT(view1.GetNodeByUuid(
base::Uuid::ParseLowercase(bookmarks::kBookmarkBarNodeUuid)),
Eq(model_->bookmark_bar_node()));
EXPECT_THAT(view2.GetNodeByUuid(
base::Uuid::ParseLowercase(bookmarks::kBookmarkBarNodeUuid)),
Eq(model_->account_bookmark_bar_node()));
// `folder1` should only be exposed in `view1`.
EXPECT_THAT(view1.GetNodeByUuid(folder1->uuid()), Eq(folder1));
EXPECT_THAT(view2.GetNodeByUuid(folder1->uuid()), IsNull());
// `folder2` should only be exposed in `view2`.
EXPECT_THAT(view1.GetNodeByUuid(folder2->uuid()), IsNull());
EXPECT_THAT(view2.GetNodeByUuid(folder2->uuid()), Eq(folder2));
}
TEST_F(BookmarkModelViewTest, ShouldRemoveAllLocalOrSyncableNodes) {
// Add two local bookmarks.
model_->AddFolder(/*parent=*/model_->bookmark_bar_node(), /*index=*/0,
u"Title 1");
model_->AddFolder(/*parent=*/model_->bookmark_bar_node(), /*index=*/1,
u"Title 2");
// Add two account bookmarks.
model_->AddFolder(/*parent=*/model_->account_bookmark_bar_node(), /*index=*/0,
u"Title 3");
model_->AddFolder(/*parent=*/model_->account_bookmark_bar_node(), /*index=*/1,
u"Title 4");
ASSERT_THAT(model_->bookmark_bar_node()->children().size(), Eq(2));
ASSERT_THAT(model_->account_bookmark_bar_node()->children().size(), Eq(2));
BookmarkModelViewUsingLocalOrSyncableNodes view1(model_.get());
BookmarkModelViewUsingAccountNodes view2(model_.get());
view1.RemoveAllSyncableNodes();
// Only local-or-syncable nodes should have been removed.
EXPECT_THAT(model_->bookmark_bar_node()->children().size(), Eq(0));
ASSERT_THAT(model_->account_bookmark_bar_node(), NotNull());
EXPECT_THAT(model_->account_bookmark_bar_node()->children().size(), Eq(2));
}
TEST_F(BookmarkModelViewTest, ShouldRemoveAllAccountNodes) {
// Add two local bookmarks.
model_->AddFolder(/*parent=*/model_->bookmark_bar_node(), /*index=*/0,
u"Title 1");
model_->AddFolder(/*parent=*/model_->bookmark_bar_node(), /*index=*/1,
u"Title 2");
// Add two account bookmarks.
model_->AddFolder(/*parent=*/model_->account_bookmark_bar_node(), /*index=*/0,
u"Title 3");
model_->AddFolder(/*parent=*/model_->account_bookmark_bar_node(), /*index=*/1,
u"Title 4");
ASSERT_THAT(model_->bookmark_bar_node()->children().size(), Eq(2));
ASSERT_THAT(model_->account_bookmark_bar_node()->children().size(), Eq(2));
BookmarkModelViewUsingLocalOrSyncableNodes view1(model_.get());
BookmarkModelViewUsingAccountNodes view2(model_.get());
view2.RemoveAllSyncableNodes();
// Only account nodes should have been removed.
EXPECT_THAT(model_->bookmark_bar_node()->children().size(), Eq(2));
EXPECT_THAT(model_->account_bookmark_bar_node(), IsNull());
EXPECT_THAT(model_->account_mobile_node(), IsNull());
EXPECT_THAT(model_->account_other_node(), IsNull());
}
} // namespace
} // namespace sync_bookmarks