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; |
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 |