Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6475)

Unified Diff: chrome/browser/undo/bookmark_undo_service_test.cc

Issue 19287013: Bookmark Undo service for multiple level undo/redo of bookmarks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/undo/bookmark_undo_service_test.cc
diff --git a/chrome/browser/undo/bookmark_undo_service_test.cc b/chrome/browser/undo/bookmark_undo_service_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..80f130811a8719901b6c91a3265027f535e0f3a6
--- /dev/null
+++ b/chrome/browser/undo/bookmark_undo_service_test.cc
@@ -0,0 +1,369 @@
+// Copyright 2013 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 "chrome/browser/undo/bookmark_undo_service.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/bookmarks/bookmark_model.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/undo/bookmark_undo_service_factory.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class BookmarkUndoServiceTest : public testing::Test {
+ public:
+ BookmarkUndoServiceTest();
+
+ virtual void SetUp() OVERRIDE;
+ virtual void TearDown() OVERRIDE;
+
+ BookmarkModel* GetModel();
+ BookmarkUndoService* GetUndoService();
+
+ private:
+ scoped_ptr<TestingProfile> profile_;
+ content::TestBrowserThreadBundle thread_bundle_;
+
+ DISALLOW_COPY_AND_ASSIGN(BookmarkUndoServiceTest);
+};
+
+BookmarkUndoServiceTest::BookmarkUndoServiceTest() {}
+
+void BookmarkUndoServiceTest::SetUp() {
+ profile_.reset(new TestingProfile);
+ profile_->CreateBookmarkModel(true);
+ ui_test_utils::WaitForBookmarkModelToLoad(GetModel());
+}
+
+BookmarkModel* BookmarkUndoServiceTest::GetModel() {
+ return BookmarkModelFactory::GetForProfile(profile_.get());
+}
+
+BookmarkUndoService* BookmarkUndoServiceTest::GetUndoService() {
+ return BookmarkUndoServiceFactory::GetForProfile(profile_.get());
+}
+
+void BookmarkUndoServiceTest::TearDown() {
+ profile_.reset(NULL);
+}
+
+TEST_F(BookmarkUndoServiceTest, AddBookmark) {
+ BookmarkModel* model = GetModel();
+ BookmarkUndoService* undo_service = GetUndoService();
+
+ const BookmarkNode* parent = model->other_node();
+ model->AddURL(parent, 0, ASCIIToUTF16("foo"), GURL("http://www.bar.com"));
+
+ // Undo bookmark creation and test for no bookmarks.
+ undo_service->undo_manager()->Undo();
+ EXPECT_EQ(0, model->other_node()->child_count());
+
+ // Redo bookmark creation and ensure bookmark information is valid.
+ undo_service->undo_manager()->Redo();
+ const BookmarkNode* node = parent->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo"));
+ EXPECT_EQ(node->url(), GURL("http://www.bar.com"));
+}
+
+// Test that a bookmark removal action can be undone and redone.
+TEST_F(BookmarkUndoServiceTest, UndoBookmarkRemove) {
+ BookmarkModel* model = GetModel();
+ BookmarkUndoService* undo_service = GetUndoService();
+
+ const BookmarkNode* parent = model->other_node();
+ model->AddURL(parent, 0, ASCIIToUTF16("foo"), GURL("http://www.bar.com"));
+ model->Remove(parent, 0);
+
+ EXPECT_EQ(2U, undo_service->undo_manager()->undo_count());
+ EXPECT_EQ(0U, undo_service->undo_manager()->redo_count());
+
+ // Undo the deletion of the only bookmark and check the bookmark values.
+ undo_service->undo_manager()->Undo();
+ EXPECT_EQ(1, model->other_node()->child_count());
+ const BookmarkNode* node = parent->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo"));
+ EXPECT_EQ(node->url(), GURL("http://www.bar.com"));
+
+ EXPECT_EQ(1U, undo_service->undo_manager()->undo_count());
+ EXPECT_EQ(1U, undo_service->undo_manager()->redo_count());
+
+ // Redo the deletion and check that there are no bookmarks left.
+ undo_service->undo_manager()->Redo();
+ EXPECT_EQ(0, model->other_node()->child_count());
+
+ EXPECT_EQ(2U, undo_service->undo_manager()->undo_count());
+ EXPECT_EQ(0U, undo_service->undo_manager()->redo_count());
+}
+
+// Ensure the undo/redo works for editing of bookmark information grouped into
+// one action.
+TEST_F(BookmarkUndoServiceTest, UndoBookmarkGroupedAction) {
+ BookmarkModel* model = GetModel();
+ BookmarkUndoService* undo_service = GetUndoService();
+
+ const BookmarkNode* n1 = model->AddURL(model->other_node(),
+ 0,
+ ASCIIToUTF16("foo"),
+ GURL("http://www.foo.com"));
+ undo_service->undo_manager()->StartGroupingActions();
+ model->SetTitle(n1, ASCIIToUTF16("bar"));
+ model->SetURL(n1, GURL("http://www.bar.com"));
+ undo_service->undo_manager()->EndGroupingActions();
+
+ EXPECT_EQ(2U, undo_service->undo_manager()->undo_count());
+ EXPECT_EQ(0U, undo_service->undo_manager()->redo_count());
+
+ // Undo the modification of the bookmark and check for the original values.
+ undo_service->undo_manager()->Undo();
+ EXPECT_EQ(1, model->other_node()->child_count());
+ const BookmarkNode* node = model->other_node()->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo"));
+ EXPECT_EQ(node->url(), GURL("http://www.foo.com"));
+
+ // Redo the modifications and ensure the newer values are present.
+ undo_service->undo_manager()->Redo();
+ EXPECT_EQ(1, model->other_node()->child_count());
+ node = model->other_node()->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar"));
+ EXPECT_EQ(node->url(), GURL("http://www.bar.com"));
+
+ EXPECT_EQ(2U, undo_service->undo_manager()->undo_count());
+ EXPECT_EQ(0U, undo_service->undo_manager()->redo_count());
+}
+
+// Test moving bookmarks within a folder and between folders.
+TEST_F(BookmarkUndoServiceTest, UndoBookmarkMoveWithinFolder) {
+ BookmarkModel* model = GetModel();
+ BookmarkUndoService* undo_service = GetUndoService();
+
+ const BookmarkNode* n1 = model->AddURL(model->other_node(),
+ 0,
+ ASCIIToUTF16("foo"),
+ GURL("http://www.foo.com"));
+ const BookmarkNode* n2 = model->AddURL(model->other_node(),
+ 1,
+ ASCIIToUTF16("moo"),
+ GURL("http://www.moo.com"));
+ const BookmarkNode* n3 = model->AddURL(model->other_node(),
+ 2,
+ ASCIIToUTF16("bar"),
+ GURL("http://www.bar.com"));
+ model->Move(n1, model->other_node(), 3);
+
+ // Undo the move and check that the nodes are in order.
+ undo_service->undo_manager()->Undo();
+ EXPECT_EQ(model->other_node()->GetChild(0), n1);
+ EXPECT_EQ(model->other_node()->GetChild(1), n2);
+ EXPECT_EQ(model->other_node()->GetChild(2), n3);
+
+ // Redo the move and check that the first node is in the last position.
+ undo_service->undo_manager()->Redo();
+ EXPECT_EQ(model->other_node()->GetChild(0), n2);
+ EXPECT_EQ(model->other_node()->GetChild(1), n3);
+ EXPECT_EQ(model->other_node()->GetChild(2), n1);
+}
+
+// Test undo of a bookmark moved to a different folder.
+TEST_F(BookmarkUndoServiceTest, UndoBookmarkMoveToOtherFolder) {
+ BookmarkModel* model = GetModel();
+ BookmarkUndoService* undo_service = GetUndoService();
+
+ const BookmarkNode* n1 = model->AddURL(model->other_node(),
+ 0,
+ ASCIIToUTF16("foo"),
+ GURL("http://www.foo.com"));
+ const BookmarkNode* n2 = model->AddURL(model->other_node(),
+ 1,
+ ASCIIToUTF16("moo"),
+ GURL("http://www.moo.com"));
+ const BookmarkNode* n3 = model->AddURL(model->other_node(),
+ 2,
+ ASCIIToUTF16("bar"),
+ GURL("http://www.bar.com"));
+ const BookmarkNode* f1 =
+ model->AddFolder(model->other_node(), 3, ASCIIToUTF16("folder"));
+ model->Move(n3, f1, 0);
+
+ // Undo the move and check that the bookmark and folder are in place.
+ undo_service->undo_manager()->Undo();
+ ASSERT_EQ(4, model->other_node()->child_count());
+ EXPECT_EQ(model->other_node()->GetChild(0), n1);
+ EXPECT_EQ(model->other_node()->GetChild(1), n2);
+ EXPECT_EQ(model->other_node()->GetChild(2), n3);
+ EXPECT_EQ(model->other_node()->GetChild(3), f1);
+ EXPECT_EQ(0, f1->child_count());
+
+ // Redo the move back into the folder and check validity.
+ undo_service->undo_manager()->Redo();
+ ASSERT_EQ(3, model->other_node()->child_count());
+ EXPECT_EQ(model->other_node()->GetChild(0), n1);
+ EXPECT_EQ(model->other_node()->GetChild(1), n2);
+ EXPECT_EQ(model->other_node()->GetChild(2), f1);
+ ASSERT_EQ(1, f1->child_count());
+ EXPECT_EQ(f1->GetChild(0), n3);
+}
+
+// Tests the handling of multiple modifications that include renumbering of the
+// bookmark identifiers.
+TEST_F(BookmarkUndoServiceTest, UndoBookmarkRenameDelete) {
+ BookmarkModel* model = GetModel();
+ BookmarkUndoService* undo_service = GetUndoService();
+
+ const BookmarkNode* f1 = model->AddFolder(model->other_node(),
+ 0,
+ ASCIIToUTF16("folder"));
+ model->AddURL(f1, 0, ASCIIToUTF16("foo"), GURL("http://www.foo.com"));
+ model->SetTitle(f1, ASCIIToUTF16("Renamed"));
+ model->Remove(model->other_node(), 0);
+
+ // Undo the folder removal and ensure the folder and bookmark were restored.
+ undo_service->undo_manager()->Undo();
+ ASSERT_EQ(1, model->other_node()->child_count());
+ ASSERT_EQ(1, model->other_node()->GetChild(0)->child_count());
+ const BookmarkNode* node = model->other_node()->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("Renamed"));
+
+ node = model->other_node()->GetChild(0)->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo"));
+ EXPECT_EQ(node->url(), GURL("http://www.foo.com"));
+
+ // Undo the title change and ensure the folder was updated even though the
+ // id has changed.
+ undo_service->undo_manager()->Undo();
+ node = model->other_node()->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("folder"));
+
+ // Undo bookmark creation and test for removal of bookmark.
+ undo_service->undo_manager()->Undo();
+ ASSERT_EQ(0, model->other_node()->GetChild(0)->child_count());
+
+ // Undo folder creation and confirm the bookmark model is empty.
+ undo_service->undo_manager()->Undo();
+ ASSERT_EQ(0, model->other_node()->child_count());
+
+ // Redo all the actions and ensure the folder and bookmark are restored.
+ undo_service->undo_manager()->Redo(); // folder creation
+ undo_service->undo_manager()->Redo(); // bookmark creation
+ undo_service->undo_manager()->Redo(); // bookmark title change
+ ASSERT_EQ(1, model->other_node()->child_count());
+ ASSERT_EQ(1, model->other_node()->GetChild(0)->child_count());
+ node = model->other_node()->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("Renamed"));
+ node = model->other_node()->GetChild(0)->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo"));
+ EXPECT_EQ(node->url(), GURL("http://www.foo.com"));
+
+ undo_service->undo_manager()->Redo(); // folder deletion
+ EXPECT_EQ(0, model->other_node()->child_count());
+}
+
+// Test the undo of SortChildren and ReorderChildren.
+TEST_F(BookmarkUndoServiceTest, UndoBookmarkReorder) {
+ BookmarkModel* model = GetModel();
+ BookmarkUndoService* undo_service = GetUndoService();
+
+ const BookmarkNode* parent = model->other_node();
+ model->AddURL(parent, 0, ASCIIToUTF16("foo"), GURL("http://www.foo.com"));
+ model->AddURL(parent, 1, ASCIIToUTF16("moo"), GURL("http://www.moo.com"));
+ model->AddURL(parent, 2, ASCIIToUTF16("bar"), GURL("http://www.bar.com"));
+ model->SortChildren(parent);
+
+ // Test the undo of SortChildren.
+ undo_service->undo_manager()->Undo();
+ const BookmarkNode* node = parent->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo"));
+ EXPECT_EQ(node->url(), GURL("http://www.foo.com"));
+
+ node = parent->GetChild(1);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("moo"));
+ EXPECT_EQ(node->url(), GURL("http://www.moo.com"));
+
+ node = parent->GetChild(2);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar"));
+ EXPECT_EQ(node->url(), GURL("http://www.bar.com"));
+
+ // Test the redo of SortChildren.
+ undo_service->undo_manager()->Redo();
+ node = parent->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar"));
+ EXPECT_EQ(node->url(), GURL("http://www.bar.com"));
+
+ node = parent->GetChild(1);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo"));
+ EXPECT_EQ(node->url(), GURL("http://www.foo.com"));
+
+ node = parent->GetChild(2);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("moo"));
+ EXPECT_EQ(node->url(), GURL("http://www.moo.com"));
+
+}
+
+TEST_F(BookmarkUndoServiceTest, UndoBookmarkRemoveAll) {
+ BookmarkModel* model = GetModel();
+ BookmarkUndoService* undo_service = GetUndoService();
+
+ // Setup bookmarks in the Other Bookmarks and the Bookmark Bar.
+ const BookmarkNode* new_folder;
+ const BookmarkNode* parent = model->other_node();
+ model->AddURL(parent, 0, ASCIIToUTF16("foo"), GURL("http://www.google.com"));
+ new_folder= model->AddFolder(parent, 1, ASCIIToUTF16("folder"));
+ model->AddURL(new_folder, 0, ASCIIToUTF16("bar"), GURL("http://www.bar.com"));
+
+ parent = model->bookmark_bar_node();
+ model->AddURL(parent, 0, ASCIIToUTF16("a"), GURL("http://www.a.com"));
+ new_folder = model->AddFolder(parent, 1, ASCIIToUTF16("folder"));
+ model->AddURL(new_folder, 0, ASCIIToUTF16("b"), GURL("http://www.b.com"));
+
+ model->RemoveAll();
+
+ // Test that the undo of RemoveAll restores all folders and bookmarks.
+ undo_service->undo_manager()->Undo();
+
+ ASSERT_EQ(2, model->other_node()->child_count());
+ EXPECT_EQ(1, model->other_node()->GetChild(1)->child_count());
+ const BookmarkNode* node = model->other_node()->GetChild(1)->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar"));
+ EXPECT_EQ(node->url(), GURL("http://www.bar.com"));
+
+ ASSERT_EQ(2, model->bookmark_bar_node()->child_count());
+ EXPECT_EQ(1, model->bookmark_bar_node()->GetChild(1)->child_count());
+ node = model->bookmark_bar_node()->GetChild(1)->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("b"));
+ EXPECT_EQ(node->url(), GURL("http://www.b.com"));
+
+ // Test that the redo removes all folders and bookmarks.
+ undo_service->undo_manager()->Redo();
+ EXPECT_EQ(0, model->other_node()->child_count());
+ EXPECT_EQ(0, model->bookmark_bar_node()->child_count());
+}
+
+TEST_F(BookmarkUndoServiceTest, TestUpperLimit) {
+ BookmarkModel* model = GetModel();
+ BookmarkUndoService* undo_service = GetUndoService();
+
+ // This maximum is set in undo_manager.cc
+ const size_t kMaxUndoGroups = 100;
+
+ const BookmarkNode* parent = model->other_node();
+ model->AddURL(parent, 0, ASCIIToUTF16("foo"), GURL("http://www.foo.com"));
+ for (size_t i = 1; i < kMaxUndoGroups + 1; ++i)
+ model->AddURL(parent, i, ASCIIToUTF16("bar"), GURL("http://www.bar.com"));
+
+ EXPECT_EQ(kMaxUndoGroups, undo_service->undo_manager()->undo_count());
+
+ // Undo as many operations as possible.
+ while (undo_service->undo_manager()->undo_count())
+ undo_service->undo_manager()->Undo();
+
+ EXPECT_EQ(1, parent->child_count());
+ const BookmarkNode* node = model->other_node()->GetChild(0);
+ EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo"));
+ EXPECT_EQ(node->url(), GURL("http://www.foo.com"));
+}
+
+} // namespace

Powered by Google App Engine
This is Rietveld 408576698