toolbar_importer_unittest.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2006-2008 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 "testing/gtest/include/gtest/gtest.h"
6
7#include <string>
8#include <vector>
9
10#include "base/string16.h"
11#include "chrome/browser/first_run.h"
12#include "chrome/browser/importer/importer.h"
13#include "chrome/browser/importer/toolbar_importer.h"
14#include "chrome/common/libxml_utils.h"
15#include "googleurl/src/gurl.h"
16
17// See http://crbug.com/11838
18TEST(Toolbar5ImporterTest, BookmarkParse) {
19static const wchar_t* kTitle = L"MyTitle";
20static const char* kUrl = "http://www.google.com/";
21static const wchar_t* kFolder = L"Google";
22static const wchar_t* kFolder2 = L"Homepage";
23static const wchar_t* kFolderArray[3] = {L"Google", L"Search", L"Page"};
24
25static const wchar_t* kOtherTitle = L"MyOtherTitle";
26static const char* kOtherUrl = "http://www.google.com/mail";
27static const wchar_t* kOtherFolder = L"Mail";
28
29static const string16 kBookmarkGroupTitle = ASCIIToUTF16("BookmarkGroupTitle");
30
31// Since the following is very dense to read I enumerate the test cases here.
32// 1. Correct bookmark structure with one label.
33// 2. Correct bookmark structure with no labels.
34// 3. Correct bookmark structure with two labels.
35// 4. Correct bookmark structure with a folder->label translation by toolbar.
36// 5. Correct bookmark structure with no favicon.
37// 6. Two correct bookmarks.
38// The following are error cases by removing sections from the xml:
39// 7. Empty string passed as xml.
40// 8. No <bookmarks> section in the xml.
41// 9. No <bookmark> section below the <bookmarks> section.
42// 10. No <title> in a <bookmark> section.
43// 11. No <url> in a <bookmark> section.
44// 12. No <timestamp> in a <bookmark> section.
45// 13. No <labels> in a <bookmark> section.
46static const char* kGoodBookmark =
47    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
48    " <bookmark> "
49    "<title>MyTitle</title> "
50    "<url>http://www.google.com/</url> "
51    "<timestamp>1153328691085181</timestamp> "
52    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
53    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
54    "<labels> <label>Google</label> </labels> "
55    "<attributes> "
56    "<attribute> "
57    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
58    "</attribute> "
59    "<attribute> "
60    "<name>favicon_timestamp</name> <value>1153328653</value> "
61    "</attribute> "
62    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
63    "</attribute> "
64    "<attribute> <name>section_name</name> <value>My section 0 "
65    "</value> </attribute> </attributes> "
66    "</bookmark> </bookmarks>";
67static const char* kGoodBookmarkNoLabel =
68    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
69    " <bookmark> "
70    "<title>MyTitle</title> "
71    "<url>http://www.google.com/</url> "
72    "<timestamp>1153328691085181</timestamp> "
73    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
74    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
75    "<labels> </labels> "
76    "<attributes> "
77    "<attribute> "
78    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
79    "</attribute> "
80    "<attribute> "
81    "<name>favicon_timestamp</name> <value>1153328653</value> "
82    "</attribute> "
83    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
84    "</attribute> "
85    "<attribute> <name>section_name</name> <value>My section 0 "
86    "</value> </attribute> </attributes> "
87    "</bookmark> </bookmarks>";
88static const char* kGoodBookmarkTwoLabels =
89    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
90    " <bookmark> "
91    "<title>MyTitle</title> "
92    "<url>http://www.google.com/</url> "
93    "<timestamp>1153328691085181</timestamp> "
94    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
95    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
96    "<labels> <label>Google</label> <label>Homepage</label> </labels> "
97    "<attributes> "
98    "<attribute> "
99    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
100    "</attribute> "
101    "<attribute> "
102    "<name>favicon_timestamp</name> <value>1153328653</value> "
103    "</attribute> "
104    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
105    "</attribute> "
106    "<attribute> <name>section_name</name> <value>My section 0 "
107    "</value> </attribute> </attributes> "
108    "</bookmark> </bookmarks>";
109static const char* kGoodBookmarkFolderLabel =
110    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
111    " <bookmark> "
112    "<title>MyTitle</title> "
113    "<url>http://www.google.com/</url> "
114    "<timestamp>1153328691085181</timestamp> "
115    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
116    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
117    "<labels> <label>Google:Search:Page</label> </labels> "
118    "<attributes> "
119    "<attribute> "
120    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
121    "</attribute> "
122    "<attribute> "
123    "<name>favicon_timestamp</name> <value>1153328653</value> "
124    "</attribute> "
125    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
126    "</attribute> "
127    "<attribute> <name>section_name</name> <value>My section 0 "
128    "</value> </attribute> </attributes> "
129    "</bookmark> </bookmarks>";
130static const char* kGoodBookmarkNoFavicon =
131    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
132    " <bookmark> "
133    "<title>MyTitle</title> "
134    "<url>http://www.google.com/</url> "
135    "<timestamp>1153328691085181</timestamp> "
136    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
137    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
138    "<labels> <label>Google</label> </labels> "
139    "<attributes> "
140    "<attribute> "
141    "<name>favicon_timestamp</name> <value>1153328653</value> "
142    "</attribute> "
143    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
144    "</attribute> "
145    "<attribute> <name>section_name</name> <value>My section 0 "
146    "</value> </attribute> </attributes> "
147    "</bookmark> </bookmarks>";
148static const char* kGoodBookmark2Items =
149    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
150    " <bookmark> "
151    "<title>MyTitle</title> "
152    "<url>http://www.google.com/</url> "
153    "<timestamp>1153328691085181</timestamp> "
154    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
155    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
156    "<labels> <label>Google</label> </labels> "
157    "<attributes> "
158    "<attribute> "
159    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
160    "</attribute> "
161    "<attribute> "
162    "<name>favicon_timestamp</name> <value>1153328653</value> "
163    "</attribute> "
164    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
165    "</attribute> "
166    "<attribute> <name>section_name</name> <value>My section 0 "
167    "</value> </attribute> </attributes> "
168    "</bookmark>"
169    " <bookmark> "
170    "<title>MyOtherTitle</title> "
171    "<url>http://www.google.com/mail</url> "
172    "<timestamp>1153328691085181</timestamp> "
173    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
174    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
175    "<labels> <label>Mail</label> </labels> "
176    "<attributes> "
177    "<attribute> "
178    "<name>favicon_url</name>"
179    "<value>http://www.google.com/mail/favicon.ico</value> "
180    "</attribute> "
181    "<attribute> "
182    "<name>favicon_timestamp</name> <value>1253328653</value> "
183    "</attribute> "
184    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
185    "</attribute> "
186    "<attribute> <name>section_name</name> <value>My section 0 "
187    "</value> </attribute> </attributes> "
188    "</bookmark>"
189    "</bookmarks>";
190static const char* kEmptyString = "";
191static const char* kBadBookmarkNoBookmarks =
192    " <bookmark> "
193    "<title>MyTitle</title> "
194    "<url>http://www.google.com/</url> "
195    "<timestamp>1153328691085181</timestamp> "
196    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
197    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
198    "<labels> <label>Google</label> </labels> "
199    "<attributes> "
200    "<attribute> "
201    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
202    "</attribute> "
203    "<attribute> "
204    "<name>favicon_timestamp</name> <value>1153328653</value> "
205    "</attribute> "
206    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
207    "</attribute> "
208    "<attribute> <name>section_name</name> <value>My section 0 "
209    "</value> </attribute> </attributes> "
210    "</bookmark> </bookmarks>";
211static const char* kBadBookmarkNoBookmark =
212    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
213    "<title>MyTitle</title> "
214    "<url>http://www.google.com/</url> "
215    "<timestamp>1153328691085181</timestamp> "
216    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
217    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
218    "<labels> <label>Google</label> </labels> "
219    "<attributes> "
220    "<attribute> "
221    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
222    "</attribute> "
223    "<attribute> "
224    "<name>favicon_timestamp</name> <value>1153328653</value> "
225    "</attribute> "
226    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
227    "</attribute> "
228    "<attribute> <name>section_name</name> <value>My section 0 "
229    "</value> </attribute> </attributes> "
230    "</bookmark> </bookmarks>";
231static const char* kBadBookmarkNoTitle =
232    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
233    " <bookmark> "
234    "<url>http://www.google.com/</url> "
235    "<timestamp>1153328691085181</timestamp> "
236    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
237    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
238    "<labels> <label>Google</label> </labels> "
239    "<attributes> "
240    "<attribute> "
241    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
242    "</attribute> "
243    "<attribute> "
244    "<name>favicon_timestamp</name> <value>1153328653</value> "
245    "</attribute> "
246    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
247    "</attribute> "
248    "<attribute> <name>section_name</name> <value>My section 0 "
249    "</value> </attribute> </attributes> "
250    "</bookmark> </bookmarks>";
251static const char* kBadBookmarkNoUrl =
252    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
253    " <bookmark> "
254    "<title>MyTitle</title> "
255    "<timestamp>1153328691085181</timestamp> "
256    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
257    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
258    "<labels> <label>Google</label> </labels> "
259    "<attributes> "
260    "<attribute> "
261    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
262    "</attribute> "
263    "<attribute> "
264    "<name>favicon_timestamp</name> <value>1153328653</value> "
265    "</attribute> "
266    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
267    "</attribute> "
268    "<attribute> <name>section_name</name> <value>My section 0 "
269    "</value> </attribute> </attributes> "
270    "</bookmark> </bookmarks>";
271static const char* kBadBookmarkNoTimestamp =
272    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
273    " <bookmark> "
274    "<title>MyTitle</title> "
275    "<url>http://www.google.com/</url> "
276    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
277    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
278    "<labels> <label>Google</label> </labels> "
279    "<attributes> "
280    "<attribute> "
281    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
282    "</attribute> "
283    "<attribute> "
284    "<name>favicon_timestamp</name> <value>1153328653</value> "
285    "</attribute> "
286    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
287    "</attribute> "
288    "<attribute> <name>section_name</name> <value>My section 0 "
289    "</value> </attribute> </attributes> "
290    "</bookmark> </bookmarks>";
291static const char* kBadBookmarkNoLabels =
292    "<?xml version=\"1.0\" ?> <xml_api_reply version=\"1\"> <bookmarks>"
293    " <bookmark> "
294    "<title>MyTitle</title> "
295    "<url>http://www.google.com/</url> "
296    "<timestamp>1153328691085181</timestamp> "
297    "<id>N123nasdf239</id> <notebook_id>Bxxxxxxx</notebook_id> "
298    "<section_id>Sxxxxxx</section_id> <has_highlight>0</has_highlight>"
299    "<attributes> "
300    "<attribute> "
301    "<name>favicon_url</name> <value>http://www.google.com/favicon.ico</value> "
302    "</attribute> "
303    "<attribute> "
304    "<name>favicon_timestamp</name> <value>1153328653</value> "
305    "</attribute> "
306    "<attribute> <name>notebook_name</name> <value>My notebook 0</value> "
307    "</attribute> "
308    "<attribute> <name>section_name</name> <value>My section 0 "
309    "</value> </attribute> </attributes> "
310    "</bookmark> </bookmarks>";
311
312  XmlReader reader;
313  std::string bookmark_xml;
314  std::vector<ProfileWriter::BookmarkEntry> bookmarks;
315
316  const GURL url(kUrl);
317  const GURL other_url(kOtherUrl);
318
319  // Test doesn't work if the importer thinks this is the first run of Chromium.
320  // Mark this as a subsequent run of the browser.
321  FirstRun::CreateSentinel();
322
323  // Test case 1 is parsing a basic bookmark with a single label.
324  bookmark_xml = kGoodBookmark;
325  bookmarks.clear();
326  XmlReader reader1;
327  EXPECT_TRUE(reader1.Load(bookmark_xml));
328  EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader1, &bookmarks,
329      kBookmarkGroupTitle));
330
331  ASSERT_EQ(1U, bookmarks.size());
332  EXPECT_FALSE(bookmarks[0].in_toolbar);
333  EXPECT_EQ(kTitle, bookmarks[0].title);
334  EXPECT_EQ(url, bookmarks[0].url);
335  ASSERT_EQ(2U, bookmarks[0].path.size());
336  EXPECT_EQ(kFolder, bookmarks[0].path[1]);
337
338  // Test case 2 is parsing a single bookmark with no label.
339  bookmark_xml = kGoodBookmarkNoLabel;
340  bookmarks.clear();
341  XmlReader reader2;
342  EXPECT_TRUE(reader2.Load(bookmark_xml));
343  EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader2, &bookmarks,
344      kBookmarkGroupTitle));
345
346  ASSERT_EQ(1U, bookmarks.size());
347  EXPECT_FALSE(bookmarks[0].in_toolbar);
348  EXPECT_EQ(kTitle, bookmarks[0].title);
349  EXPECT_EQ(url, bookmarks[0].url);
350  EXPECT_EQ(1U, bookmarks[0].path.size());
351
352  // Test case 3 is parsing a single bookmark with two labels.
353  bookmark_xml = kGoodBookmarkTwoLabels;
354  bookmarks.clear();
355  XmlReader reader3;
356  EXPECT_TRUE(reader3.Load(bookmark_xml));
357  EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader3, &bookmarks,
358      kBookmarkGroupTitle));
359
360  ASSERT_EQ(2U, bookmarks.size());
361  EXPECT_FALSE(bookmarks[0].in_toolbar);
362  EXPECT_FALSE(bookmarks[1].in_toolbar);
363  EXPECT_EQ(kTitle, bookmarks[0].title);
364  EXPECT_EQ(kTitle, bookmarks[1].title);
365  EXPECT_EQ(url, bookmarks[0].url);
366  EXPECT_EQ(url, bookmarks[1].url);
367  ASSERT_EQ(2U, bookmarks[0].path.size());
368  EXPECT_EQ(kFolder, bookmarks[0].path[1]);
369  ASSERT_EQ(2U, bookmarks[1].path.size());
370  EXPECT_EQ(kFolder2, bookmarks[1].path[1]);
371
372  // Test case 4 is parsing a single bookmark which has a label with a colon,
373  // this test file name translation between Toolbar and Chrome.
374  bookmark_xml = kGoodBookmarkFolderLabel;
375  bookmarks.clear();
376  XmlReader reader4;
377  EXPECT_TRUE(reader4.Load(bookmark_xml));
378  EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader4, &bookmarks,
379      kBookmarkGroupTitle));
380
381  ASSERT_EQ(1U, bookmarks.size());
382  EXPECT_FALSE(bookmarks[0].in_toolbar);
383  EXPECT_EQ(kTitle, bookmarks[0].title);
384  EXPECT_EQ(url, bookmarks[0].url);
385  ASSERT_EQ(4U, bookmarks[0].path.size());
386  EXPECT_EQ(std::wstring(kFolderArray[0]),
387            bookmarks[0].path[1]);
388  EXPECT_EQ(std::wstring(kFolderArray[1]),
389            bookmarks[0].path[2]);
390  EXPECT_EQ(std::wstring(kFolderArray[2]),
391            bookmarks[0].path[3]);
392
393  // Test case 5 is parsing a single bookmark without a favicon URL.
394  bookmark_xml = kGoodBookmarkNoFavicon;
395  bookmarks.clear();
396  XmlReader reader5;
397  EXPECT_TRUE(reader5.Load(bookmark_xml));
398  EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader5, &bookmarks,
399      kBookmarkGroupTitle));
400
401  ASSERT_EQ(1U, bookmarks.size());
402  EXPECT_FALSE(bookmarks[0].in_toolbar);
403  EXPECT_EQ(kTitle, bookmarks[0].title);
404  EXPECT_EQ(url, bookmarks[0].url);
405  ASSERT_EQ(2U, bookmarks[0].path.size());
406  EXPECT_EQ(kFolder, bookmarks[0].path[1]);
407
408  // Test case 6 is parsing two bookmarks.
409  bookmark_xml = kGoodBookmark2Items;
410  bookmarks.clear();
411  XmlReader reader6;
412  EXPECT_TRUE(reader6.Load(bookmark_xml));
413  EXPECT_TRUE(Toolbar5Importer::ParseBookmarksFromReader(&reader6, &bookmarks,
414      kBookmarkGroupTitle));
415
416  ASSERT_EQ(2U, bookmarks.size());
417  EXPECT_FALSE(bookmarks[0].in_toolbar);
418  EXPECT_FALSE(bookmarks[1].in_toolbar);
419  EXPECT_EQ(kTitle, bookmarks[0].title);
420  EXPECT_EQ(kOtherTitle, bookmarks[1].title);
421  EXPECT_EQ(url, bookmarks[0].url);
422  EXPECT_EQ(other_url, bookmarks[1].url);
423  ASSERT_EQ(2U, bookmarks[0].path.size());
424  EXPECT_EQ(kFolder, bookmarks[0].path[1]);
425  ASSERT_EQ(2U, bookmarks[1].path.size());
426  EXPECT_EQ(kOtherFolder, bookmarks[1].path[1]);
427
428  // Test case 7 is parsing an empty string for bookmarks.
429  bookmark_xml = kEmptyString;
430  bookmarks.clear();
431  XmlReader reader7;
432  EXPECT_FALSE(reader7.Load(bookmark_xml));
433
434  // Test case 8 is testing the error when no <bookmarks> section is present.
435  bookmark_xml = kBadBookmarkNoBookmarks;
436  bookmarks.clear();
437  XmlReader reader8;
438  EXPECT_TRUE(reader8.Load(bookmark_xml));
439  EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader8,
440      &bookmarks, kBookmarkGroupTitle));
441
442  // Test case 9 tests when no <bookmark> section is present.
443  bookmark_xml = kBadBookmarkNoBookmark;
444  bookmarks.clear();
445  XmlReader reader9;
446  EXPECT_TRUE(reader9.Load(bookmark_xml));
447  EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader9,
448      &bookmarks, kBookmarkGroupTitle));
449
450
451  // Test case 10 tests when a bookmark has no <title> section.
452  bookmark_xml = kBadBookmarkNoTitle;
453  bookmarks.clear();
454  XmlReader reader10;
455  EXPECT_TRUE(reader10.Load(bookmark_xml));
456  EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader10,
457      &bookmarks, kBookmarkGroupTitle));
458
459  // Test case 11 tests when a bookmark has no <url> section.
460  bookmark_xml = kBadBookmarkNoUrl;
461  bookmarks.clear();
462  XmlReader reader11;
463  EXPECT_TRUE(reader11.Load(bookmark_xml));
464  EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader11,
465      &bookmarks, kBookmarkGroupTitle));
466
467  // Test case 12 tests when a bookmark has no <timestamp> section.
468  bookmark_xml = kBadBookmarkNoTimestamp;
469  bookmarks.clear();
470  XmlReader reader12;
471  EXPECT_TRUE(reader12.Load(bookmark_xml));
472  EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader12,
473      &bookmarks, kBookmarkGroupTitle));
474
475  // Test case 13 tests when a bookmark has no <labels> section.
476  bookmark_xml = kBadBookmarkNoLabels;
477  bookmarks.clear();
478  XmlReader reader13;
479  EXPECT_TRUE(reader13.Load(bookmark_xml));
480  EXPECT_FALSE(Toolbar5Importer::ParseBookmarksFromReader(&reader13,
481      &bookmarks, kBookmarkGroupTitle));
482}
483