OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 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 "chrome/browser/undo/bookmark_undo_service.h" |
| 6 |
| 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 9 #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
| 10 #include "chrome/browser/undo/bookmark_undo_service_factory.h" |
| 11 #include "chrome/test/base/testing_profile.h" |
| 12 #include "chrome/test/base/ui_test_utils.h" |
| 13 #include "content/public/test/test_browser_thread_bundle.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 |
| 16 namespace { |
| 17 |
| 18 class BookmarkUndoServiceTest : public testing::Test { |
| 19 public: |
| 20 BookmarkUndoServiceTest(); |
| 21 |
| 22 virtual void SetUp() OVERRIDE; |
| 23 virtual void TearDown() OVERRIDE; |
| 24 |
| 25 BookmarkModel* GetModel(); |
| 26 BookmarkUndoService* GetUndoService(); |
| 27 |
| 28 private: |
| 29 scoped_ptr<TestingProfile> profile_; |
| 30 content::TestBrowserThreadBundle thread_bundle_; |
| 31 |
| 32 DISALLOW_COPY_AND_ASSIGN(BookmarkUndoServiceTest); |
| 33 }; |
| 34 |
| 35 BookmarkUndoServiceTest::BookmarkUndoServiceTest() {} |
| 36 |
| 37 void BookmarkUndoServiceTest::SetUp() { |
| 38 profile_.reset(new TestingProfile); |
| 39 profile_->CreateBookmarkModel(true); |
| 40 ui_test_utils::WaitForBookmarkModelToLoad(GetModel()); |
| 41 } |
| 42 |
| 43 BookmarkModel* BookmarkUndoServiceTest::GetModel() { |
| 44 return BookmarkModelFactory::GetForProfile(profile_.get()); |
| 45 } |
| 46 |
| 47 BookmarkUndoService* BookmarkUndoServiceTest::GetUndoService() { |
| 48 return BookmarkUndoServiceFactory::GetForProfile(profile_.get()); |
| 49 } |
| 50 |
| 51 void BookmarkUndoServiceTest::TearDown() { |
| 52 profile_.reset(NULL); |
| 53 } |
| 54 |
| 55 TEST_F(BookmarkUndoServiceTest, AddBookmark) { |
| 56 BookmarkModel* model = GetModel(); |
| 57 BookmarkUndoService* undo_service = GetUndoService(); |
| 58 |
| 59 const BookmarkNode* parent = model->other_node(); |
| 60 model->AddURL(parent, 0, ASCIIToUTF16("foo"), GURL("http://www.bar.com")); |
| 61 |
| 62 // Undo bookmark creation and test for no bookmarks. |
| 63 undo_service->undo_manager()->Undo(); |
| 64 EXPECT_EQ(0, model->other_node()->child_count()); |
| 65 |
| 66 // Redo bookmark creation and ensure bookmark information is valid. |
| 67 undo_service->undo_manager()->Redo(); |
| 68 const BookmarkNode* node = parent->GetChild(0); |
| 69 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); |
| 70 EXPECT_EQ(node->url(), GURL("http://www.bar.com")); |
| 71 } |
| 72 |
| 73 // Test that a bookmark removal action can be undone and redone. |
| 74 TEST_F(BookmarkUndoServiceTest, UndoBookmarkRemove) { |
| 75 BookmarkModel* model = GetModel(); |
| 76 BookmarkUndoService* undo_service = GetUndoService(); |
| 77 |
| 78 const BookmarkNode* parent = model->other_node(); |
| 79 model->AddURL(parent, 0, ASCIIToUTF16("foo"), GURL("http://www.bar.com")); |
| 80 model->Remove(parent, 0); |
| 81 |
| 82 EXPECT_EQ(2U, undo_service->undo_manager()->undo_count()); |
| 83 EXPECT_EQ(0U, undo_service->undo_manager()->redo_count()); |
| 84 |
| 85 // Undo the deletion of the only bookmark and check the bookmark values. |
| 86 undo_service->undo_manager()->Undo(); |
| 87 EXPECT_EQ(1, model->other_node()->child_count()); |
| 88 const BookmarkNode* node = parent->GetChild(0); |
| 89 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); |
| 90 EXPECT_EQ(node->url(), GURL("http://www.bar.com")); |
| 91 |
| 92 EXPECT_EQ(1U, undo_service->undo_manager()->undo_count()); |
| 93 EXPECT_EQ(1U, undo_service->undo_manager()->redo_count()); |
| 94 |
| 95 // Redo the deletion and check that there are no bookmarks left. |
| 96 undo_service->undo_manager()->Redo(); |
| 97 EXPECT_EQ(0, model->other_node()->child_count()); |
| 98 |
| 99 EXPECT_EQ(2U, undo_service->undo_manager()->undo_count()); |
| 100 EXPECT_EQ(0U, undo_service->undo_manager()->redo_count()); |
| 101 } |
| 102 |
| 103 // Ensure the undo/redo works for editing of bookmark information grouped into |
| 104 // one action. |
| 105 TEST_F(BookmarkUndoServiceTest, UndoBookmarkGroupedAction) { |
| 106 BookmarkModel* model = GetModel(); |
| 107 BookmarkUndoService* undo_service = GetUndoService(); |
| 108 |
| 109 const BookmarkNode* n1 = model->AddURL(model->other_node(), |
| 110 0, |
| 111 ASCIIToUTF16("foo"), |
| 112 GURL("http://www.foo.com")); |
| 113 undo_service->undo_manager()->StartGroupingActions(); |
| 114 model->SetTitle(n1, ASCIIToUTF16("bar")); |
| 115 model->SetURL(n1, GURL("http://www.bar.com")); |
| 116 undo_service->undo_manager()->EndGroupingActions(); |
| 117 |
| 118 EXPECT_EQ(2U, undo_service->undo_manager()->undo_count()); |
| 119 EXPECT_EQ(0U, undo_service->undo_manager()->redo_count()); |
| 120 |
| 121 // Undo the modification of the bookmark and check for the original values. |
| 122 undo_service->undo_manager()->Undo(); |
| 123 EXPECT_EQ(1, model->other_node()->child_count()); |
| 124 const BookmarkNode* node = model->other_node()->GetChild(0); |
| 125 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); |
| 126 EXPECT_EQ(node->url(), GURL("http://www.foo.com")); |
| 127 |
| 128 // Redo the modifications and ensure the newer values are present. |
| 129 undo_service->undo_manager()->Redo(); |
| 130 EXPECT_EQ(1, model->other_node()->child_count()); |
| 131 node = model->other_node()->GetChild(0); |
| 132 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar")); |
| 133 EXPECT_EQ(node->url(), GURL("http://www.bar.com")); |
| 134 |
| 135 EXPECT_EQ(2U, undo_service->undo_manager()->undo_count()); |
| 136 EXPECT_EQ(0U, undo_service->undo_manager()->redo_count()); |
| 137 } |
| 138 |
| 139 // Test moving bookmarks within a folder and between folders. |
| 140 TEST_F(BookmarkUndoServiceTest, UndoBookmarkMoveWithinFolder) { |
| 141 BookmarkModel* model = GetModel(); |
| 142 BookmarkUndoService* undo_service = GetUndoService(); |
| 143 |
| 144 const BookmarkNode* n1 = model->AddURL(model->other_node(), |
| 145 0, |
| 146 ASCIIToUTF16("foo"), |
| 147 GURL("http://www.foo.com")); |
| 148 const BookmarkNode* n2 = model->AddURL(model->other_node(), |
| 149 1, |
| 150 ASCIIToUTF16("moo"), |
| 151 GURL("http://www.moo.com")); |
| 152 const BookmarkNode* n3 = model->AddURL(model->other_node(), |
| 153 2, |
| 154 ASCIIToUTF16("bar"), |
| 155 GURL("http://www.bar.com")); |
| 156 model->Move(n1, model->other_node(), 3); |
| 157 |
| 158 // Undo the move and check that the nodes are in order. |
| 159 undo_service->undo_manager()->Undo(); |
| 160 EXPECT_EQ(model->other_node()->GetChild(0), n1); |
| 161 EXPECT_EQ(model->other_node()->GetChild(1), n2); |
| 162 EXPECT_EQ(model->other_node()->GetChild(2), n3); |
| 163 |
| 164 // Redo the move and check that the first node is in the last position. |
| 165 undo_service->undo_manager()->Redo(); |
| 166 EXPECT_EQ(model->other_node()->GetChild(0), n2); |
| 167 EXPECT_EQ(model->other_node()->GetChild(1), n3); |
| 168 EXPECT_EQ(model->other_node()->GetChild(2), n1); |
| 169 } |
| 170 |
| 171 // Test undo of a bookmark moved to a different folder. |
| 172 TEST_F(BookmarkUndoServiceTest, UndoBookmarkMoveToOtherFolder) { |
| 173 BookmarkModel* model = GetModel(); |
| 174 BookmarkUndoService* undo_service = GetUndoService(); |
| 175 |
| 176 const BookmarkNode* n1 = model->AddURL(model->other_node(), |
| 177 0, |
| 178 ASCIIToUTF16("foo"), |
| 179 GURL("http://www.foo.com")); |
| 180 const BookmarkNode* n2 = model->AddURL(model->other_node(), |
| 181 1, |
| 182 ASCIIToUTF16("moo"), |
| 183 GURL("http://www.moo.com")); |
| 184 const BookmarkNode* n3 = model->AddURL(model->other_node(), |
| 185 2, |
| 186 ASCIIToUTF16("bar"), |
| 187 GURL("http://www.bar.com")); |
| 188 const BookmarkNode* f1 = |
| 189 model->AddFolder(model->other_node(), 3, ASCIIToUTF16("folder")); |
| 190 model->Move(n3, f1, 0); |
| 191 |
| 192 // Undo the move and check that the bookmark and folder are in place. |
| 193 undo_service->undo_manager()->Undo(); |
| 194 ASSERT_EQ(4, model->other_node()->child_count()); |
| 195 EXPECT_EQ(model->other_node()->GetChild(0), n1); |
| 196 EXPECT_EQ(model->other_node()->GetChild(1), n2); |
| 197 EXPECT_EQ(model->other_node()->GetChild(2), n3); |
| 198 EXPECT_EQ(model->other_node()->GetChild(3), f1); |
| 199 EXPECT_EQ(0, f1->child_count()); |
| 200 |
| 201 // Redo the move back into the folder and check validity. |
| 202 undo_service->undo_manager()->Redo(); |
| 203 ASSERT_EQ(3, model->other_node()->child_count()); |
| 204 EXPECT_EQ(model->other_node()->GetChild(0), n1); |
| 205 EXPECT_EQ(model->other_node()->GetChild(1), n2); |
| 206 EXPECT_EQ(model->other_node()->GetChild(2), f1); |
| 207 ASSERT_EQ(1, f1->child_count()); |
| 208 EXPECT_EQ(f1->GetChild(0), n3); |
| 209 } |
| 210 |
| 211 // Tests the handling of multiple modifications that include renumbering of the |
| 212 // bookmark identifiers. |
| 213 TEST_F(BookmarkUndoServiceTest, UndoBookmarkRenameDelete) { |
| 214 BookmarkModel* model = GetModel(); |
| 215 BookmarkUndoService* undo_service = GetUndoService(); |
| 216 |
| 217 const BookmarkNode* f1 = model->AddFolder(model->other_node(), |
| 218 0, |
| 219 ASCIIToUTF16("folder")); |
| 220 model->AddURL(f1, 0, ASCIIToUTF16("foo"), GURL("http://www.foo.com")); |
| 221 model->SetTitle(f1, ASCIIToUTF16("Renamed")); |
| 222 model->Remove(model->other_node(), 0); |
| 223 |
| 224 // Undo the folder removal and ensure the folder and bookmark were restored. |
| 225 undo_service->undo_manager()->Undo(); |
| 226 ASSERT_EQ(1, model->other_node()->child_count()); |
| 227 ASSERT_EQ(1, model->other_node()->GetChild(0)->child_count()); |
| 228 const BookmarkNode* node = model->other_node()->GetChild(0); |
| 229 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("Renamed")); |
| 230 |
| 231 node = model->other_node()->GetChild(0)->GetChild(0); |
| 232 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); |
| 233 EXPECT_EQ(node->url(), GURL("http://www.foo.com")); |
| 234 |
| 235 // Undo the title change and ensure the folder was updated even though the |
| 236 // id has changed. |
| 237 undo_service->undo_manager()->Undo(); |
| 238 node = model->other_node()->GetChild(0); |
| 239 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("folder")); |
| 240 |
| 241 // Undo bookmark creation and test for removal of bookmark. |
| 242 undo_service->undo_manager()->Undo(); |
| 243 ASSERT_EQ(0, model->other_node()->GetChild(0)->child_count()); |
| 244 |
| 245 // Undo folder creation and confirm the bookmark model is empty. |
| 246 undo_service->undo_manager()->Undo(); |
| 247 ASSERT_EQ(0, model->other_node()->child_count()); |
| 248 |
| 249 // Redo all the actions and ensure the folder and bookmark are restored. |
| 250 undo_service->undo_manager()->Redo(); // folder creation |
| 251 undo_service->undo_manager()->Redo(); // bookmark creation |
| 252 undo_service->undo_manager()->Redo(); // bookmark title change |
| 253 ASSERT_EQ(1, model->other_node()->child_count()); |
| 254 ASSERT_EQ(1, model->other_node()->GetChild(0)->child_count()); |
| 255 node = model->other_node()->GetChild(0); |
| 256 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("Renamed")); |
| 257 node = model->other_node()->GetChild(0)->GetChild(0); |
| 258 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); |
| 259 EXPECT_EQ(node->url(), GURL("http://www.foo.com")); |
| 260 |
| 261 undo_service->undo_manager()->Redo(); // folder deletion |
| 262 EXPECT_EQ(0, model->other_node()->child_count()); |
| 263 } |
| 264 |
| 265 // Test the undo of SortChildren and ReorderChildren. |
| 266 TEST_F(BookmarkUndoServiceTest, UndoBookmarkReorder) { |
| 267 BookmarkModel* model = GetModel(); |
| 268 BookmarkUndoService* undo_service = GetUndoService(); |
| 269 |
| 270 const BookmarkNode* parent = model->other_node(); |
| 271 model->AddURL(parent, 0, ASCIIToUTF16("foo"), GURL("http://www.foo.com")); |
| 272 model->AddURL(parent, 1, ASCIIToUTF16("moo"), GURL("http://www.moo.com")); |
| 273 model->AddURL(parent, 2, ASCIIToUTF16("bar"), GURL("http://www.bar.com")); |
| 274 model->SortChildren(parent); |
| 275 |
| 276 // Test the undo of SortChildren. |
| 277 undo_service->undo_manager()->Undo(); |
| 278 const BookmarkNode* node = parent->GetChild(0); |
| 279 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); |
| 280 EXPECT_EQ(node->url(), GURL("http://www.foo.com")); |
| 281 |
| 282 node = parent->GetChild(1); |
| 283 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("moo")); |
| 284 EXPECT_EQ(node->url(), GURL("http://www.moo.com")); |
| 285 |
| 286 node = parent->GetChild(2); |
| 287 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar")); |
| 288 EXPECT_EQ(node->url(), GURL("http://www.bar.com")); |
| 289 |
| 290 // Test the redo of SortChildren. |
| 291 undo_service->undo_manager()->Redo(); |
| 292 node = parent->GetChild(0); |
| 293 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar")); |
| 294 EXPECT_EQ(node->url(), GURL("http://www.bar.com")); |
| 295 |
| 296 node = parent->GetChild(1); |
| 297 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); |
| 298 EXPECT_EQ(node->url(), GURL("http://www.foo.com")); |
| 299 |
| 300 node = parent->GetChild(2); |
| 301 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("moo")); |
| 302 EXPECT_EQ(node->url(), GURL("http://www.moo.com")); |
| 303 |
| 304 } |
| 305 |
| 306 TEST_F(BookmarkUndoServiceTest, UndoBookmarkRemoveAll) { |
| 307 BookmarkModel* model = GetModel(); |
| 308 BookmarkUndoService* undo_service = GetUndoService(); |
| 309 |
| 310 // Setup bookmarks in the Other Bookmarks and the Bookmark Bar. |
| 311 const BookmarkNode* new_folder; |
| 312 const BookmarkNode* parent = model->other_node(); |
| 313 model->AddURL(parent, 0, ASCIIToUTF16("foo"), GURL("http://www.google.com")); |
| 314 new_folder= model->AddFolder(parent, 1, ASCIIToUTF16("folder")); |
| 315 model->AddURL(new_folder, 0, ASCIIToUTF16("bar"), GURL("http://www.bar.com")); |
| 316 |
| 317 parent = model->bookmark_bar_node(); |
| 318 model->AddURL(parent, 0, ASCIIToUTF16("a"), GURL("http://www.a.com")); |
| 319 new_folder = model->AddFolder(parent, 1, ASCIIToUTF16("folder")); |
| 320 model->AddURL(new_folder, 0, ASCIIToUTF16("b"), GURL("http://www.b.com")); |
| 321 |
| 322 model->RemoveAll(); |
| 323 |
| 324 // Test that the undo of RemoveAll restores all folders and bookmarks. |
| 325 undo_service->undo_manager()->Undo(); |
| 326 |
| 327 ASSERT_EQ(2, model->other_node()->child_count()); |
| 328 EXPECT_EQ(1, model->other_node()->GetChild(1)->child_count()); |
| 329 const BookmarkNode* node = model->other_node()->GetChild(1)->GetChild(0); |
| 330 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar")); |
| 331 EXPECT_EQ(node->url(), GURL("http://www.bar.com")); |
| 332 |
| 333 ASSERT_EQ(2, model->bookmark_bar_node()->child_count()); |
| 334 EXPECT_EQ(1, model->bookmark_bar_node()->GetChild(1)->child_count()); |
| 335 node = model->bookmark_bar_node()->GetChild(1)->GetChild(0); |
| 336 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("b")); |
| 337 EXPECT_EQ(node->url(), GURL("http://www.b.com")); |
| 338 |
| 339 // Test that the redo removes all folders and bookmarks. |
| 340 undo_service->undo_manager()->Redo(); |
| 341 EXPECT_EQ(0, model->other_node()->child_count()); |
| 342 EXPECT_EQ(0, model->bookmark_bar_node()->child_count()); |
| 343 } |
| 344 |
| 345 TEST_F(BookmarkUndoServiceTest, TestUpperLimit) { |
| 346 BookmarkModel* model = GetModel(); |
| 347 BookmarkUndoService* undo_service = GetUndoService(); |
| 348 |
| 349 // This maximum is set in undo_manager.cc |
| 350 const size_t kMaxUndoGroups = 100; |
| 351 |
| 352 const BookmarkNode* parent = model->other_node(); |
| 353 model->AddURL(parent, 0, ASCIIToUTF16("foo"), GURL("http://www.foo.com")); |
| 354 for (size_t i = 1; i < kMaxUndoGroups + 1; ++i) |
| 355 model->AddURL(parent, i, ASCIIToUTF16("bar"), GURL("http://www.bar.com")); |
| 356 |
| 357 EXPECT_EQ(kMaxUndoGroups, undo_service->undo_manager()->undo_count()); |
| 358 |
| 359 // Undo as many operations as possible. |
| 360 while (undo_service->undo_manager()->undo_count()) |
| 361 undo_service->undo_manager()->Undo(); |
| 362 |
| 363 EXPECT_EQ(1, parent->child_count()); |
| 364 const BookmarkNode* node = model->other_node()->GetChild(0); |
| 365 EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); |
| 366 EXPECT_EQ(node->url(), GURL("http://www.foo.com")); |
| 367 } |
| 368 |
| 369 } // namespace |
OLD | NEW |