blob: d717e2cf9f338e40458a7a3ec0b42c53c41334c9 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include "chrome/browser/power_bookmarks/power_bookmark_utils.h"
#include "chrome/browser/power_bookmarks/proto/power_bookmark_meta.pb.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/test/test_bookmark_client.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace power_bookmarks {
namespace {
const std::string kLeadImageUrl = "image.png";
const char16_t kExampleTitle[] = u"Title";
const std::string kExampleUrl = "https://example.com";
class PowerBookmarkUtilsTest : public testing::Test {
protected:
bookmarks::BookmarkModel* CreateTestModel() {
std::unique_ptr<bookmarks::BookmarkModel> model(
bookmarks::TestBookmarkClient::CreateModel());
const bookmarks::BookmarkNode* bookmark_bar = model->bookmark_bar_node();
model->AddURL(bookmark_bar, 0, kExampleTitle, GURL(kExampleUrl));
return model.release();
}
};
// Ensure the list |nodes| contains |node|.
bool ListContainsNode(const std::vector<const bookmarks::BookmarkNode*>& nodes,
const bookmarks::BookmarkNode* node) {
for (auto* cur_node : nodes) {
if (cur_node == node)
return true;
}
return false;
}
TEST_F(PowerBookmarkUtilsTest, TestAddAndAccess) {
bookmarks::BookmarkModel* model = CreateTestModel();
const bookmarks::BookmarkNode* node =
model->bookmark_bar_node()->children().front().get();
std::unique_ptr<PowerBookmarkMeta> meta =
std::make_unique<PowerBookmarkMeta>();
meta->mutable_lead_image()->set_url(kLeadImageUrl);
SetNodePowerBookmarkMeta(model, node, std::move(meta));
const std::unique_ptr<PowerBookmarkMeta> fetched_meta =
GetNodePowerBookmarkMeta(model, node);
EXPECT_EQ(kLeadImageUrl, fetched_meta->lead_image().url());
}
TEST_F(PowerBookmarkUtilsTest, TestAddAndDelete) {
bookmarks::BookmarkModel* model = CreateTestModel();
const bookmarks::BookmarkNode* node =
model->bookmark_bar_node()->children().front().get();
std::unique_ptr<PowerBookmarkMeta> meta =
std::make_unique<PowerBookmarkMeta>();
meta->mutable_lead_image()->set_url(kLeadImageUrl);
SetNodePowerBookmarkMeta(model, node, std::move(meta));
DeleteNodePowerBookmarkMeta(model, node);
const std::unique_ptr<PowerBookmarkMeta> fetched_meta =
GetNodePowerBookmarkMeta(model, node);
EXPECT_EQ(nullptr, fetched_meta.get());
}
TEST_F(PowerBookmarkUtilsTest, GetBookmarksMatchingPropertiesFilterTags) {
std::unique_ptr<bookmarks::BookmarkModel> model(
bookmarks::TestBookmarkClient::CreateModel());
const bookmarks::BookmarkNode* node1 = model->AddURL(
model->other_node(), 0, u"foo bar", GURL("http://www.google.com"));
std::unique_ptr<PowerBookmarkMeta> meta1 =
std::make_unique<PowerBookmarkMeta>();
meta1->add_tags()->set_display_name("search");
SetNodePowerBookmarkMeta(model.get(), node1, std::move(meta1));
const bookmarks::BookmarkNode* node2 = model->AddURL(
model->other_node(), 0, u"baz buz", GURL("http://www.cnn.com"));
std::unique_ptr<PowerBookmarkMeta> meta2 =
std::make_unique<PowerBookmarkMeta>();
meta2->add_tags()->set_display_name("news");
SetNodePowerBookmarkMeta(model.get(), node2, std::move(meta2));
std::vector<const bookmarks::BookmarkNode*> nodes;
PowerBookmarkQueryFields query;
query.word_phrase_query = std::make_unique<std::u16string>();
// Test that the correct bookmark is returned for the "search" tag.
query.tags.push_back(u"search");
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node1 == nodes[0]);
nodes.clear();
query.tags.clear();
// Test that the correct bookmark is returned for the "news" tag.
query.tags.push_back(u"news");
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node2 == nodes[0]);
nodes.clear();
query.tags.clear();
// Test that there are no results when valid but mutually exclusive tags are
// specified.
query.tags.push_back(u"news");
query.tags.push_back(u"search");
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(0U, nodes.size());
nodes.clear();
query.tags.clear();
// Test that no bookmarks are returned for unknown tag.
query.tags.push_back(u"foo");
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
EXPECT_TRUE(nodes.empty());
nodes.clear();
query.tags.clear();
// Test that no bookmarks are returned for a totally empty query.
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_TRUE(nodes.empty());
nodes.clear();
query.tags.clear();
// Test that a query plus tag returns the correct bookmark.
query.tags.push_back(u"news");
*query.word_phrase_query = u"baz";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node2 == nodes[0]);
nodes.clear();
query.tags.clear();
// Test that a mismatched query and tag returns nothing.
query.tags.push_back(u"search");
*query.word_phrase_query = u"baz";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
EXPECT_TRUE(nodes.empty());
nodes.clear();
query.tags.clear();
}
TEST_F(PowerBookmarkUtilsTest, GetBookmarksMatchingPropertiesSearchTags) {
std::unique_ptr<bookmarks::BookmarkModel> model(
bookmarks::TestBookmarkClient::CreateModel());
const bookmarks::BookmarkNode* node1 = model->AddURL(
model->other_node(), 0, u"foo bar", GURL("http://www.google.com"));
std::unique_ptr<PowerBookmarkMeta> meta1 =
std::make_unique<PowerBookmarkMeta>();
meta1->add_tags()->set_display_name("search");
SetNodePowerBookmarkMeta(model.get(), node1, std::move(meta1));
const bookmarks::BookmarkNode* node2 = model->AddURL(
model->other_node(), 0, u"baz buz", GURL("http://www.cnn.com"));
std::unique_ptr<PowerBookmarkMeta> meta2 =
std::make_unique<PowerBookmarkMeta>();
meta2->add_tags()->set_display_name("news");
SetNodePowerBookmarkMeta(model.get(), node2, std::move(meta2));
std::vector<const bookmarks::BookmarkNode*> nodes;
PowerBookmarkQueryFields query;
query.word_phrase_query = std::make_unique<std::u16string>();
// Test that a query for a substring in a tag and having a specified tag
// finds the correct node.
query.tags.push_back(u"news");
*query.word_phrase_query = u"ews";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node2 == nodes[0]);
nodes.clear();
query.tags.clear();
// Test that a query for a substring in a tag finds the correct node.
*query.word_phrase_query = u"ews";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node2 == nodes[0]);
nodes.clear();
query.tags.clear();
// Test that a query for the start of a tag finds the correct node.
*query.word_phrase_query = u"sea";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node1 == nodes[0]);
nodes.clear();
query.tags.clear();
}
TEST_F(PowerBookmarkUtilsTest,
GetBookmarksMatchingPropertiesSearchMultipleTags) {
std::unique_ptr<bookmarks::BookmarkModel> model(
bookmarks::TestBookmarkClient::CreateModel());
const bookmarks::BookmarkNode* node1 = model->AddURL(
model->other_node(), 0, u"foo bar", GURL("http://www.google.com"));
std::unique_ptr<PowerBookmarkMeta> meta1 =
std::make_unique<PowerBookmarkMeta>();
meta1->add_tags()->set_display_name("search");
meta1->add_tags()->set_display_name("news");
SetNodePowerBookmarkMeta(model.get(), node1, std::move(meta1));
const bookmarks::BookmarkNode* node2 = model->AddURL(
model->other_node(), 0, u"baz buz", GURL("http://www.cnn.com"));
std::unique_ptr<PowerBookmarkMeta> meta2 =
std::make_unique<PowerBookmarkMeta>();
meta2->add_tags()->set_display_name("news");
SetNodePowerBookmarkMeta(model.get(), node2, std::move(meta2));
std::vector<const bookmarks::BookmarkNode*> nodes;
PowerBookmarkQueryFields query;
query.word_phrase_query = std::make_unique<std::u16string>();
// Test that a query that contains multiple tags finds results that have all
// of those tags.
*query.word_phrase_query = u"news search";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node1 == nodes[0]);
nodes.clear();
query.tags.clear();
// Make sure searching for one tag finds both bookmarks.
*query.word_phrase_query = u"news";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(2U, nodes.size());
nodes.clear();
query.tags.clear();
}
TEST_F(PowerBookmarkUtilsTest, GetBookmarksMatchingPropertiesStringSearch) {
std::unique_ptr<bookmarks::BookmarkModel> model(
bookmarks::TestBookmarkClient::CreateModel());
const bookmarks::BookmarkNode* node1 = model->AddURL(
model->other_node(), 0, u"foo bar", GURL("http://www.google.com"));
const bookmarks::BookmarkNode* node2 = model->AddURL(
model->other_node(), 0, u"baz buz", GURL("http://www.cnn.com"));
std::vector<const bookmarks::BookmarkNode*> nodes;
PowerBookmarkQueryFields query;
query.word_phrase_query = std::make_unique<std::u16string>();
*query.word_phrase_query = u"bar";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node1 == nodes[0]);
nodes.clear();
*query.word_phrase_query = u"baz";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node2 == nodes[0]);
nodes.clear();
// A string search for "ba" should find both nodes.
*query.word_phrase_query = u"ba";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(2U, nodes.size());
nodes.clear();
// Ensure a search checks the URL.
*query.word_phrase_query = u"goog";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node1 == nodes[0]);
nodes.clear();
// Ensure a string that doesn't exist in the bookmarks returns nothing.
*query.word_phrase_query = u"zzz";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(0U, nodes.size());
nodes.clear();
// Check that two strings from different bookmarks returns nothing.
*query.word_phrase_query = u"foo buz";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(0U, nodes.size());
nodes.clear();
// Ensure an empty string returns no bookmarks.
*query.word_phrase_query = u"";
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(0U, nodes.size());
nodes.clear();
}
TEST_F(PowerBookmarkUtilsTest, GetBookmarksMatchingPropertiesFolderSearch) {
std::unique_ptr<bookmarks::BookmarkModel> model(
bookmarks::TestBookmarkClient::CreateModel());
model->AddURL(model->other_node(), 0, u"foo example",
GURL("http://www.google.com"));
model->AddURL(model->other_node(), 0, u"baz example",
GURL("http://www.cnn.com"));
const bookmarks::BookmarkNode* folder =
model->AddFolder(model->other_node(), 0, u"test folder");
const bookmarks::BookmarkNode* node =
model->AddURL(folder, 0, u"buz example", GURL("http://www.example.com"));
std::vector<const bookmarks::BookmarkNode*> nodes;
PowerBookmarkQueryFields query;
query.word_phrase_query = std::make_unique<std::u16string>();
*query.word_phrase_query = u"example";
query.folder = nullptr;
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(3U, nodes.size());
nodes.clear();
*query.word_phrase_query = u"example";
query.folder = folder;
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(node == nodes[0]);
nodes.clear();
}
TEST_F(PowerBookmarkUtilsTest, GetBookmarksMatchingPropertiesTypeSearch) {
std::unique_ptr<bookmarks::BookmarkModel> model(
bookmarks::TestBookmarkClient::CreateModel());
const bookmarks::BookmarkNode* node1 = model->AddURL(
model->other_node(), 0, u"foo bar", GURL("http://www.google.com"));
std::unique_ptr<PowerBookmarkMeta> meta1 =
std::make_unique<PowerBookmarkMeta>();
meta1->set_type(PowerBookmarkType::SHOPPING);
SetNodePowerBookmarkMeta(model.get(), node1, std::move(meta1));
const bookmarks::BookmarkNode* node2 = model->AddURL(
model->other_node(), 0, u"baz buz", GURL("http://www.cnn.com"));
std::unique_ptr<PowerBookmarkMeta> meta2 =
std::make_unique<PowerBookmarkMeta>();
meta2->set_type(PowerBookmarkType::SHOPPING);
SetNodePowerBookmarkMeta(model.get(), node2, std::move(meta2));
const bookmarks::BookmarkNode* node3 = model->AddURL(
model->other_node(), 0, u"chromium", GURL("http://www.chromium.org"));
std::unique_ptr<PowerBookmarkMeta> meta3 =
std::make_unique<PowerBookmarkMeta>();
meta3->set_type(PowerBookmarkType::UNSPECIFIED);
SetNodePowerBookmarkMeta(model.get(), node3, std::move(meta3));
const bookmarks::BookmarkNode* normal_node = model->AddURL(
model->other_node(), 0, u"example page", GURL("http://www.example.com"));
std::vector<const bookmarks::BookmarkNode*> nodes;
PowerBookmarkQueryFields query;
// Test that a query with no type returns all results.
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(4U, nodes.size());
nodes.clear();
// Test that a query for the SHOPPING type returns the correct results.
query.type = PowerBookmarkType::SHOPPING;
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(2U, nodes.size());
EXPECT_FALSE(ListContainsNode(nodes, normal_node));
EXPECT_FALSE(ListContainsNode(nodes, node3));
nodes.clear();
// Test that a query for the UNSPECIFIED type returns the correct results.
query.type = PowerBookmarkType::UNSPECIFIED;
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(3U, nodes.size());
EXPECT_FALSE(ListContainsNode(nodes, normal_node));
nodes.clear();
}
TEST_F(PowerBookmarkUtilsTest, EncodeAndDecodeForPersistence) {
PowerBookmarkMeta meta;
meta.set_type(PowerBookmarkType::SHOPPING);
meta.mutable_shopping_specifics()->set_title("Example Title");
std::string encoded_data;
EncodeMetaForStorage(meta, &encoded_data);
PowerBookmarkMeta out_meta;
EXPECT_TRUE(DecodeMetaFromStorage(encoded_data, &out_meta));
ASSERT_EQ(meta.type(), out_meta.type());
ASSERT_EQ(meta.shopping_specifics().title(),
out_meta.shopping_specifics().title());
}
} // namespace
} // namespace power_bookmarks