Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // TODO(akalin): This file is basically just a unit test for | 5 // TODO(akalin): This file is basically just a unit test for |
| 6 // BookmarkChangeProcessor. Write unit tests for | 6 // BookmarkChangeProcessor. Write unit tests for |
| 7 // BookmarkModelAssociator separately. | 7 // BookmarkModelAssociator separately. |
| 8 | 8 |
| 9 #include <stack> | 9 #include <stack> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 #include "chrome/browser/sync/test/engine/test_user_share.h" | 35 #include "chrome/browser/sync/test/engine/test_user_share.h" |
| 36 #include "chrome/common/chrome_switches.h" | 36 #include "chrome/common/chrome_switches.h" |
| 37 #include "chrome/test/base/testing_profile.h" | 37 #include "chrome/test/base/testing_profile.h" |
| 38 #include "content/test/test_browser_thread.h" | 38 #include "content/test/test_browser_thread.h" |
| 39 #include "sync/test/engine/test_id_factory.h" | 39 #include "sync/test/engine/test_id_factory.h" |
| 40 #include "testing/gmock/include/gmock/gmock.h" | 40 #include "testing/gmock/include/gmock/gmock.h" |
| 41 #include "testing/gtest/include/gtest/gtest.h" | 41 #include "testing/gtest/include/gtest/gtest.h" |
| 42 | 42 |
| 43 namespace browser_sync { | 43 namespace browser_sync { |
| 44 | 44 |
| 45 using content::BrowserThread; | |
| 46 using sync_api::BaseNode; | |
|
Nicolas Zea
2012/04/19 23:55:43
same here
| |
| 45 using testing::_; | 47 using testing::_; |
| 46 using testing::InvokeWithoutArgs; | 48 using testing::InvokeWithoutArgs; |
| 47 using testing::Mock; | 49 using testing::Mock; |
| 48 using testing::StrictMock; | 50 using testing::StrictMock; |
| 49 using content::BrowserThread; | |
| 50 | 51 |
| 51 class TestBookmarkModelAssociator : public BookmarkModelAssociator { | 52 class TestBookmarkModelAssociator : public BookmarkModelAssociator { |
| 52 public: | 53 public: |
| 53 TestBookmarkModelAssociator( | 54 TestBookmarkModelAssociator( |
| 54 BookmarkModel* bookmark_model, | 55 BookmarkModel* bookmark_model, |
| 55 sync_api::UserShare* user_share, | 56 sync_api::UserShare* user_share, |
| 56 DataTypeErrorHandler* error_handler) | 57 DataTypeErrorHandler* error_handler) |
| 57 : BookmarkModelAssociator(bookmark_model, user_share, | 58 : BookmarkModelAssociator(bookmark_model, user_share, |
| 58 error_handler, | 59 error_handler, |
| 59 true /* expect_mobile_bookmarks_folder */), | 60 true /* expect_mobile_bookmarks_folder */), |
| 60 user_share_(user_share) {} | 61 user_share_(user_share) {} |
| 61 | 62 |
| 62 // TODO(akalin): This logic lazily creates any tagged node that is | 63 // TODO(akalin): This logic lazily creates any tagged node that is |
| 63 // requested. A better way would be to have utility functions to | 64 // requested. A better way would be to have utility functions to |
| 64 // create sync nodes from some bookmark structure and to use that. | 65 // create sync nodes from some bookmark structure and to use that. |
| 65 virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id) { | 66 virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id) { |
| 66 std::string tag_str = std::string(tag.c_str(), tag.length()); | 67 std::string tag_str = std::string(tag.c_str(), tag.length()); |
| 67 bool root_exists = false; | 68 bool root_exists = false; |
| 68 syncable::ModelType type = model_type(); | 69 syncable::ModelType type = model_type(); |
| 69 { | 70 { |
| 70 sync_api::WriteTransaction trans(FROM_HERE, user_share_); | 71 sync_api::WriteTransaction trans(FROM_HERE, user_share_); |
| 71 sync_api::ReadNode uber_root(&trans); | 72 sync_api::ReadNode uber_root(&trans); |
| 72 uber_root.InitByRootLookup(); | 73 uber_root.InitByRootLookup(); |
| 73 | 74 |
| 74 sync_api::ReadNode root(&trans); | 75 sync_api::ReadNode root(&trans); |
| 75 root_exists = root.InitByTagLookup( | 76 root_exists = root.InitByTagLookup( |
| 76 ProfileSyncServiceTestHelper::GetTagForType(type)); | 77 ProfileSyncServiceTestHelper::GetTagForType(type)) == |
| 78 BaseNode::INIT_OK; | |
| 77 } | 79 } |
| 78 | 80 |
| 79 if (!root_exists) { | 81 if (!root_exists) { |
| 80 bool created = ProfileSyncServiceTestHelper::CreateRoot( | 82 bool created = ProfileSyncServiceTestHelper::CreateRoot( |
| 81 type, | 83 type, |
| 82 user_share_, | 84 user_share_, |
| 83 &id_factory_); | 85 &id_factory_); |
| 84 if (!created) | 86 if (!created) |
| 85 return false; | 87 return false; |
| 86 } | 88 } |
| 87 | 89 |
| 88 sync_api::WriteTransaction trans(FROM_HERE, user_share_); | 90 sync_api::WriteTransaction trans(FROM_HERE, user_share_); |
| 89 sync_api::ReadNode root(&trans); | 91 sync_api::ReadNode root(&trans); |
| 90 EXPECT_TRUE(root.InitByTagLookup( | 92 EXPECT_EQ(BaseNode::INIT_OK, root.InitByTagLookup( |
| 91 ProfileSyncServiceTestHelper::GetTagForType(type))); | 93 ProfileSyncServiceTestHelper::GetTagForType(type))); |
| 92 | 94 |
| 93 // First, try to find a node with the title among the root's children. | 95 // First, try to find a node with the title among the root's children. |
| 94 // This will be the case if we are testing model persistence, and | 96 // This will be the case if we are testing model persistence, and |
| 95 // are reloading a sync repository created earlier in the test. | 97 // are reloading a sync repository created earlier in the test. |
| 96 int64 last_child_id = sync_api::kInvalidId; | 98 int64 last_child_id = sync_api::kInvalidId; |
| 97 for (int64 id = root.GetFirstChildId(); id != sync_api::kInvalidId; /***/) { | 99 for (int64 id = root.GetFirstChildId(); id != sync_api::kInvalidId; /***/) { |
| 98 sync_api::ReadNode child(&trans); | 100 sync_api::ReadNode child(&trans); |
| 99 child.InitByIdLookup(id); | 101 EXPECT_EQ(BaseNode::INIT_OK, child.InitByIdLookup(id)); |
| 100 last_child_id = id; | 102 last_child_id = id; |
| 101 if (tag_str == child.GetTitle()) { | 103 if (tag_str == child.GetTitle()) { |
| 102 *sync_id = id; | 104 *sync_id = id; |
| 103 return true; | 105 return true; |
| 104 } | 106 } |
| 105 id = child.GetSuccessorId(); | 107 id = child.GetSuccessorId(); |
| 106 } | 108 } |
| 107 | 109 |
| 108 sync_api::ReadNode predecessor_node(&trans); | 110 sync_api::ReadNode predecessor_node(&trans); |
| 109 sync_api::ReadNode* predecessor = NULL; | 111 sync_api::ReadNode* predecessor = NULL; |
| 110 if (last_child_id != sync_api::kInvalidId) { | 112 if (last_child_id != sync_api::kInvalidId) { |
| 111 predecessor_node.InitByIdLookup(last_child_id); | 113 EXPECT_EQ(BaseNode::INIT_OK, |
| 114 predecessor_node.InitByIdLookup(last_child_id)); | |
| 112 predecessor = &predecessor_node; | 115 predecessor = &predecessor_node; |
| 113 } | 116 } |
| 114 sync_api::WriteNode node(&trans); | 117 sync_api::WriteNode node(&trans); |
| 115 // Create new fake tagged nodes at the end of the ordering. | 118 // Create new fake tagged nodes at the end of the ordering. |
| 116 node.InitByCreation(type, root, predecessor); | 119 node.InitByCreation(type, root, predecessor); |
| 117 node.SetIsFolder(true); | 120 node.SetIsFolder(true); |
| 118 node.entry_->Put(syncable::UNIQUE_SERVER_TAG, tag); | 121 node.entry_->Put(syncable::UNIQUE_SERVER_TAG, tag); |
| 119 node.SetTitle(UTF8ToWide(tag_str)); | 122 node.SetTitle(UTF8ToWide(tag_str)); |
| 120 node.SetExternalId(0); | 123 node.SetExternalId(0); |
| 121 *sync_id = node.GetId(); | 124 *sync_id = node.GetId(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 140 explicit FakeServerChange(sync_api::WriteTransaction* trans) : trans_(trans) { | 143 explicit FakeServerChange(sync_api::WriteTransaction* trans) : trans_(trans) { |
| 141 } | 144 } |
| 142 | 145 |
| 143 // Pretend that the server told the syncer to add a bookmark object. | 146 // Pretend that the server told the syncer to add a bookmark object. |
| 144 int64 Add(const std::wstring& title, | 147 int64 Add(const std::wstring& title, |
| 145 const std::string& url, | 148 const std::string& url, |
| 146 bool is_folder, | 149 bool is_folder, |
| 147 int64 parent_id, | 150 int64 parent_id, |
| 148 int64 predecessor_id) { | 151 int64 predecessor_id) { |
| 149 sync_api::ReadNode parent(trans_); | 152 sync_api::ReadNode parent(trans_); |
| 150 EXPECT_TRUE(parent.InitByIdLookup(parent_id)); | 153 EXPECT_EQ(BaseNode::INIT_OK, parent.InitByIdLookup(parent_id)); |
| 151 sync_api::WriteNode node(trans_); | 154 sync_api::WriteNode node(trans_); |
| 152 if (predecessor_id == 0) { | 155 if (predecessor_id == 0) { |
| 153 EXPECT_TRUE(node.InitByCreation(syncable::BOOKMARKS, parent, NULL)); | 156 EXPECT_TRUE(node.InitByCreation(syncable::BOOKMARKS, parent, NULL)); |
| 154 } else { | 157 } else { |
| 155 sync_api::ReadNode predecessor(trans_); | 158 sync_api::ReadNode predecessor(trans_); |
| 156 EXPECT_TRUE(predecessor.InitByIdLookup(predecessor_id)); | 159 EXPECT_EQ(BaseNode::INIT_OK, predecessor.InitByIdLookup(predecessor_id)); |
| 157 EXPECT_EQ(predecessor.GetParentId(), parent.GetId()); | 160 EXPECT_EQ(predecessor.GetParentId(), parent.GetId()); |
| 158 EXPECT_TRUE(node.InitByCreation(syncable::BOOKMARKS, parent, | 161 EXPECT_TRUE(node.InitByCreation(syncable::BOOKMARKS, parent, |
| 159 &predecessor)); | 162 &predecessor)); |
| 160 } | 163 } |
| 161 EXPECT_EQ(node.GetPredecessorId(), predecessor_id); | 164 EXPECT_EQ(node.GetPredecessorId(), predecessor_id); |
| 162 EXPECT_EQ(node.GetParentId(), parent_id); | 165 EXPECT_EQ(node.GetParentId(), parent_id); |
| 163 node.SetIsFolder(is_folder); | 166 node.SetIsFolder(is_folder); |
| 164 node.SetTitle(title); | 167 node.SetTitle(title); |
| 165 if (!is_folder) | 168 if (!is_folder) |
| 166 node.SetURL(GURL(url)); | 169 node.SetURL(GURL(url)); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 184 int64 parent_id, | 187 int64 parent_id, |
| 185 int64 predecessor_id) { | 188 int64 predecessor_id) { |
| 186 return Add(title, url, false, parent_id, predecessor_id); | 189 return Add(title, url, false, parent_id, predecessor_id); |
| 187 } | 190 } |
| 188 | 191 |
| 189 // Pretend that the server told the syncer to delete an object. | 192 // Pretend that the server told the syncer to delete an object. |
| 190 void Delete(int64 id) { | 193 void Delete(int64 id) { |
| 191 { | 194 { |
| 192 // Delete the sync node. | 195 // Delete the sync node. |
| 193 sync_api::WriteNode node(trans_); | 196 sync_api::WriteNode node(trans_); |
| 194 EXPECT_TRUE(node.InitByIdLookup(id)); | 197 EXPECT_EQ(BaseNode::INIT_OK, node.InitByIdLookup(id)); |
| 195 EXPECT_FALSE(node.GetFirstChildId()); | 198 EXPECT_FALSE(node.GetFirstChildId()); |
| 196 node.Remove(); | 199 node.Remove(); |
| 197 } | 200 } |
| 198 { | 201 { |
| 199 // Verify the deletion. | 202 // Verify the deletion. |
| 200 sync_api::ReadNode node(trans_); | 203 sync_api::ReadNode node(trans_); |
| 201 EXPECT_FALSE(node.InitByIdLookup(id)); | 204 EXPECT_EQ(BaseNode::INIT_FAILED_ENTRY_IS_DEL, node.InitByIdLookup(id)); |
| 202 } | 205 } |
| 203 | 206 |
| 204 sync_api::ChangeRecord record; | 207 sync_api::ChangeRecord record; |
| 205 record.action = sync_api::ChangeRecord::ACTION_DELETE; | 208 record.action = sync_api::ChangeRecord::ACTION_DELETE; |
| 206 record.id = id; | 209 record.id = id; |
| 207 // Deletions are always first in the changelist, but we can't actually do | 210 // Deletions are always first in the changelist, but we can't actually do |
| 208 // WriteNode::Remove() on the node until its children are moved. So, as | 211 // WriteNode::Remove() on the node until its children are moved. So, as |
| 209 // a practical matter, users of FakeServerChange must move or delete | 212 // a practical matter, users of FakeServerChange must move or delete |
| 210 // children before parents. Thus, we must insert the deletion record | 213 // children before parents. Thus, we must insert the deletion record |
| 211 // at the front of the vector. | 214 // at the front of the vector. |
| 212 changes_.insert(changes_.begin(), record); | 215 changes_.insert(changes_.begin(), record); |
| 213 } | 216 } |
| 214 | 217 |
| 215 // Set a new title value, and return the old value. | 218 // Set a new title value, and return the old value. |
| 216 std::wstring ModifyTitle(int64 id, const std::wstring& new_title) { | 219 std::wstring ModifyTitle(int64 id, const std::wstring& new_title) { |
| 217 sync_api::WriteNode node(trans_); | 220 sync_api::WriteNode node(trans_); |
| 218 EXPECT_TRUE(node.InitByIdLookup(id)); | 221 EXPECT_EQ(BaseNode::INIT_OK, node.InitByIdLookup(id)); |
| 219 std::string old_title = node.GetTitle(); | 222 std::string old_title = node.GetTitle(); |
| 220 node.SetTitle(new_title); | 223 node.SetTitle(new_title); |
| 221 SetModified(id); | 224 SetModified(id); |
| 222 return UTF8ToWide(old_title); | 225 return UTF8ToWide(old_title); |
| 223 } | 226 } |
| 224 | 227 |
| 225 // Set a new parent and predecessor value. Return the old parent id. | 228 // Set a new parent and predecessor value. Return the old parent id. |
| 226 // We could return the old predecessor id, but it turns out not to be | 229 // We could return the old predecessor id, but it turns out not to be |
| 227 // very useful for assertions. | 230 // very useful for assertions. |
| 228 int64 ModifyPosition(int64 id, int64 parent_id, int64 predecessor_id) { | 231 int64 ModifyPosition(int64 id, int64 parent_id, int64 predecessor_id) { |
| 229 sync_api::ReadNode parent(trans_); | 232 sync_api::ReadNode parent(trans_); |
| 230 EXPECT_TRUE(parent.InitByIdLookup(parent_id)); | 233 EXPECT_EQ(BaseNode::INIT_OK, parent.InitByIdLookup(parent_id)); |
| 231 sync_api::WriteNode node(trans_); | 234 sync_api::WriteNode node(trans_); |
| 232 EXPECT_TRUE(node.InitByIdLookup(id)); | 235 EXPECT_EQ(BaseNode::INIT_OK, node.InitByIdLookup(id)); |
| 233 int64 old_parent_id = node.GetParentId(); | 236 int64 old_parent_id = node.GetParentId(); |
| 234 if (predecessor_id == 0) { | 237 if (predecessor_id == 0) { |
| 235 EXPECT_TRUE(node.SetPosition(parent, NULL)); | 238 EXPECT_TRUE(node.SetPosition(parent, NULL)); |
| 236 } else { | 239 } else { |
| 237 sync_api::ReadNode predecessor(trans_); | 240 sync_api::ReadNode predecessor(trans_); |
| 238 EXPECT_TRUE(predecessor.InitByIdLookup(predecessor_id)); | 241 EXPECT_EQ(BaseNode::INIT_OK, predecessor.InitByIdLookup(predecessor_id)); |
| 239 EXPECT_EQ(predecessor.GetParentId(), parent.GetId()); | 242 EXPECT_EQ(predecessor.GetParentId(), parent.GetId()); |
| 240 EXPECT_TRUE(node.SetPosition(parent, &predecessor)); | 243 EXPECT_TRUE(node.SetPosition(parent, &predecessor)); |
| 241 } | 244 } |
| 242 SetModified(id); | 245 SetModified(id); |
| 243 return old_parent_id; | 246 return old_parent_id; |
| 244 } | 247 } |
| 245 | 248 |
| 246 // Pass the fake change list to |service|. | 249 // Pass the fake change list to |service|. |
| 247 void ApplyPendingChanges(ChangeProcessor* processor) { | 250 void ApplyPendingChanges(ChangeProcessor* processor) { |
| 248 processor->ApplyChangesFromSyncModel( | 251 processor->ApplyChangesFromSyncModel( |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 std::stack<int64> stack; | 508 std::stack<int64> stack; |
| 506 stack.push(bookmark_bar_id()); | 509 stack.push(bookmark_bar_id()); |
| 507 while (!stack.empty()) { | 510 while (!stack.empty()) { |
| 508 int64 id = stack.top(); | 511 int64 id = stack.top(); |
| 509 stack.pop(); | 512 stack.pop(); |
| 510 if (!id) continue; | 513 if (!id) continue; |
| 511 | 514 |
| 512 ExpectBrowserNodeMatching(trans, id); | 515 ExpectBrowserNodeMatching(trans, id); |
| 513 | 516 |
| 514 sync_api::ReadNode gnode(trans); | 517 sync_api::ReadNode gnode(trans); |
| 515 ASSERT_TRUE(gnode.InitByIdLookup(id)); | 518 ASSERT_EQ(BaseNode::INIT_OK, gnode.InitByIdLookup(id)); |
| 516 stack.push(gnode.GetFirstChildId()); | 519 stack.push(gnode.GetFirstChildId()); |
| 517 stack.push(gnode.GetSuccessorId()); | 520 stack.push(gnode.GetSuccessorId()); |
| 518 } | 521 } |
| 519 } | 522 } |
| 520 | 523 |
| 521 void ExpectModelMatch() { | 524 void ExpectModelMatch() { |
| 522 sync_api::ReadTransaction trans(FROM_HERE, test_user_share_.user_share()); | 525 sync_api::ReadTransaction trans(FROM_HERE, test_user_share_.user_share()); |
| 523 ExpectModelMatch(&trans); | 526 ExpectModelMatch(&trans); |
| 524 } | 527 } |
| 525 | 528 |
| (...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1486 EXPECT_EQ(1, observer.get_started()); | 1489 EXPECT_EQ(1, observer.get_started()); |
| 1487 EXPECT_EQ(0, observer.get_completed_count_at_started()); | 1490 EXPECT_EQ(0, observer.get_completed_count_at_started()); |
| 1488 EXPECT_EQ(1, observer.get_completed()); | 1491 EXPECT_EQ(1, observer.get_completed()); |
| 1489 | 1492 |
| 1490 model_->RemoveObserver(&observer); | 1493 model_->RemoveObserver(&observer); |
| 1491 } | 1494 } |
| 1492 | 1495 |
| 1493 } // namespace | 1496 } // namespace |
| 1494 | 1497 |
| 1495 } // namespace browser_sync | 1498 } // namespace browser_sync |
| OLD | NEW |