// Copyright (c) 2011 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 "testing/gtest/include/gtest/gtest.h" #include <string> #include <vector> #include "base/string16.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "chrome/browser/first_run/first_run.h" #include "chrome/browser/importer/toolbar_importer.h" #include "chrome/common/libxml_utils.h" #include "googleurl/src/gurl.h" // See http://crbug.com/11838 TEST(Toolbar5ImporterTest, BookmarkParse) { static const string16 kTitle = ASCIIToUTF16("MyTitle"); static const char kUrl[] = "http://www.google.com/"; static const string16 kFolder = ASCIIToUTF16("Google"); static const string16 kFolder2 = ASCIIToUTF16("Homepage"); static const string16 kFolderArray[3] = { ASCIIToUTF16("Google"), ASCIIToUTF16("Search"), ASCIIToUTF16("Page") }; static const string16 kOtherTitle = ASCIIToUTF16("MyOtherTitle"); static const char* kOtherUrl = "http://www.google.com/mail"; static const string16 kOtherFolder = ASCIIToUTF16("Mail"); static const string16 kBookmarkGroupTitle = ASCIIToUTF16("BookmarkGroupTitle"); // Since the following is very dense to read I enumerate the test cases here. // 1. Correct bookmark structure with one label. // 2. Correct bookmark structure with no labels. // 3. Correct bookmark structure with two labels. // 4. Correct bookmark structure with a folder->label translation by toolbar. // 5. Correct bookmark structure with no favicon. // 6. Two correct bookmarks. // The following are error cases by removing sections from the xml: // 7. Empty string passed as xml. // 8. No <bookmarks> section in the xml. // 9. No <bookmark> section below the <bookmarks> section. // 10. No <title> in a <bookmark> section. // 11. No <url> in a <bookmark> section. // 12. No <timestamp> in a <bookmark> section. // 13. No <labels> in a <bookmark> section. static const char* kGoodBookmark = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" " <bookmark> " "<title>MyTitle</title> " "<url>http://www.google.com/</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Google</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; static const char* kGoodBookmarkNoLabel = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" " <bookmark> " "<title>MyTitle</title> " "<url>http://www.google.com/</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; static const char* kGoodBookmarkTwoLabels = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" " <bookmark> " "<title>MyTitle</title> " "<url>http://www.google.com/</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Google</label> <label>Homepage</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; static const char* kGoodBookmarkFolderLabel = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" " <bookmark> " "<title>MyTitle</title> " "<url>http://www.google.com/</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Google:Search:Page</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; static const char* kGoodBookmarkNoFavicon = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" " <bookmark> " "<title>MyTitle</title> " "<url>http://www.google.com/</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Google</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; static const char* kGoodBookmark2Items = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" " <bookmark> " "<title>MyTitle</title> " "<url>http://www.google.com/</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Google</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark>" " <bookmark> " "<title>MyOtherTitle</title> " "<url>http://www.google.com/mail</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Mail</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name>" "<value>http://www.google.com/mail/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1253328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark>" "</bookmarks>"; static const char* kEmptyString = ""; static const char* kBadBookmarkNoBookmarks = " <bookmark> " "<title>MyTitle</title> " "<url>http://www.google.com/</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Google</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; static const char* kBadBookmarkNoBookmark = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" "<title>MyTitle</title> " "<url>http://www.google.com/</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Google</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; static const char* kBadBookmarkNoTitle = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" " <bookmark> " "<url>http://www.google.com/</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Google</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; static const char* kBadBookmarkNoUrl = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" " <bookmark> " "<title>MyTitle</title> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Google</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; static const char* kBadBookmarkNoTimestamp = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" " <bookmark> " "<title>MyTitle</title> " "<url>http://www.google.com/</url> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<labels> <label>Google</label> </labels> " "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; static const char* kBadBookmarkNoLabels = "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>" " <bookmark> " "<title>MyTitle</title> " "<url>http://www.google.com/</url> " "<timestamp>1153328691085181</timestamp> " "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> " "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>" "<attributes> " "<attribute> " "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> " "</attribute> " "<attribute> " "<name>favicon_timestamp</name> <value>1153328653</value> " "</attribute> " "<attribute> <name>notebook_name</name> <value>My notebook 0</value> " "</attribute> " "<attribute> <name>section_name</name> <value>My section 0 " "</value> </attribute> </attributes> " "</bookmark> </bookmarks>"; XmlReader reader; std::string bookmark_xml; std::vector<ProfileWriter::BookmarkEntry> bookmarks; const GURL url(kUrl); const GURL other_url(kOtherUrl); // Test doesn't work if the importer thinks this is the first run of Chromium. // Mark this as a subsequent run of the browser. FirstRun::first_run_ = FirstRun::FIRST_RUN_FALSE; // Test case 1 is parsing a basic bookmark with a single label. bookmark_xml = kGoodBookmark; bookmarks.clear(); XmlReader reader1; EXPECT_TRUE(reader1.Load(bookmark_xml)); EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader1, &bookmarks, kBookmarkGroupTitle)); ASSERT_EQ(1U, bookmarks.size()); EXPECT_FALSE(bookmarks[0].in_toolbar); EXPECT_EQ(kTitle, bookmarks[0].title); EXPECT_EQ(url, bookmarks[0].url); ASSERT_EQ(2U, bookmarks[0].path.size()); EXPECT_EQ(kFolder, bookmarks[0].path[1]); // Test case 2 is parsing a single bookmark with no label. bookmark_xml = kGoodBookmarkNoLabel; bookmarks.clear(); XmlReader reader2; EXPECT_TRUE(reader2.Load(bookmark_xml)); EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader2, &bookmarks, kBookmarkGroupTitle)); ASSERT_EQ(1U, bookmarks.size()); EXPECT_FALSE(bookmarks[0].in_toolbar); EXPECT_EQ(kTitle, bookmarks[0].title); EXPECT_EQ(url, bookmarks[0].url); EXPECT_EQ(1U, bookmarks[0].path.size()); // Test case 3 is parsing a single bookmark with two labels. bookmark_xml = kGoodBookmarkTwoLabels; bookmarks.clear(); XmlReader reader3; EXPECT_TRUE(reader3.Load(bookmark_xml)); EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader3, &bookmarks, kBookmarkGroupTitle)); ASSERT_EQ(2U, bookmarks.size()); EXPECT_FALSE(bookmarks[0].in_toolbar); EXPECT_FALSE(bookmarks[1].in_toolbar); EXPECT_EQ(kTitle, bookmarks[0].title); EXPECT_EQ(kTitle, bookmarks[1].title); EXPECT_EQ(url, bookmarks[0].url); EXPECT_EQ(url, bookmarks[1].url); ASSERT_EQ(2U, bookmarks[0].path.size()); EXPECT_EQ(kFolder, bookmarks[0].path[1]); ASSERT_EQ(2U, bookmarks[1].path.size()); EXPECT_EQ(kFolder2, bookmarks[1].path[1]); // Test case 4 is parsing a single bookmark which has a label with a colon, // this test file name translation between Toolbar and Chrome. bookmark_xml = kGoodBookmarkFolderLabel; bookmarks.clear(); XmlReader reader4; EXPECT_TRUE(reader4.Load(bookmark_xml)); EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader4, &bookmarks, kBookmarkGroupTitle)); ASSERT_EQ(1U, bookmarks.size()); EXPECT_FALSE(bookmarks[0].in_toolbar); EXPECT_EQ(kTitle, bookmarks[0].title); EXPECT_EQ(url, bookmarks[0].url); ASSERT_EQ(4U, bookmarks[0].path.size()); EXPECT_EQ(string16(kFolderArray[0]), bookmarks[0].path[1]); EXPECT_EQ(string16(kFolderArray[1]), bookmarks[0].path[2]); EXPECT_EQ(string16(kFolderArray[2]), bookmarks[0].path[3]); // Test case 5 is parsing a single bookmark without a favicon URL. bookmark_xml = kGoodBookmarkNoFavicon; bookmarks.clear(); XmlReader reader5; EXPECT_TRUE(reader5.Load(bookmark_xml)); EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader5, &bookmarks, kBookmarkGroupTitle)); ASSERT_EQ(1U, bookmarks.size()); EXPECT_FALSE(bookmarks[0].in_toolbar); EXPECT_EQ(kTitle, bookmarks[0].title); EXPECT_EQ(url, bookmarks[0].url); ASSERT_EQ(2U, bookmarks[0].path.size()); EXPECT_EQ(kFolder, bookmarks[0].path[1]); // Test case 6 is parsing two bookmarks. bookmark_xml = kGoodBookmark2Items; bookmarks.clear(); XmlReader reader6; EXPECT_TRUE(reader6.Load(bookmark_xml)); EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader6, &bookmarks, kBookmarkGroupTitle)); ASSERT_EQ(2U, bookmarks.size()); EXPECT_FALSE(bookmarks[0].in_toolbar); EXPECT_FALSE(bookmarks[1].in_toolbar); EXPECT_EQ(kTitle, bookmarks[0].title); EXPECT_EQ(kOtherTitle, bookmarks[1].title); EXPECT_EQ(url, bookmarks[0].url); EXPECT_EQ(other_url, bookmarks[1].url); ASSERT_EQ(2U, bookmarks[0].path.size()); EXPECT_EQ(kFolder, bookmarks[0].path[1]); ASSERT_EQ(2U, bookmarks[1].path.size()); EXPECT_EQ(kOtherFolder, bookmarks[1].path[1]); // Test case 7 is parsing an empty string for bookmarks. bookmark_xml = kEmptyString; bookmarks.clear(); XmlReader reader7; EXPECT_FALSE(reader7.Load(bookmark_xml)); // Test case 8 is testing the error when no <bookmarks> section is present. bookmark_xml = kBadBookmarkNoBookmarks; bookmarks.clear(); XmlReader reader8; EXPECT_TRUE(reader8.Load(bookmark_xml)); EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader8, &bookmarks, kBookmarkGroupTitle)); // Test case 9 tests when no <bookmark> section is present. bookmark_xml = kBadBookmarkNoBookmark; bookmarks.clear(); XmlReader reader9; EXPECT_TRUE(reader9.Load(bookmark_xml)); EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader9, &bookmarks, kBookmarkGroupTitle)); // Test case 10 tests when a bookmark has no <title> section. bookmark_xml = kBadBookmarkNoTitle; bookmarks.clear(); XmlReader reader10; EXPECT_TRUE(reader10.Load(bookmark_xml)); EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader10, &bookmarks, kBookmarkGroupTitle)); // Test case 11 tests when a bookmark has no <url> section. bookmark_xml = kBadBookmarkNoUrl; bookmarks.clear(); XmlReader reader11; EXPECT_TRUE(reader11.Load(bookmark_xml)); EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader11, &bookmarks, kBookmarkGroupTitle)); // Test case 12 tests when a bookmark has no <timestamp> section. bookmark_xml = kBadBookmarkNoTimestamp; bookmarks.clear(); XmlReader reader12; EXPECT_TRUE(reader12.Load(bookmark_xml)); EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader12, &bookmarks, kBookmarkGroupTitle)); // Test case 13 tests when a bookmark has no <labels> section. bookmark_xml = kBadBookmarkNoLabels; bookmarks.clear(); XmlReader reader13; EXPECT_TRUE(reader13.Load(bookmark_xml)); EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader13, &bookmarks, kBookmarkGroupTitle)); }