Home | History | Annotate | Download | only in bookmarks
      1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/strings/string_number_conversions.h"
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "base/values.h"
     11 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
     12 #include "chrome/browser/bookmarks/chrome_bookmark_client.h"
     13 #include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h"
     14 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h"
     15 #include "chrome/common/extensions/api/bookmarks.h"
     16 #include "chrome/test/base/testing_profile.h"
     17 #include "components/bookmarks/browser/bookmark_model.h"
     18 #include "components/bookmarks/test/bookmark_test_helpers.h"
     19 #include "content/public/test/test_browser_thread_bundle.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 
     22 namespace extensions {
     23 
     24 namespace keys = bookmark_api_constants;
     25 using api::bookmarks::BookmarkTreeNode;
     26 
     27 namespace bookmark_api_helpers {
     28 
     29 class ExtensionBookmarksTest : public testing::Test {
     30  public:
     31   ExtensionBookmarksTest()
     32       : client_(NULL), model_(NULL), node_(NULL), node2_(NULL), folder_(NULL) {}
     33 
     34   virtual void SetUp() OVERRIDE {
     35     profile_.CreateBookmarkModel(false);
     36     model_ = BookmarkModelFactory::GetForProfile(&profile_);
     37     client_ = ChromeBookmarkClientFactory::GetForProfile(&profile_);
     38     test::WaitForBookmarkModelToLoad(model_);
     39 
     40     node_ = model_->AddURL(model_->other_node(), 0, base::ASCIIToUTF16("Digg"),
     41                            GURL("http://www.reddit.com"));
     42     model_->SetNodeMetaInfo(node_, "some_key1", "some_value1");
     43     model_->SetNodeMetaInfo(node_, "some_key2", "some_value2");
     44     model_->AddURL(model_->other_node(), 0, base::ASCIIToUTF16("News"),
     45                    GURL("http://www.foxnews.com"));
     46     folder_ = model_->AddFolder(
     47         model_->other_node(), 0, base::ASCIIToUTF16("outer folder"));
     48     model_->SetNodeMetaInfo(folder_, "some_key1", "some_value1");
     49     model_->AddFolder(folder_, 0, base::ASCIIToUTF16("inner folder 1"));
     50     model_->AddFolder(folder_, 0, base::ASCIIToUTF16("inner folder 2"));
     51     node2_ = model_->AddURL(
     52         folder_, 0, base::ASCIIToUTF16("Digg"), GURL("http://reddit.com"));
     53     model_->SetNodeMetaInfo(node2_, "some_key2", "some_value2");
     54     model_->AddURL(
     55         folder_, 0, base::ASCIIToUTF16("CNet"), GURL("http://cnet.com"));
     56   }
     57 
     58   content::TestBrowserThreadBundle thread_bundle_;
     59   TestingProfile profile_;
     60   ChromeBookmarkClient* client_;
     61   BookmarkModel* model_;
     62   const BookmarkNode* node_;
     63   const BookmarkNode* node2_;
     64   const BookmarkNode* folder_;
     65 };
     66 
     67 TEST_F(ExtensionBookmarksTest, GetFullTreeFromRoot) {
     68   scoped_ptr<BookmarkTreeNode> tree(
     69       GetBookmarkTreeNode(client_,
     70                           model_->other_node(),
     71                           true,    // Recurse.
     72                           false));  // Not only folders.
     73   ASSERT_EQ(3U, tree->children->size());
     74 }
     75 
     76 TEST_F(ExtensionBookmarksTest, GetFoldersOnlyFromRoot) {
     77   scoped_ptr<BookmarkTreeNode> tree(
     78       GetBookmarkTreeNode(client_,
     79                           model_->other_node(),
     80                           true,   // Recurse.
     81                           true));  // Only folders.
     82   ASSERT_EQ(1U, tree->children->size());
     83 }
     84 
     85 TEST_F(ExtensionBookmarksTest, GetSubtree) {
     86   scoped_ptr<BookmarkTreeNode> tree(
     87       GetBookmarkTreeNode(client_,
     88                           folder_,
     89                           true,    // Recurse.
     90                           false));  // Not only folders.
     91   ASSERT_EQ(4U, tree->children->size());
     92   linked_ptr<BookmarkTreeNode> digg = tree->children->at(1);
     93   ASSERT_TRUE(digg.get());
     94   ASSERT_EQ("Digg", digg->title);
     95 }
     96 
     97 TEST_F(ExtensionBookmarksTest, GetSubtreeFoldersOnly) {
     98   scoped_ptr<BookmarkTreeNode> tree(
     99       GetBookmarkTreeNode(client_,
    100                           folder_,
    101                           true,   // Recurse.
    102                           true));  // Only folders.
    103   ASSERT_EQ(2U, tree->children->size());
    104   linked_ptr<BookmarkTreeNode> inner_folder = tree->children->at(1);
    105   ASSERT_TRUE(inner_folder.get());
    106   ASSERT_EQ("inner folder 1", inner_folder->title);
    107 }
    108 
    109 TEST_F(ExtensionBookmarksTest, GetModifiableNode) {
    110   scoped_ptr<BookmarkTreeNode> tree(
    111       GetBookmarkTreeNode(client_,
    112                           node_,
    113                           false,    // Recurse.
    114                           false));  // Only folders.
    115   EXPECT_EQ("Digg", tree->title);
    116   ASSERT_TRUE(tree->url);
    117   EXPECT_EQ("http://www.reddit.com/", *tree->url);
    118   EXPECT_EQ(BookmarkTreeNode::UNMODIFIABLE_NONE, tree->unmodifiable);
    119 }
    120 
    121 TEST_F(ExtensionBookmarksTest, GetManagedNode) {
    122   const BookmarkNode* managed_bookmark =
    123       model_->AddURL(client_->managed_node(),
    124                      0,
    125                      base::ASCIIToUTF16("Chromium"),
    126                      GURL("http://www.chromium.org/"));
    127   scoped_ptr<BookmarkTreeNode> tree(
    128       GetBookmarkTreeNode(client_,
    129                           managed_bookmark,
    130                           false,    // Recurse.
    131                           false));  // Only folders.
    132   EXPECT_EQ("Chromium", tree->title);
    133   EXPECT_EQ("http://www.chromium.org/", *tree->url);
    134   EXPECT_EQ(BookmarkTreeNode::UNMODIFIABLE_MANAGED, tree->unmodifiable);
    135 }
    136 
    137 TEST_F(ExtensionBookmarksTest, RemoveNodeInvalidId) {
    138   int64 invalid_id = model_->next_node_id();
    139   std::string error;
    140   EXPECT_FALSE(RemoveNode(model_, client_, invalid_id, true, &error));
    141   EXPECT_EQ(keys::kNoNodeError, error);
    142 }
    143 
    144 TEST_F(ExtensionBookmarksTest, RemoveNodePermanent) {
    145   std::string error;
    146   EXPECT_FALSE(
    147       RemoveNode(model_, client_, model_->other_node()->id(), true, &error));
    148   EXPECT_EQ(keys::kModifySpecialError, error);
    149 }
    150 
    151 TEST_F(ExtensionBookmarksTest, RemoveNodeManaged) {
    152   const BookmarkNode* managed_bookmark =
    153       model_->AddURL(client_->managed_node(),
    154                      0,
    155                      base::ASCIIToUTF16("Chromium"),
    156                      GURL("http://www.chromium.org"));
    157   std::string error;
    158   EXPECT_FALSE(
    159       RemoveNode(model_, client_, managed_bookmark->id(), true, &error));
    160   EXPECT_EQ(keys::kModifyManagedError, error);
    161 }
    162 
    163 TEST_F(ExtensionBookmarksTest, RemoveNodeNotRecursive) {
    164   std::string error;
    165   EXPECT_FALSE(RemoveNode(model_, client_, folder_->id(), false, &error));
    166   EXPECT_EQ(keys::kFolderNotEmptyError, error);
    167 }
    168 
    169 TEST_F(ExtensionBookmarksTest, RemoveNodeRecursive) {
    170   EXPECT_EQ(3, model_->other_node()->child_count());
    171   std::string error;
    172   EXPECT_TRUE(RemoveNode(model_, client_, folder_->id(), true, &error));
    173   EXPECT_EQ(2, model_->other_node()->child_count());
    174 }
    175 
    176 TEST_F(ExtensionBookmarksTest, GetMetaInfo) {
    177   base::DictionaryValue id_to_meta_info_map;
    178   GetMetaInfo(*model_->other_node(), &id_to_meta_info_map);
    179   EXPECT_EQ(8u, id_to_meta_info_map.size());
    180 
    181   // Verify top level node.
    182   const base::Value* value = NULL;
    183   EXPECT_TRUE(id_to_meta_info_map.Get(
    184       base::Int64ToString(model_->other_node()->id()), &value));
    185   ASSERT_TRUE(NULL != value);
    186   const base::DictionaryValue* dictionary_value = NULL;
    187   EXPECT_TRUE(value->GetAsDictionary(&dictionary_value));
    188   ASSERT_TRUE(NULL != dictionary_value);
    189   EXPECT_EQ(0u, dictionary_value->size());
    190 
    191   // Verify bookmark with two meta info key/value pairs.
    192   value = NULL;
    193   EXPECT_TRUE(id_to_meta_info_map.Get(
    194       base::Int64ToString(node_->id()), &value));
    195   ASSERT_TRUE(NULL != value);
    196   dictionary_value = NULL;
    197   EXPECT_TRUE(value->GetAsDictionary(&dictionary_value));
    198   ASSERT_TRUE(NULL != dictionary_value);
    199   EXPECT_EQ(2u, dictionary_value->size());
    200   std::string string_value;
    201   EXPECT_TRUE(dictionary_value->GetString("some_key1", &string_value));
    202   EXPECT_EQ("some_value1", string_value);
    203   EXPECT_TRUE(dictionary_value->GetString("some_key2", &string_value));
    204   EXPECT_EQ("some_value2", string_value);
    205 
    206   // Verify folder with one meta info key/value pair.
    207   value = NULL;
    208   EXPECT_TRUE(id_to_meta_info_map.Get(
    209       base::Int64ToString(folder_->id()), &value));
    210   ASSERT_TRUE(NULL != value);
    211   dictionary_value = NULL;
    212   EXPECT_TRUE(value->GetAsDictionary(&dictionary_value));
    213   ASSERT_TRUE(NULL != dictionary_value);
    214   EXPECT_EQ(1u, dictionary_value->size());
    215   EXPECT_TRUE(dictionary_value->GetString("some_key1", &string_value));
    216   EXPECT_EQ("some_value1", string_value);
    217 
    218   // Verify bookmark in a subfolder with one meta info key/value pairs.
    219   value = NULL;
    220   EXPECT_TRUE(id_to_meta_info_map.Get(
    221       base::Int64ToString(node2_->id()), &value));
    222   ASSERT_TRUE(NULL != value);
    223   dictionary_value = NULL;
    224   EXPECT_TRUE(value->GetAsDictionary(&dictionary_value));
    225   ASSERT_TRUE(NULL != dictionary_value);
    226   EXPECT_EQ(1u, dictionary_value->size());
    227   string_value.clear();
    228   EXPECT_FALSE(dictionary_value->GetString("some_key1", &string_value));
    229   EXPECT_EQ("", string_value);
    230   EXPECT_TRUE(dictionary_value->GetString("some_key2", &string_value));
    231   EXPECT_EQ("some_value2", string_value);
    232 
    233 }
    234 
    235 }  // namespace bookmark_api_helpers
    236 }  // namespace extensions
    237