Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / enhanced_bookmarks / enhanced_bookmark_model_unittest.cc
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 "components/enhanced_bookmarks/enhanced_bookmark_model.h"
6
7 #include "base/base64.h"
8 #include "base/macros.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "components/bookmarks/browser/bookmark_model.h"
16 #include "components/bookmarks/browser/bookmark_node.h"
17 #include "components/bookmarks/test/test_bookmark_client.h"
18 #include "components/enhanced_bookmarks/enhanced_bookmark_model_observer.h"
19 #include "components/enhanced_bookmarks/proto/metadata.pb.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "url/gurl.h"
22
23 using enhanced_bookmarks::EnhancedBookmarkModel;
24
25 namespace {
26 const std::string BOOKMARK_URL("http://example.com/index.html");
27 }  // namespace
28
29 class EnhancedBookmarkModelTest
30     : public testing::Test,
31       public enhanced_bookmarks::EnhancedBookmarkModelObserver {
32  public:
33   EnhancedBookmarkModelTest()
34       : loaded_calls_(0),
35         shutting_down_calls_(0),
36         added_calls_(0),
37         removed_calls_(0),
38         changed_calls_(0),
39         all_user_nodes_removed_calls_(0),
40         remote_id_changed_calls_(0),
41         last_added_(NULL),
42         last_removed_(NULL),
43         last_changed_(NULL),
44         last_remote_id_node_(NULL) {}
45   ~EnhancedBookmarkModelTest() override {}
46
47   void SetUp() override {
48     message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_DEFAULT));
49     bookmark_client_.reset(new bookmarks::TestBookmarkClient());
50     bookmark_model_.reset(bookmark_client_->CreateModel().release());
51     model_.reset(new EnhancedBookmarkModel(bookmark_model_.get(), "v1.0"));
52     model_->AddObserver(this);
53   }
54
55   void TearDown() override {
56     if (model_)
57       model_->Shutdown();
58     model_.reset();
59     bookmark_model_.reset();
60     bookmark_client_.reset();
61     message_loop_.reset();
62   }
63
64  protected:
65   const BookmarkNode* AddBookmark() {
66     return AddBookmark("Some title", bookmark_model_->other_node());
67   }
68
69   const BookmarkNode* AddFolder() {
70     return AddFolder("Some title", bookmark_model_->other_node());
71   }
72
73   const BookmarkNode* AddBookmark(const std::string& name,
74                                   const BookmarkNode* parent) {
75     return model_->AddURL(parent,
76                           0,  // index.
77                           base::ASCIIToUTF16(name),
78                           GURL(BOOKMARK_URL),
79                           base::Time::Now());
80   }
81
82   const BookmarkNode* AddFolder(const std::string& name,
83                                 const BookmarkNode* parent) {
84     return model_->AddFolder(parent, 0, base::ASCIIToUTF16(name));
85   }
86
87   std::string GetVersion(const BookmarkNode* node) {
88     return GetMetaInfoField(node, "stars.version");
89   }
90
91   std::string GetId(const BookmarkNode* node) {
92     return GetMetaInfoField(node, "stars.id");
93   }
94
95   std::string GetOldId(const BookmarkNode* node) {
96     return GetMetaInfoField(node, "stars.oldId");
97   }
98
99   std::string GetMetaInfoField(const BookmarkNode* node,
100                                const std::string& name) {
101     std::string value;
102     if (!node->GetMetaInfo(name, &value))
103       return std::string();
104     return value;
105   }
106
107   scoped_ptr<base::MessageLoop> message_loop_;
108   scoped_ptr<bookmarks::TestBookmarkClient> bookmark_client_;
109   scoped_ptr<BookmarkModel> bookmark_model_;
110   scoped_ptr<EnhancedBookmarkModel> model_;
111
112   // EnhancedBookmarkModelObserver implementation:
113   void EnhancedBookmarkModelLoaded() override { loaded_calls_++; }
114   void EnhancedBookmarkModelShuttingDown() override { shutting_down_calls_++; }
115   void EnhancedBookmarkAdded(const BookmarkNode* node) override {
116     added_calls_++;
117     last_added_ = node;
118   }
119   void EnhancedBookmarkRemoved(const BookmarkNode* node) override {
120     removed_calls_++;
121     last_removed_ = node;
122   }
123   void EnhancedBookmarkNodeChanged(const BookmarkNode* node) override {
124     changed_calls_++;
125     last_changed_ = node;
126   }
127   void EnhancedBookmarkAllUserNodesRemoved() override {
128     all_user_nodes_removed_calls_++;
129   }
130   void EnhancedBookmarkRemoteIdChanged(const BookmarkNode* node,
131                                        const std::string& old_remote_id,
132                                        const std::string& remote_id) override {
133     remote_id_changed_calls_++;
134     last_remote_id_node_ = node;
135     last_old_remote_id_ = old_remote_id;
136     last_remote_id_ = remote_id;
137   }
138
139   // Observer call counters:
140   int loaded_calls_;
141   int shutting_down_calls_;
142   int added_calls_;
143   int removed_calls_;
144   int changed_calls_;
145   int all_user_nodes_removed_calls_;
146   int remote_id_changed_calls_;
147
148   // Observer parameter cache:
149   const BookmarkNode* last_added_;
150   const BookmarkNode* last_removed_;
151   const BookmarkNode* last_changed_;
152   const BookmarkNode* last_remote_id_node_;
153   std::string last_old_remote_id_;
154   std::string last_remote_id_;
155
156  private:
157   DISALLOW_COPY_AND_ASSIGN(EnhancedBookmarkModelTest);
158 };
159
160 TEST_F(EnhancedBookmarkModelTest, TestEmptySnippet) {
161   const BookmarkNode* node = AddBookmark();
162
163   std::string snippet(model_->GetSnippet(node));
164   EXPECT_EQ(snippet, "");
165 };
166
167 TEST_F(EnhancedBookmarkModelTest, TestSnippet) {
168   const BookmarkNode* node = AddBookmark();
169
170   // Binary serialize the protobuf.
171   image::collections::PageData data;
172   data.set_snippet("I'm happy!");
173   ASSERT_TRUE(data.IsInitialized());
174   std::string output;
175   bool result = data.SerializeToString(&output);
176   ASSERT_TRUE(result);
177
178   // base64 encode the output.
179   std::string encoded;
180   base::Base64Encode(output, &encoded);
181   bookmark_model_->SetNodeMetaInfo(node, "stars.pageData", encoded);
182
183   std::string snippet(model_->GetSnippet(node));
184   EXPECT_EQ(snippet, "I'm happy!");
185 }
186
187 TEST_F(EnhancedBookmarkModelTest, TestBadEncodingSnippet) {
188   const BookmarkNode* node = AddBookmark();
189
190   // Binary serialize the protobuf.
191   image::collections::PageData data;
192   data.set_snippet("You are happy!");
193   ASSERT_TRUE(data.IsInitialized());
194   std::string output;
195   bool result = data.SerializeToString(&output);
196   ASSERT_TRUE(result);
197
198   // don't base 64 encode the output.
199   bookmark_model_->SetNodeMetaInfo(node, "stars.pageData", output);
200
201   std::string snippet(model_->GetSnippet(node));
202   EXPECT_EQ(snippet, "");
203 }
204
205 TEST_F(EnhancedBookmarkModelTest, TestOriginalImage) {
206   const BookmarkNode* node = AddBookmark();
207
208   image::collections::ImageData data;
209   // Intentionally make raw pointer.
210   image::collections::ImageData_ImageInfo* info =
211       new image::collections::ImageData_ImageInfo;
212   info->set_url("http://example.com/foobar");
213   info->set_width(15);
214   info->set_height(55);
215   // This method consumes the pointer.
216   data.set_allocated_original_info(info);
217
218   std::string output;
219   bool result = data.SerializePartialToString(&output);
220   ASSERT_TRUE(result);
221
222   // base64 encode the output.
223   std::string encoded;
224   base::Base64Encode(output, &encoded);
225   bookmark_model_->SetNodeMetaInfo(node, "stars.imageData", encoded);
226
227   GURL url;
228   int width;
229   int height;
230   result = model_->GetOriginalImage(node, &url, &width, &height);
231   ASSERT_TRUE(result);
232   EXPECT_EQ(url, GURL("http://example.com/foobar"));
233   EXPECT_EQ(width, 15);
234   EXPECT_EQ(height, 55);
235 }
236
237 TEST_F(EnhancedBookmarkModelTest, TestThumbnailImage) {
238   const BookmarkNode* node = AddBookmark();
239
240   image::collections::ImageData data;
241   // Intentionally make raw pointer.
242   image::collections::ImageData_ImageInfo* info =
243       new image::collections::ImageData_ImageInfo;
244   info->set_url("http://example.com/foobar");
245   info->set_width(15);
246   info->set_height(55);
247   // This method consumes the pointer.
248   data.set_allocated_thumbnail_info(info);
249
250   std::string output;
251   bool result = data.SerializePartialToString(&output);
252   ASSERT_TRUE(result);
253
254   // base64 encode the output.
255   std::string encoded;
256   base::Base64Encode(output, &encoded);
257   bookmark_model_->SetNodeMetaInfo(node, "stars.imageData", encoded);
258
259   GURL url;
260   int width;
261   int height;
262   result = model_->GetThumbnailImage(node, &url, &width, &height);
263   ASSERT_TRUE(result);
264   EXPECT_EQ(url, GURL("http://example.com/foobar"));
265   EXPECT_EQ(width, 15);
266   EXPECT_EQ(height, 55);
267 }
268
269 TEST_F(EnhancedBookmarkModelTest, TestOriginalImageMissingDimensions) {
270   const BookmarkNode* node = AddBookmark();
271
272   image::collections::ImageData data;
273   // Intentionally make raw pointer.
274   image::collections::ImageData_ImageInfo* info =
275       new image::collections::ImageData_ImageInfo;
276   info->set_url("http://example.com/foobar");
277   // This method consumes the pointer.
278   data.set_allocated_original_info(info);
279
280   std::string output;
281   bool result = data.SerializePartialToString(&output);
282   ASSERT_TRUE(result);
283
284   // base64 encode the output.
285   std::string encoded;
286   base::Base64Encode(output, &encoded);
287   bookmark_model_->SetNodeMetaInfo(node, "stars.imageData", encoded);
288
289   GURL url;
290   int width;
291   int height;
292   result = model_->GetOriginalImage(node, &url, &width, &height);
293   ASSERT_FALSE(result);
294 }
295
296 TEST_F(EnhancedBookmarkModelTest, TestOriginalImageBadUrl) {
297   const BookmarkNode* node = AddBookmark();
298
299   image::collections::ImageData data;
300   // Intentionally make raw pointer.
301   image::collections::ImageData_ImageInfo* info =
302       new image::collections::ImageData_ImageInfo;
303   info->set_url("asdf. 13r");
304   info->set_width(15);
305   info->set_height(55);
306   // This method consumes the pointer.
307   data.set_allocated_original_info(info);
308
309   std::string output;
310   bool result = data.SerializePartialToString(&output);
311   ASSERT_TRUE(result);
312
313   // base64 encode the output.
314   std::string encoded;
315   base::Base64Encode(output, &encoded);
316   bookmark_model_->SetNodeMetaInfo(node, "stars.imageData", encoded);
317
318   GURL url;
319   int width;
320   int height;
321   result = model_->GetOriginalImage(node, &url, &width, &height);
322   ASSERT_FALSE(result);
323 }
324
325 TEST_F(EnhancedBookmarkModelTest, TestEncodeDecode) {
326   const BookmarkNode* node = AddBookmark();
327
328   bool result =
329       model_->SetOriginalImage(node, GURL("http://example.com/i.jpg"), 22, 33);
330   ASSERT_TRUE(result);
331
332   GURL url;
333   int width;
334   int height;
335   result = model_->GetOriginalImage(node, &url, &width, &height);
336   ASSERT_TRUE(result);
337   EXPECT_EQ(url, GURL("http://example.com/i.jpg"));
338   EXPECT_EQ(width, 22);
339   EXPECT_EQ(height, 33);
340   EXPECT_EQ("v1.0", GetVersion(node));
341 }
342
343 TEST_F(EnhancedBookmarkModelTest, TestDoubleEncodeDecode) {
344   const BookmarkNode* node = AddBookmark();
345
346   // Encode some information.
347   bool result =
348       model_->SetOriginalImage(node, GURL("http://example.com/i.jpg"), 22, 33);
349   ASSERT_TRUE(result);
350   // Encode some different information.
351   result =
352       model_->SetOriginalImage(node, GURL("http://example.com/i.jpg"), 33, 44);
353   ASSERT_TRUE(result);
354
355   GURL url;
356   int width;
357   int height;
358   result = model_->GetOriginalImage(node, &url, &width, &height);
359   ASSERT_TRUE(result);
360   EXPECT_EQ(url, GURL("http://example.com/i.jpg"));
361   EXPECT_EQ(width, 33);
362   EXPECT_EQ(height, 44);
363   EXPECT_EQ("v1.0", GetVersion(node));
364 }
365
366 TEST_F(EnhancedBookmarkModelTest, TestRemoteId) {
367   const BookmarkNode* node = AddBookmark();
368   // Verify that the remote id starts with the correct prefix.
369   EXPECT_TRUE(StartsWithASCII(model_->GetRemoteId(node), "ebc_", true));
370
371   // Getting the remote id for nodes that don't have them should return the
372   // empty string.
373   const BookmarkNode* existing_node =
374       bookmark_model_->AddURL(bookmark_model_->other_node(),
375                               0,
376                               base::ASCIIToUTF16("Title"),
377                               GURL(GURL(BOOKMARK_URL)));
378   EXPECT_TRUE(model_->GetRemoteId(existing_node).empty());
379
380   // Folder nodes should not have a remote id set on creation.
381   const BookmarkNode* folder_node = AddFolder();
382   EXPECT_TRUE(model_->GetRemoteId(folder_node).empty());
383 }
384
385 TEST_F(EnhancedBookmarkModelTest, TestEmptyDescription) {
386   const BookmarkNode* node = AddBookmark();
387
388   std::string description(model_->GetDescription(node));
389   EXPECT_EQ(description, "");
390 }
391
392 TEST_F(EnhancedBookmarkModelTest, TestDescription) {
393   const BookmarkNode* node = AddBookmark();
394   const std::string description("This is the most useful description of all.");
395
396   // Set the description.
397   model_->SetDescription(node, description);
398
399   // Check the description is the one that was set.
400   EXPECT_EQ(model_->GetDescription(node), description);
401   EXPECT_EQ("v1.0", GetVersion(node));
402 }
403
404 // If there is no notes field, the description should fall back on the snippet.
405 TEST_F(EnhancedBookmarkModelTest, TestDescriptionFallback) {
406   const BookmarkNode* node = AddBookmark();
407
408   // Binary serialize the protobuf.
409   image::collections::PageData data;
410   data.set_snippet("Joe Bar Team");
411   ASSERT_TRUE(data.IsInitialized());
412   std::string output;
413   bool result = data.SerializeToString(&output);
414   ASSERT_TRUE(result);
415
416   // base64 encode the output.
417   std::string encoded;
418   base::Base64Encode(output, &encoded);
419   bookmark_model_->SetNodeMetaInfo(node, "stars.pageData", encoded);
420
421   // The snippet is used as the description.
422   std::string snippet(model_->GetSnippet(node));
423   EXPECT_EQ("Joe Bar Team", model_->GetDescription(node));
424
425   // Set the description.
426   const std::string description("This is the most useful description of all.");
427   model_->SetDescription(node, description);
428
429   // Check the description is the one that was set.
430   EXPECT_EQ(model_->GetDescription(node), description);
431 }
432
433 // Makes sure that the stars.version field is set every time
434 // EnhancedBookmarkModel makes a change to a node.
435 TEST_F(EnhancedBookmarkModelTest, TestVersionField) {
436   const BookmarkNode* node = AddBookmark();
437   EXPECT_EQ("", GetVersion(node));
438
439   model_->SetDescription(node, "foo");
440   EXPECT_EQ("v1.0", GetVersion(node));
441
442   // Add a suffix to the version to set.
443   model_->SetVersionSuffix("alpha");
444
445   model_->SetDescription(node, "foo");
446   // Since the description didn't actually change, the version field should
447   // not either.
448   EXPECT_EQ("v1.0", GetVersion(node));
449
450   model_->SetDescription(node, "bar");
451   EXPECT_EQ("v1.0/alpha", GetVersion(node));
452 }
453
454 // Verifies that duplicate nodes are reset when the model is created.
455 TEST_F(EnhancedBookmarkModelTest, ResetDuplicateNodesOnInitialization) {
456   model_->Shutdown();
457
458   const BookmarkNode* parent = bookmark_model_->other_node();
459   const BookmarkNode* node1 = bookmark_model_->AddURL(
460       parent, 0, base::ASCIIToUTF16("Some title"), GURL(BOOKMARK_URL));
461   const BookmarkNode* node2 = bookmark_model_->AddURL(
462       parent, 0, base::ASCIIToUTF16("Some title"), GURL(BOOKMARK_URL));
463   const BookmarkNode* node3 = bookmark_model_->AddURL(
464       parent, 0, base::ASCIIToUTF16("Some title"), GURL(BOOKMARK_URL));
465   const BookmarkNode* node4 = bookmark_model_->AddURL(
466       parent, 0, base::ASCIIToUTF16("Some title"), GURL(BOOKMARK_URL));
467
468   bookmark_model_->SetNodeMetaInfo(node1, "stars.id", "c_1");
469   bookmark_model_->SetNodeMetaInfo(node2, "stars.id", "c_2");
470   bookmark_model_->SetNodeMetaInfo(node3, "stars.id", "c_1");
471   bookmark_model_->SetNodeMetaInfo(node4, "stars.id", "c_1");
472   EXPECT_EQ("c_1", GetId(node1));
473   EXPECT_EQ("c_2", GetId(node2));
474   EXPECT_EQ("c_1", GetId(node3));
475   EXPECT_EQ("c_1", GetId(node4));
476
477   model_.reset(new EnhancedBookmarkModel(bookmark_model_.get(), "v2.0"));
478   base::RunLoop().RunUntilIdle();
479   EXPECT_EQ("c_2", GetId(node2));
480   EXPECT_EQ("", GetId(node1));
481   EXPECT_EQ("", GetId(node3));
482   EXPECT_EQ("", GetId(node4));
483   EXPECT_EQ("c_1", GetOldId(node1));
484   EXPECT_EQ("c_1", GetOldId(node3));
485   EXPECT_EQ("c_1", GetOldId(node4));
486   EXPECT_EQ("v2.0", GetVersion(node1));
487   EXPECT_EQ("v2.0", GetVersion(node3));
488   EXPECT_EQ("v2.0", GetVersion(node4));
489 }
490
491 // Verifies that duplicate nodes are reset if one is created.
492 TEST_F(EnhancedBookmarkModelTest, ResetDuplicateAddedNodes) {
493   BookmarkNode::MetaInfoMap meta_info;
494   meta_info["stars.id"] = "c_1";
495   const BookmarkNode* parent = bookmark_model_->other_node();
496
497   const BookmarkNode* node1 =
498       bookmark_model_->AddURLWithCreationTimeAndMetaInfo(
499           parent,
500           0,
501           base::ASCIIToUTF16("Some title"),
502           GURL(BOOKMARK_URL),
503           base::Time::Now(),
504           &meta_info);
505   EXPECT_EQ("c_1", GetId(node1));
506
507   const BookmarkNode* node2 =
508       bookmark_model_->AddURLWithCreationTimeAndMetaInfo(
509           parent,
510           0,
511           base::ASCIIToUTF16("Some title"),
512           GURL(BOOKMARK_URL),
513           base::Time::Now(),
514           &meta_info);
515
516   base::RunLoop().RunUntilIdle();
517   EXPECT_EQ("", GetId(node1));
518   EXPECT_EQ("", GetId(node2));
519   EXPECT_EQ("c_1", GetOldId(node1));
520   EXPECT_EQ("c_1", GetOldId(node2));
521   EXPECT_EQ("v1.0", GetVersion(node1));
522   EXPECT_EQ("v1.0", GetVersion(node2));
523 }
524
525 // Verifies that duplicate nodes are reset if an id is changed to a duplicate
526 // value.
527 TEST_F(EnhancedBookmarkModelTest, ResetDuplicateChangedNodes) {
528   const BookmarkNode* node1 = AddBookmark();
529   const BookmarkNode* node2 = AddBookmark();
530
531   bookmark_model_->SetNodeMetaInfo(node1, "stars.id", "c_1");
532   EXPECT_EQ("c_1", GetId(node1));
533
534   bookmark_model_->SetNodeMetaInfo(node2, "stars.id", "c_1");
535   base::RunLoop().RunUntilIdle();
536   EXPECT_EQ("", GetId(node1));
537   EXPECT_EQ("", GetId(node2));
538   EXPECT_EQ("c_1", GetOldId(node1));
539   EXPECT_EQ("c_1", GetOldId(node2));
540   EXPECT_EQ("v1.0", GetVersion(node1));
541   EXPECT_EQ("v1.0", GetVersion(node2));
542 }
543
544 TEST_F(EnhancedBookmarkModelTest, SetMultipleMetaInfo) {
545   const BookmarkNode* node = AddBookmark();
546   BookmarkNode::MetaInfoMap meta_info;
547   meta_info["a"] = "aa";
548   meta_info["b"] = "bb";
549
550   model_->SetVersionSuffix("1");
551   model_->SetMultipleMetaInfo(node, meta_info);
552   EXPECT_EQ("aa", GetMetaInfoField(node, "a"));
553   EXPECT_EQ("bb", GetMetaInfoField(node, "b"));
554   EXPECT_EQ("v1.0/1", GetVersion(node));
555
556   // Not present fields does not erase the fields already set on the node.
557   meta_info["a"] = "aaa";
558   model_->SetVersionSuffix("2");
559   model_->SetMultipleMetaInfo(node, meta_info);
560   EXPECT_EQ("aaa", GetMetaInfoField(node, "a"));
561   EXPECT_EQ("bb", GetMetaInfoField(node, "b"));
562   EXPECT_EQ("v1.0/2", GetVersion(node));
563
564   // Not actually changing any values should not set the version field.
565   model_->SetVersionSuffix("3");
566   model_->SetMultipleMetaInfo(node, meta_info);
567   EXPECT_EQ("v1.0/2", GetVersion(node));
568 }
569
570 TEST_F(EnhancedBookmarkModelTest, ObserverShuttingDownEvent) {
571   EXPECT_EQ(0, shutting_down_calls_);
572   model_->Shutdown();
573   EXPECT_EQ(1, shutting_down_calls_);
574   model_.reset();
575 }
576
577 TEST_F(EnhancedBookmarkModelTest, ObserverNodeAddedEvent) {
578   EXPECT_EQ(0, added_calls_);
579   const BookmarkNode* node = AddBookmark();
580   EXPECT_EQ(1, added_calls_);
581   EXPECT_EQ(node, last_added_);
582
583   const BookmarkNode* folder = AddFolder();
584   EXPECT_EQ(2, added_calls_);
585   EXPECT_EQ(folder, last_added_);
586 }
587
588 TEST_F(EnhancedBookmarkModelTest, ObserverNodeRemovedEvent) {
589   const BookmarkNode* node = AddBookmark();
590   const BookmarkNode* folder = AddFolder();
591
592   EXPECT_EQ(0, removed_calls_);
593   bookmark_model_->Remove(node->parent(), node->parent()->GetIndexOf(node));
594   EXPECT_EQ(1, removed_calls_);
595   EXPECT_EQ(node, last_removed_);
596
597   bookmark_model_->Remove(folder->parent(),
598                           folder->parent()->GetIndexOf(folder));
599   EXPECT_EQ(2, removed_calls_);
600   EXPECT_EQ(folder, last_removed_);
601 }
602
603 TEST_F(EnhancedBookmarkModelTest, ObserverNodeChangedEvent) {
604   const BookmarkNode* node = AddBookmark();
605
606   EXPECT_EQ(0, changed_calls_);
607   bookmark_model_->SetTitle(node, base::ASCIIToUTF16("New Title"));
608   EXPECT_EQ(1, changed_calls_);
609   EXPECT_EQ(node, last_changed_);
610 }
611
612 TEST_F(EnhancedBookmarkModelTest, ObserverAllUserNodesRemovedEvent) {
613   AddBookmark();
614   AddFolder();
615   EXPECT_EQ(0, all_user_nodes_removed_calls_);
616   bookmark_model_->RemoveAllUserBookmarks();
617   EXPECT_EQ(0, removed_calls_);
618   EXPECT_EQ(1, all_user_nodes_removed_calls_);
619 }
620
621 TEST_F(EnhancedBookmarkModelTest, ObserverRemoteIdChangedEvent) {
622   const BookmarkNode* node1 = AddFolder();
623   const BookmarkNode* node2 = AddFolder();
624
625   EXPECT_EQ(0, remote_id_changed_calls_);
626   bookmark_model_->SetNodeMetaInfo(node1, "stars.id", "c_1");
627   base::RunLoop().RunUntilIdle();
628   EXPECT_EQ(1, remote_id_changed_calls_);
629   EXPECT_EQ(node1, last_remote_id_node_);
630   EXPECT_EQ("", last_old_remote_id_);
631   EXPECT_EQ("c_1", last_remote_id_);
632
633   bookmark_model_->SetNodeMetaInfo(node2, "stars.id", "c_2");
634   base::RunLoop().RunUntilIdle();
635   EXPECT_EQ(2, remote_id_changed_calls_);
636   EXPECT_EQ(node2, last_remote_id_node_);
637   EXPECT_EQ("", last_old_remote_id_);
638   EXPECT_EQ("c_2", last_remote_id_);
639
640   bookmark_model_->SetNodeMetaInfo(node1, "stars.id", "c_3");
641   base::RunLoop().RunUntilIdle();
642   EXPECT_EQ(3, remote_id_changed_calls_);
643   EXPECT_EQ(node1, last_remote_id_node_);
644   EXPECT_EQ("c_1", last_old_remote_id_);
645   EXPECT_EQ("c_3", last_remote_id_);
646
647   // Set to duplicate ids.
648   bookmark_model_->SetNodeMetaInfo(node2, "stars.id", "c_3");
649   EXPECT_EQ(4, remote_id_changed_calls_);
650   EXPECT_EQ(node2, last_remote_id_node_);
651   EXPECT_EQ("c_2", last_old_remote_id_);
652   EXPECT_EQ("c_3", last_remote_id_);
653   base::RunLoop().RunUntilIdle();
654   EXPECT_EQ(6, remote_id_changed_calls_);
655   EXPECT_EQ("", last_remote_id_);
656 }
657
658 TEST_F(EnhancedBookmarkModelTest, ShutDownWhileResetDuplicationScheduled) {
659   const BookmarkNode* node1 = AddBookmark();
660   const BookmarkNode* node2 = AddBookmark();
661   bookmark_model_->SetNodeMetaInfo(node1, "stars.id", "c_1");
662   bookmark_model_->SetNodeMetaInfo(node2, "stars.id", "c_1");
663   model_->Shutdown();
664   model_.reset();
665   base::RunLoop().RunUntilIdle();
666 }
667
668 TEST_F(EnhancedBookmarkModelTest, NodeRemovedWhileResetDuplicationScheduled) {
669   const BookmarkNode* node1 = AddBookmark();
670   const BookmarkNode* node2 = AddBookmark();
671   bookmark_model_->SetNodeMetaInfo(node1, "stars.id", "c_1");
672   bookmark_model_->SetNodeMetaInfo(node2, "stars.id", "c_1");
673   bookmark_model_->Remove(node1->parent(), node1->parent()->GetIndexOf(node1));
674   base::RunLoop().RunUntilIdle();
675 }
676
677 // Verifies that the NEEDS_OFFLINE_PROCESSING flag is set for nodes added
678 // with no remote id.
679 TEST_F(EnhancedBookmarkModelTest, BookmarkAddedSetsOfflineProcessingFlag) {
680   const BookmarkNode* node =
681       bookmark_model_->AddURL(bookmark_model_->other_node(),
682                               0,
683                               base::ASCIIToUTF16("Some title"),
684                               GURL(BOOKMARK_URL));
685   std::string flags_str;
686   EXPECT_FALSE(node->GetMetaInfo("stars.flags", &flags_str));
687   base::RunLoop().RunUntilIdle();
688   ASSERT_TRUE(node->GetMetaInfo("stars.flags", &flags_str));
689   int flags;
690   ASSERT_TRUE(base::StringToInt(flags_str, &flags));
691   EXPECT_EQ(1, (flags & 1));
692 }
693
694 // Verifies that the NEEDS_OFFLINE_PROCESSING_FLAG is not set for added folders.
695 TEST_F(EnhancedBookmarkModelTest, FolderAddedDoesNotSetOfflineProcessingFlag) {
696   const BookmarkNode* node = AddFolder();
697   base::RunLoop().RunUntilIdle();
698
699   std::string flags_str;
700   if (node->GetMetaInfo("stars.flags", &flags_str)) {
701     int flags;
702     ASSERT_TRUE(base::StringToInt(flags_str, &flags));
703     EXPECT_EQ(0, (flags & 1));
704   }
705 }
706
707 // Verifies that when a bookmark is added that has a remote id, the status of
708 // the NEEDS_OFFLINE_PROCESSING flag doesn't change.
709 TEST_F(EnhancedBookmarkModelTest,
710        BookmarkAddedWithIdKeepsOfflineProcessingFlag) {
711   BookmarkNode::MetaInfoMap meta_info;
712   meta_info["stars.id"] = "some_id";
713   meta_info["stars.flags"] = "1";
714
715   const BookmarkNode* node1 =
716       bookmark_model_->AddURLWithCreationTimeAndMetaInfo(
717           bookmark_model_->other_node(),
718           0,
719           base::ASCIIToUTF16("Some title"),
720           GURL(BOOKMARK_URL),
721           base::Time::Now(),
722           &meta_info);
723   base::RunLoop().RunUntilIdle();
724   std::string flags_str;
725   ASSERT_TRUE(node1->GetMetaInfo("stars.flags", &flags_str));
726   int flags;
727   ASSERT_TRUE(base::StringToInt(flags_str, &flags));
728   EXPECT_EQ(1, (flags & 1));
729
730   meta_info["stars.flags"] = "0";
731   const BookmarkNode* node2 =
732       bookmark_model_->AddURLWithCreationTimeAndMetaInfo(
733           bookmark_model_->other_node(),
734           0,
735           base::ASCIIToUTF16("Some title"),
736           GURL(BOOKMARK_URL),
737           base::Time::Now(),
738           &meta_info);
739   base::RunLoop().RunUntilIdle();
740   ASSERT_TRUE(node2->GetMetaInfo("stars.flags", &flags_str));
741   ASSERT_TRUE(base::StringToInt(flags_str, &flags));
742   EXPECT_EQ(0, (flags & 1));
743 }
744
745 TEST_F(EnhancedBookmarkModelTest,
746        NodeRemovedWhileSetNeedsOfflineProcessingIsScheduled) {
747   const BookmarkNode* node =
748       bookmark_model_->AddURL(bookmark_model_->other_node(),
749                               0,
750                               base::ASCIIToUTF16("Some title"),
751                               GURL(BOOKMARK_URL));
752   bookmark_model_->Remove(node->parent(), node->parent()->GetIndexOf(node));
753   base::RunLoop().RunUntilIdle();
754 }
755
756 TEST_F(EnhancedBookmarkModelTest,
757        RemoveParentShouldRemoveChildrenFromMaps) {
758   const BookmarkNode* parent = AddFolder();
759   const BookmarkNode* node = AddBookmark("Title", parent);
760   std::string remote_id = GetId(node);
761   EXPECT_EQ(node, model_->BookmarkForRemoteId(remote_id));
762
763   const BookmarkNode* gp = parent->parent();
764   bookmark_model_->Remove(gp, gp->GetIndexOf(parent));
765   EXPECT_FALSE(model_->BookmarkForRemoteId(remote_id));
766 }