Home | History | Annotate | Download | only in browser
      1 // Copyright 2014 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 "base/basictypes.h"
      6 #include "base/files/scoped_temp_dir.h"
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/strings/string16.h"
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "components/bookmarks/browser/bookmark_model.h"
     11 #include "components/bookmarks/browser/bookmark_node_data.h"
     12 #include "components/bookmarks/test/bookmark_test_helpers.h"
     13 #include "components/bookmarks/test/test_bookmark_client.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 #include "ui/base/dragdrop/os_exchange_data.h"
     16 #include "ui/events/platform/platform_event_source.h"
     17 #include "url/gurl.h"
     18 
     19 using base::ASCIIToUTF16;
     20 
     21 class BookmarkNodeDataTest : public testing::Test {
     22  public:
     23   BookmarkNodeDataTest() {}
     24 
     25   virtual void SetUp() OVERRIDE {
     26     event_source_ = ui::PlatformEventSource::CreateDefault();
     27     model_ = client_.CreateModel(false);
     28     test::WaitForBookmarkModelToLoad(model_.get());
     29     bool success = profile_dir_.CreateUniqueTempDir();
     30     ASSERT_TRUE(success);
     31   }
     32 
     33   virtual void TearDown() OVERRIDE {
     34     model_.reset();
     35     event_source_.reset();
     36     bool success = profile_dir_.Delete();
     37     ASSERT_TRUE(success);
     38   }
     39 
     40   const base::FilePath& GetProfilePath() const { return profile_dir_.path(); }
     41 
     42   BookmarkModel* model() { return model_.get(); }
     43 
     44  private:
     45   base::ScopedTempDir profile_dir_;
     46   test::TestBookmarkClient client_;
     47   scoped_ptr<BookmarkModel> model_;
     48   scoped_ptr<ui::PlatformEventSource> event_source_;
     49 
     50   DISALLOW_COPY_AND_ASSIGN(BookmarkNodeDataTest);
     51 };
     52 
     53 namespace {
     54 
     55 ui::OSExchangeData::Provider* CloneProvider(const ui::OSExchangeData& data) {
     56   return data.provider().Clone();
     57 }
     58 
     59 }  // namespace
     60 
     61 // Makes sure BookmarkNodeData is initially invalid.
     62 TEST_F(BookmarkNodeDataTest, InitialState) {
     63   BookmarkNodeData data;
     64   EXPECT_FALSE(data.is_valid());
     65 }
     66 
     67 // Makes sure reading bogus data leaves the BookmarkNodeData invalid.
     68 TEST_F(BookmarkNodeDataTest, BogusRead) {
     69   ui::OSExchangeData data;
     70   BookmarkNodeData drag_data;
     71   EXPECT_FALSE(drag_data.Read(ui::OSExchangeData(CloneProvider(data))));
     72   EXPECT_FALSE(drag_data.is_valid());
     73 }
     74 
     75 // Writes a URL to the clipboard and make sure BookmarkNodeData can correctly
     76 // read it.
     77 TEST_F(BookmarkNodeDataTest, JustURL) {
     78   const GURL url("http://google.com");
     79   const base::string16 title(ASCIIToUTF16("google.com"));
     80 
     81   ui::OSExchangeData data;
     82   data.SetURL(url, title);
     83 
     84   BookmarkNodeData drag_data;
     85   EXPECT_TRUE(drag_data.Read(ui::OSExchangeData(CloneProvider(data))));
     86   EXPECT_TRUE(drag_data.is_valid());
     87   ASSERT_EQ(1u, drag_data.elements.size());
     88   EXPECT_TRUE(drag_data.elements[0].is_url);
     89   EXPECT_EQ(url, drag_data.elements[0].url);
     90   EXPECT_EQ(title, drag_data.elements[0].title);
     91   EXPECT_TRUE(drag_data.elements[0].date_added.is_null());
     92   EXPECT_TRUE(drag_data.elements[0].date_folder_modified.is_null());
     93   EXPECT_EQ(0u, drag_data.elements[0].children.size());
     94 }
     95 
     96 TEST_F(BookmarkNodeDataTest, URL) {
     97   // Write a single node representing a URL to the clipboard.
     98   const BookmarkNode* root = model()->bookmark_bar_node();
     99   GURL url(GURL("http://foo.com"));
    100   const base::string16 title(ASCIIToUTF16("foo.com"));
    101   const BookmarkNode* node = model()->AddURL(root, 0, title, url);
    102   BookmarkNodeData drag_data(node);
    103   EXPECT_TRUE(drag_data.is_valid());
    104   ASSERT_EQ(1u, drag_data.elements.size());
    105   EXPECT_TRUE(drag_data.elements[0].is_url);
    106   EXPECT_EQ(url, drag_data.elements[0].url);
    107   EXPECT_EQ(title, drag_data.elements[0].title);
    108   EXPECT_EQ(node->date_added(), drag_data.elements[0].date_added);
    109   EXPECT_EQ(node->date_folder_modified(),
    110             drag_data.elements[0].date_folder_modified);
    111   ui::OSExchangeData data;
    112   drag_data.Write(GetProfilePath(), &data);
    113 
    114   // Now read the data back in.
    115   ui::OSExchangeData data2(CloneProvider(data));
    116   BookmarkNodeData read_data;
    117   EXPECT_TRUE(read_data.Read(data2));
    118   EXPECT_TRUE(read_data.is_valid());
    119   ASSERT_EQ(1u, read_data.elements.size());
    120   EXPECT_TRUE(read_data.elements[0].is_url);
    121   EXPECT_EQ(url, read_data.elements[0].url);
    122   EXPECT_EQ(title, read_data.elements[0].title);
    123   EXPECT_TRUE(read_data.elements[0].date_added.is_null());
    124   EXPECT_TRUE(read_data.elements[0].date_folder_modified.is_null());
    125   EXPECT_TRUE(read_data.GetFirstNode(model(), GetProfilePath()) == node);
    126 
    127   // Make sure asking for the node with a different profile returns NULL.
    128   base::ScopedTempDir other_profile_dir;
    129   EXPECT_TRUE(other_profile_dir.CreateUniqueTempDir());
    130   EXPECT_TRUE(read_data.GetFirstNode(model(), other_profile_dir.path()) ==
    131               NULL);
    132 
    133   // Writing should also put the URL and title on the clipboard.
    134   GURL read_url;
    135   base::string16 read_title;
    136   EXPECT_TRUE(data2.GetURLAndTitle(
    137       ui::OSExchangeData::CONVERT_FILENAMES, &read_url, &read_title));
    138   EXPECT_EQ(url, read_url);
    139   EXPECT_EQ(title, read_title);
    140 }
    141 
    142 // Tests writing a folder to the clipboard.
    143 TEST_F(BookmarkNodeDataTest, Folder) {
    144   const BookmarkNode* root = model()->bookmark_bar_node();
    145   const BookmarkNode* g1 = model()->AddFolder(root, 0, ASCIIToUTF16("g1"));
    146   model()->AddFolder(g1, 0, ASCIIToUTF16("g11"));
    147   const BookmarkNode* g12 = model()->AddFolder(g1, 0, ASCIIToUTF16("g12"));
    148 
    149   BookmarkNodeData drag_data(g12);
    150   EXPECT_TRUE(drag_data.is_valid());
    151   ASSERT_EQ(1u, drag_data.elements.size());
    152   EXPECT_EQ(g12->GetTitle(), drag_data.elements[0].title);
    153   EXPECT_FALSE(drag_data.elements[0].is_url);
    154   EXPECT_EQ(g12->date_added(), drag_data.elements[0].date_added);
    155   EXPECT_EQ(g12->date_folder_modified(),
    156             drag_data.elements[0].date_folder_modified);
    157 
    158   ui::OSExchangeData data;
    159   drag_data.Write(GetProfilePath(), &data);
    160 
    161   // Now read the data back in.
    162   ui::OSExchangeData data2(CloneProvider(data));
    163   BookmarkNodeData read_data;
    164   EXPECT_TRUE(read_data.Read(data2));
    165   EXPECT_TRUE(read_data.is_valid());
    166   ASSERT_EQ(1u, read_data.elements.size());
    167   EXPECT_EQ(g12->GetTitle(), read_data.elements[0].title);
    168   EXPECT_FALSE(read_data.elements[0].is_url);
    169   EXPECT_TRUE(read_data.elements[0].date_added.is_null());
    170   EXPECT_TRUE(read_data.elements[0].date_folder_modified.is_null());
    171 
    172   // We should get back the same node when asking for the same profile.
    173   const BookmarkNode* r_g12 = read_data.GetFirstNode(model(), GetProfilePath());
    174   EXPECT_TRUE(g12 == r_g12);
    175 
    176   // A different profile should return NULL for the node.
    177   base::ScopedTempDir other_profile_dir;
    178   EXPECT_TRUE(other_profile_dir.CreateUniqueTempDir());
    179   EXPECT_TRUE(read_data.GetFirstNode(model(), other_profile_dir.path()) ==
    180               NULL);
    181 }
    182 
    183 // Tests reading/writing a folder with children.
    184 TEST_F(BookmarkNodeDataTest, FolderWithChild) {
    185   const BookmarkNode* root = model()->bookmark_bar_node();
    186   const BookmarkNode* folder = model()->AddFolder(root, 0, ASCIIToUTF16("g1"));
    187 
    188   GURL url(GURL("http://foo.com"));
    189   const base::string16 title(ASCIIToUTF16("blah2"));
    190 
    191   model()->AddURL(folder, 0, title, url);
    192 
    193   BookmarkNodeData drag_data(folder);
    194 
    195   ui::OSExchangeData data;
    196   drag_data.Write(GetProfilePath(), &data);
    197 
    198   // Now read the data back in.
    199   ui::OSExchangeData data2(CloneProvider(data));
    200   BookmarkNodeData read_data;
    201   EXPECT_TRUE(read_data.Read(data2));
    202   ASSERT_EQ(1u, read_data.elements.size());
    203   ASSERT_EQ(1u, read_data.elements[0].children.size());
    204   const BookmarkNodeData::Element& read_child =
    205       read_data.elements[0].children[0];
    206 
    207   EXPECT_TRUE(read_child.is_url);
    208   EXPECT_EQ(title, read_child.title);
    209   EXPECT_EQ(url, read_child.url);
    210   EXPECT_TRUE(read_data.elements[0].date_added.is_null());
    211   EXPECT_TRUE(read_data.elements[0].date_folder_modified.is_null());
    212   EXPECT_TRUE(read_child.is_url);
    213 
    214   // And make sure we get the node back.
    215   const BookmarkNode* r_folder =
    216       read_data.GetFirstNode(model(), GetProfilePath());
    217   EXPECT_TRUE(folder == r_folder);
    218 }
    219 
    220 // Tests reading/writing of multiple nodes.
    221 TEST_F(BookmarkNodeDataTest, MultipleNodes) {
    222   const BookmarkNode* root = model()->bookmark_bar_node();
    223   const BookmarkNode* folder = model()->AddFolder(root, 0, ASCIIToUTF16("g1"));
    224 
    225   GURL url(GURL("http://foo.com"));
    226   const base::string16 title(ASCIIToUTF16("blah2"));
    227 
    228   const BookmarkNode* url_node = model()->AddURL(folder, 0, title, url);
    229 
    230   // Write the nodes to the clipboard.
    231   std::vector<const BookmarkNode*> nodes;
    232   nodes.push_back(folder);
    233   nodes.push_back(url_node);
    234   BookmarkNodeData drag_data(nodes);
    235   ui::OSExchangeData data;
    236   drag_data.Write(GetProfilePath(), &data);
    237 
    238   // Read the data back in.
    239   ui::OSExchangeData data2(CloneProvider(data));
    240   BookmarkNodeData read_data;
    241   EXPECT_TRUE(read_data.Read(data2));
    242   EXPECT_TRUE(read_data.is_valid());
    243   ASSERT_EQ(2u, read_data.elements.size());
    244   ASSERT_EQ(1u, read_data.elements[0].children.size());
    245   EXPECT_TRUE(read_data.elements[0].date_added.is_null());
    246   EXPECT_TRUE(read_data.elements[0].date_folder_modified.is_null());
    247 
    248   const BookmarkNodeData::Element& read_folder = read_data.elements[0];
    249   EXPECT_FALSE(read_folder.is_url);
    250   EXPECT_EQ(ASCIIToUTF16("g1"), read_folder.title);
    251   EXPECT_EQ(1u, read_folder.children.size());
    252 
    253   const BookmarkNodeData::Element& read_url = read_data.elements[1];
    254   EXPECT_TRUE(read_url.is_url);
    255   EXPECT_EQ(title, read_url.title);
    256   EXPECT_EQ(0u, read_url.children.size());
    257 
    258   // And make sure we get the node back.
    259   std::vector<const BookmarkNode*> read_nodes =
    260       read_data.GetNodes(model(), GetProfilePath());
    261   ASSERT_EQ(2u, read_nodes.size());
    262   EXPECT_TRUE(read_nodes[0] == folder);
    263   EXPECT_TRUE(read_nodes[1] == url_node);
    264 
    265   // Asking for the first node should return NULL with more than one element
    266   // present.
    267   EXPECT_TRUE(read_data.GetFirstNode(model(), GetProfilePath()) == NULL);
    268 }
    269 
    270 // Tests reading/writing of meta info.
    271 TEST_F(BookmarkNodeDataTest, MetaInfo) {
    272   // Create a node containing meta info.
    273   const BookmarkNode* node = model()->AddURL(model()->other_node(),
    274                                              0,
    275                                              ASCIIToUTF16("foo bar"),
    276                                              GURL("http://www.google.com"));
    277   model()->SetNodeMetaInfo(node, "somekey", "somevalue");
    278   model()->SetNodeMetaInfo(node, "someotherkey", "someothervalue");
    279 
    280   BookmarkNodeData node_data(node);
    281   ui::OSExchangeData data;
    282   node_data.Write(GetProfilePath(), &data);
    283 
    284   // Read the data back in.
    285   ui::OSExchangeData data2(CloneProvider(data));
    286   BookmarkNodeData read_data;
    287   EXPECT_TRUE(read_data.Read(data2));
    288   EXPECT_TRUE(read_data.is_valid());
    289   ASSERT_EQ(1u, read_data.elements.size());
    290 
    291   // Verify that the read data contains the same meta info.
    292   BookmarkNode::MetaInfoMap meta_info_map = read_data.elements[0].meta_info_map;
    293   EXPECT_EQ(2u, meta_info_map.size());
    294   EXPECT_EQ("somevalue", meta_info_map["somekey"]);
    295   EXPECT_EQ("someothervalue", meta_info_map["someotherkey"]);
    296 }
    297