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

Side by Side Diff: components/reading_list/ios/reading_list_store_unittest.cc

Issue 2764533002: Reading List iOS: Use external clock in ReadingListEntry. (Closed)
Patch Set: fix microseconds Created 3 years, 9 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 #include "components/reading_list/ios/reading_list_store.h" 5 #include "components/reading_list/ios/reading_list_store.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h" 13 #include "base/run_loop.h"
14 #import "base/test/ios/wait_util.h" 14 #include "base/test/simple_test_clock.h"
15 #include "components/reading_list/ios/reading_list_model_impl.h" 15 #include "components/reading_list/ios/reading_list_model_impl.h"
16 #include "components/sync/model/fake_model_type_change_processor.h" 16 #include "components/sync/model/fake_model_type_change_processor.h"
17 #include "components/sync/model/model_type_store_test_util.h" 17 #include "components/sync/model/model_type_store_test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
19 19
20 namespace {
21
20 // Tests that the transition from |entryA| to |entryB| is possible (|possible| 22 // Tests that the transition from |entryA| to |entryB| is possible (|possible|
21 // is true) or not. 23 // is true) or not.
22 void ExpectAB(const sync_pb::ReadingListSpecifics& entryA, 24 void ExpectAB(const sync_pb::ReadingListSpecifics& entryA,
23 const sync_pb::ReadingListSpecifics& entryB, 25 const sync_pb::ReadingListSpecifics& entryB,
24 bool possible) { 26 bool possible) {
25 EXPECT_EQ(ReadingListStore::CompareEntriesForSync(entryA, entryB), possible); 27 EXPECT_EQ(ReadingListStore::CompareEntriesForSync(entryA, entryB), possible);
26 std::unique_ptr<ReadingListEntry> a = 28 std::unique_ptr<ReadingListEntry> a =
27 ReadingListEntry::FromReadingListSpecifics(entryA); 29 ReadingListEntry::FromReadingListSpecifics(entryA,
30 base::Time::FromTimeT(10));
28 std::unique_ptr<ReadingListEntry> b = 31 std::unique_ptr<ReadingListEntry> b =
29 ReadingListEntry::FromReadingListSpecifics(entryB); 32 ReadingListEntry::FromReadingListSpecifics(entryB,
33 base::Time::FromTimeT(10));
30 a->MergeWithEntry(*b); 34 a->MergeWithEntry(*b);
31 std::unique_ptr<sync_pb::ReadingListSpecifics> mergedEntry = 35 std::unique_ptr<sync_pb::ReadingListSpecifics> mergedEntry =
32 a->AsReadingListSpecifics(); 36 a->AsReadingListSpecifics();
33 if (possible) { 37 if (possible) {
34 // If transition is possible, the merge should be B. 38 // If transition is possible, the merge should be B.
35 EXPECT_EQ(entryB.SerializeAsString(), mergedEntry->SerializeAsString()); 39 EXPECT_EQ(entryB.SerializeAsString(), mergedEntry->SerializeAsString());
36 } else { 40 } else {
37 // If transition is not possible, the transition shold be possible to the 41 // If transition is not possible, the transition shold be possible to the
38 // merged state. 42 // merged state.
39 EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, *mergedEntry)); 43 EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryA, *mergedEntry));
40 EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryB, *mergedEntry)); 44 EXPECT_TRUE(ReadingListStore::CompareEntriesForSync(entryB, *mergedEntry));
41 } 45 }
42 } 46 }
gambard 2017/03/21 13:08:07 Add new line.
Olivier 2017/03/21 14:01:10 Done.
47 base::Time AdvanceAndGetTime(base::SimpleTestClock* clock) {
48 clock->Advance(base::TimeDelta::FromMilliseconds(10));
49 return clock->Now();
50 }
51
52 } // namespace
43 53
44 class FakeModelTypeChangeProcessorObserver { 54 class FakeModelTypeChangeProcessorObserver {
45 public: 55 public:
46 virtual void Put(const std::string& client_tag, 56 virtual void Put(const std::string& client_tag,
47 std::unique_ptr<syncer::EntityData> entity_data, 57 std::unique_ptr<syncer::EntityData> entity_data,
48 syncer::MetadataChangeList* metadata_change_list) = 0; 58 syncer::MetadataChangeList* metadata_change_list) = 0;
49 59
50 virtual void Delete(const std::string& client_tag, 60 virtual void Delete(const std::string& client_tag,
51 syncer::MetadataChangeList* metadata_change_list) = 0; 61 syncer::MetadataChangeList* metadata_change_list) = 0;
52 }; 62 };
(...skipping 25 matching lines...) Expand all
78 public ReadingListStoreDelegate { 88 public ReadingListStoreDelegate {
79 protected: 89 protected:
80 ReadingListStoreTest() 90 ReadingListStoreTest()
81 : store_(syncer::ModelTypeStoreTestUtil::CreateInMemoryStoreForTest()) { 91 : store_(syncer::ModelTypeStoreTestUtil::CreateInMemoryStoreForTest()) {
82 ClearState(); 92 ClearState();
83 reading_list_store_ = base::MakeUnique<ReadingListStore>( 93 reading_list_store_ = base::MakeUnique<ReadingListStore>(
84 base::Bind(&syncer::ModelTypeStoreTestUtil::MoveStoreToCallback, 94 base::Bind(&syncer::ModelTypeStoreTestUtil::MoveStoreToCallback,
85 base::Passed(&store_)), 95 base::Passed(&store_)),
86 base::Bind(&ReadingListStoreTest::CreateModelTypeChangeProcessor, 96 base::Bind(&ReadingListStoreTest::CreateModelTypeChangeProcessor,
87 base::Unretained(this))); 97 base::Unretained(this)));
88 model_ = base::MakeUnique<ReadingListModelImpl>(nullptr, nullptr); 98 auto clock = base::MakeUnique<base::SimpleTestClock>();
89 reading_list_store_->SetReadingListModel(model_.get(), this); 99 clock_ = clock.get();
100 model_ = base::MakeUnique<ReadingListModelImpl>(nullptr, nullptr,
101 std::move(clock));
102 reading_list_store_->SetReadingListModel(model_.get(), this, clock_);
90 103
91 base::RunLoop().RunUntilIdle(); 104 base::RunLoop().RunUntilIdle();
gambard 2017/03/21 13:08:07 What is this used for?
92 } 105 }
93 106
94 std::unique_ptr<syncer::ModelTypeChangeProcessor> 107 std::unique_ptr<syncer::ModelTypeChangeProcessor>
95 CreateModelTypeChangeProcessor(syncer::ModelType type, 108 CreateModelTypeChangeProcessor(syncer::ModelType type,
96 syncer::ModelTypeSyncBridge* service) { 109 syncer::ModelTypeSyncBridge* service) {
97 auto processor = base::MakeUnique<TestModelTypeChangeProcessor>(); 110 auto processor = base::MakeUnique<TestModelTypeChangeProcessor>();
98 processor->SetObserver(this); 111 processor->SetObserver(this);
99 return std::move(processor); 112 return std::move(processor);
100 } 113 }
101 114
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 sync_merge_called_++; 169 sync_merge_called_++;
157 sync_merged_[entry->URL().spec()] = entry->IsRead(); 170 sync_merged_[entry->URL().spec()] = entry->IsRead();
158 return model_->SyncMergeEntry(std::move(entry)); 171 return model_->SyncMergeEntry(std::move(entry));
159 } 172 }
160 173
161 // In memory model type store needs a MessageLoop. 174 // In memory model type store needs a MessageLoop.
162 base::MessageLoop message_loop_; 175 base::MessageLoop message_loop_;
163 176
164 std::unique_ptr<syncer::ModelTypeStore> store_; 177 std::unique_ptr<syncer::ModelTypeStore> store_;
165 std::unique_ptr<ReadingListModelImpl> model_; 178 std::unique_ptr<ReadingListModelImpl> model_;
179 base::SimpleTestClock* clock_;
166 std::unique_ptr<ReadingListStore> reading_list_store_; 180 std::unique_ptr<ReadingListStore> reading_list_store_;
167 int put_called_; 181 int put_called_;
168 int delete_called_; 182 int delete_called_;
169 int sync_add_called_; 183 int sync_add_called_;
170 int sync_remove_called_; 184 int sync_remove_called_;
171 int sync_merge_called_; 185 int sync_merge_called_;
172 std::map<std::string, std::unique_ptr<syncer::EntityData>> put_multimap_; 186 std::map<std::string, std::unique_ptr<syncer::EntityData>> put_multimap_;
173 std::set<std::string> delete_set_; 187 std::set<std::string> delete_set_;
174 std::map<std::string, bool> sync_added_; 188 std::map<std::string, bool> sync_added_;
175 std::set<std::string> sync_removed_; 189 std::set<std::string> sync_removed_;
176 std::map<std::string, bool> sync_merged_; 190 std::map<std::string, bool> sync_merged_;
177 }; 191 };
178 192
179 TEST_F(ReadingListStoreTest, CheckEmpties) { 193 TEST_F(ReadingListStoreTest, CheckEmpties) {
180 EXPECT_EQ(0ul, model_->size()); 194 EXPECT_EQ(0ul, model_->size());
181 } 195 }
182 196
183 TEST_F(ReadingListStoreTest, SaveOneRead) { 197 TEST_F(ReadingListStoreTest, SaveOneRead) {
184 ReadingListEntry entry(GURL("http://read.example.com/"), "read title"); 198 ReadingListEntry entry(GURL("http://read.example.com/"), "read title",
185 entry.SetRead(true); 199 AdvanceAndGetTime(clock_));
200 entry.SetRead(true, AdvanceAndGetTime(clock_));
201 AdvanceAndGetTime(clock_);
186 reading_list_store_->SaveEntry(entry); 202 reading_list_store_->SaveEntry(entry);
187 AssertCounts(1, 0, 0, 0, 0); 203 AssertCounts(1, 0, 0, 0, 0);
188 syncer::EntityData* data = put_multimap_["http://read.example.com/"].get(); 204 syncer::EntityData* data = put_multimap_["http://read.example.com/"].get();
189 const sync_pb::ReadingListSpecifics& specifics = 205 const sync_pb::ReadingListSpecifics& specifics =
190 data->specifics.reading_list(); 206 data->specifics.reading_list();
191 EXPECT_EQ(specifics.title(), "read title"); 207 EXPECT_EQ(specifics.title(), "read title");
gambard 2017/03/21 13:08:07 We are not testing for all update times?
Olivier 2017/03/21 14:01:10 This is tested in ReadingListEntry unittests.
gambard 2017/03/21 15:36:53 Acknowledged.
192 EXPECT_EQ(specifics.url(), "http://read.example.com/"); 208 EXPECT_EQ(specifics.url(), "http://read.example.com/");
193 EXPECT_EQ(specifics.status(), sync_pb::ReadingListSpecifics::READ); 209 EXPECT_EQ(specifics.status(), sync_pb::ReadingListSpecifics::READ);
194 } 210 }
195 211
196 TEST_F(ReadingListStoreTest, SaveOneUnread) { 212 TEST_F(ReadingListStoreTest, SaveOneUnread) {
197 ReadingListEntry entry(GURL("http://unread.example.com/"), "unread title"); 213 ReadingListEntry entry(GURL("http://unread.example.com/"), "unread title",
214 AdvanceAndGetTime(clock_));
198 reading_list_store_->SaveEntry(entry); 215 reading_list_store_->SaveEntry(entry);
199 AssertCounts(1, 0, 0, 0, 0); 216 AssertCounts(1, 0, 0, 0, 0);
200 syncer::EntityData* data = put_multimap_["http://unread.example.com/"].get(); 217 syncer::EntityData* data = put_multimap_["http://unread.example.com/"].get();
201 const sync_pb::ReadingListSpecifics& specifics = 218 const sync_pb::ReadingListSpecifics& specifics =
202 data->specifics.reading_list(); 219 data->specifics.reading_list();
203 EXPECT_EQ(specifics.title(), "unread title"); 220 EXPECT_EQ(specifics.title(), "unread title");
204 EXPECT_EQ(specifics.url(), "http://unread.example.com/"); 221 EXPECT_EQ(specifics.url(), "http://unread.example.com/");
205 EXPECT_EQ(specifics.status(), sync_pb::ReadingListSpecifics::UNSEEN); 222 EXPECT_EQ(specifics.status(), sync_pb::ReadingListSpecifics::UNSEEN);
206 } 223 }
207 224
208 TEST_F(ReadingListStoreTest, SyncMergeOneEntry) { 225 TEST_F(ReadingListStoreTest, SyncMergeOneEntry) {
209 syncer::EntityDataMap remote_input; 226 syncer::EntityDataMap remote_input;
210 ReadingListEntry entry(GURL("http://read.example.com/"), "read title"); 227 ReadingListEntry entry(GURL("http://read.example.com/"), "read title",
211 entry.SetRead(true); 228 AdvanceAndGetTime(clock_));
229 entry.SetRead(true, AdvanceAndGetTime(clock_));
212 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = 230 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics =
213 entry.AsReadingListSpecifics(); 231 entry.AsReadingListSpecifics();
214 232
215 syncer::EntityData data; 233 syncer::EntityData data;
216 data.client_tag_hash = "http://read.example.com/"; 234 data.client_tag_hash = "http://read.example.com/";
217 *data.specifics.mutable_reading_list() = *specifics; 235 *data.specifics.mutable_reading_list() = *specifics;
218 236
219 remote_input["http://read.example.com/"] = data.PassToPtr(); 237 remote_input["http://read.example.com/"] = data.PassToPtr();
220 238
221 std::unique_ptr<syncer::MetadataChangeList> metadata_changes( 239 std::unique_ptr<syncer::MetadataChangeList> metadata_changes(
222 reading_list_store_->CreateMetadataChangeList()); 240 reading_list_store_->CreateMetadataChangeList());
223 auto error = reading_list_store_->MergeSyncData(std::move(metadata_changes), 241 auto error = reading_list_store_->MergeSyncData(std::move(metadata_changes),
224 remote_input); 242 remote_input);
225 AssertCounts(0, 0, 1, 0, 0); 243 AssertCounts(0, 0, 1, 0, 0);
226 EXPECT_EQ(sync_added_.size(), 1u); 244 EXPECT_EQ(sync_added_.size(), 1u);
227 EXPECT_EQ(sync_added_.count("http://read.example.com/"), 1u); 245 EXPECT_EQ(sync_added_.count("http://read.example.com/"), 1u);
228 EXPECT_EQ(sync_added_["http://read.example.com/"], true); 246 EXPECT_EQ(sync_added_["http://read.example.com/"], true);
229 } 247 }
230 248
231 TEST_F(ReadingListStoreTest, ApplySyncChangesOneAdd) { 249 TEST_F(ReadingListStoreTest, ApplySyncChangesOneAdd) {
232 syncer::EntityDataMap remote_input; 250 syncer::EntityDataMap remote_input;
233 ReadingListEntry entry(GURL("http://read.example.com/"), "read title"); 251 ReadingListEntry entry(GURL("http://read.example.com/"), "read title",
234 entry.SetRead(true); 252 AdvanceAndGetTime(clock_));
253 entry.SetRead(true, AdvanceAndGetTime(clock_));
235 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = 254 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics =
236 entry.AsReadingListSpecifics(); 255 entry.AsReadingListSpecifics();
237 syncer::EntityData data; 256 syncer::EntityData data;
238 data.client_tag_hash = "http://read.example.com/"; 257 data.client_tag_hash = "http://read.example.com/";
239 *data.specifics.mutable_reading_list() = *specifics; 258 *data.specifics.mutable_reading_list() = *specifics;
240 259
241 syncer::EntityChangeList add_changes; 260 syncer::EntityChangeList add_changes;
242 261
243 add_changes.push_back(syncer::EntityChange::CreateAdd( 262 add_changes.push_back(syncer::EntityChange::CreateAdd(
244 "http://read.example.com/", data.PassToPtr())); 263 "http://read.example.com/", data.PassToPtr()));
245 auto error = reading_list_store_->ApplySyncChanges( 264 auto error = reading_list_store_->ApplySyncChanges(
246 reading_list_store_->CreateMetadataChangeList(), add_changes); 265 reading_list_store_->CreateMetadataChangeList(), add_changes);
247 AssertCounts(0, 0, 1, 0, 0); 266 AssertCounts(0, 0, 1, 0, 0);
248 EXPECT_EQ(sync_added_.size(), 1u); 267 EXPECT_EQ(sync_added_.size(), 1u);
249 EXPECT_EQ(sync_added_.count("http://read.example.com/"), 1u); 268 EXPECT_EQ(sync_added_.count("http://read.example.com/"), 1u);
250 EXPECT_EQ(sync_added_["http://read.example.com/"], true); 269 EXPECT_EQ(sync_added_["http://read.example.com/"], true);
251 } 270 }
252 271
253 TEST_F(ReadingListStoreTest, ApplySyncChangesOneMerge) { 272 TEST_F(ReadingListStoreTest, ApplySyncChangesOneMerge) {
254 syncer::EntityDataMap remote_input; 273 syncer::EntityDataMap remote_input;
274 AdvanceAndGetTime(clock_);
255 model_->AddEntry(GURL("http://unread.example.com/"), "unread title", 275 model_->AddEntry(GURL("http://unread.example.com/"), "unread title",
256 reading_list::ADDED_VIA_CURRENT_APP); 276 reading_list::ADDED_VIA_CURRENT_APP);
257 base::test::ios::SpinRunLoopWithMinDelay(
258 base::TimeDelta::FromMilliseconds(10));
259 277
260 ReadingListEntry new_entry(GURL("http://unread.example.com/"), 278 ReadingListEntry new_entry(GURL("http://unread.example.com/"), "unread title",
261 "unread title"); 279 AdvanceAndGetTime(clock_));
262 new_entry.SetRead(true); 280 new_entry.SetRead(true, AdvanceAndGetTime(clock_));
263 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = 281 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics =
264 new_entry.AsReadingListSpecifics(); 282 new_entry.AsReadingListSpecifics();
265 syncer::EntityData data; 283 syncer::EntityData data;
266 data.client_tag_hash = "http://unread.example.com/"; 284 data.client_tag_hash = "http://unread.example.com/";
267 *data.specifics.mutable_reading_list() = *specifics; 285 *data.specifics.mutable_reading_list() = *specifics;
268 286
269 syncer::EntityChangeList add_changes; 287 syncer::EntityChangeList add_changes;
270 add_changes.push_back(syncer::EntityChange::CreateAdd( 288 add_changes.push_back(syncer::EntityChange::CreateAdd(
271 "http://unread.example.com/", data.PassToPtr())); 289 "http://unread.example.com/", data.PassToPtr()));
272 auto error = reading_list_store_->ApplySyncChanges( 290 auto error = reading_list_store_->ApplySyncChanges(
273 reading_list_store_->CreateMetadataChangeList(), add_changes); 291 reading_list_store_->CreateMetadataChangeList(), add_changes);
274 AssertCounts(1, 0, 0, 0, 1); 292 AssertCounts(1, 0, 0, 0, 1);
275 EXPECT_EQ(sync_merged_.size(), 1u); 293 EXPECT_EQ(sync_merged_.size(), 1u);
276 EXPECT_EQ(sync_merged_.count("http://unread.example.com/"), 1u); 294 EXPECT_EQ(sync_merged_.count("http://unread.example.com/"), 1u);
277 EXPECT_EQ(sync_merged_["http://unread.example.com/"], true); 295 EXPECT_EQ(sync_merged_["http://unread.example.com/"], true);
278 } 296 }
279 297
280 TEST_F(ReadingListStoreTest, ApplySyncChangesOneIgnored) { 298 TEST_F(ReadingListStoreTest, ApplySyncChangesOneIgnored) {
281 // Read entry but with unread URL as it must update the other one. 299 // Read entry but with unread URL as it must update the other one.
282 ReadingListEntry old_entry(GURL("http://unread.example.com/"), 300 ReadingListEntry old_entry(GURL("http://unread.example.com/"),
283 "old unread title"); 301 "old unread title", AdvanceAndGetTime(clock_));
284 old_entry.SetRead(true); 302 old_entry.SetRead(true, AdvanceAndGetTime(clock_));
285 303
286 base::test::ios::SpinRunLoopWithMinDelay(
287 base::TimeDelta::FromMilliseconds(10));
288 syncer::EntityDataMap remote_input; 304 syncer::EntityDataMap remote_input;
305 AdvanceAndGetTime(clock_);
289 model_->AddEntry(GURL("http://unread.example.com/"), "new unread title", 306 model_->AddEntry(GURL("http://unread.example.com/"), "new unread title",
290 reading_list::ADDED_VIA_CURRENT_APP); 307 reading_list::ADDED_VIA_CURRENT_APP);
291 AssertCounts(0, 0, 0, 0, 0); 308 AssertCounts(0, 0, 0, 0, 0);
292 309
293 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = 310 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics =
294 old_entry.AsReadingListSpecifics(); 311 old_entry.AsReadingListSpecifics();
295 syncer::EntityData data; 312 syncer::EntityData data;
296 data.client_tag_hash = "http://unread.example.com/"; 313 data.client_tag_hash = "http://unread.example.com/";
297 *data.specifics.mutable_reading_list() = *specifics; 314 *data.specifics.mutable_reading_list() = *specifics;
298 315
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 entryB.set_status(status_oder[index_a]); 448 entryB.set_status(status_oder[index_a]);
432 ExpectAB(entryA, entryB, true); 449 ExpectAB(entryA, entryB, true);
433 ExpectAB(entryB, entryA, true); 450 ExpectAB(entryB, entryA, true);
434 for (int index_b = index_a + 1; index_b < 3; index_b++) { 451 for (int index_b = index_a + 1; index_b < 3; index_b++) {
435 entryB.set_status(status_oder[index_b]); 452 entryB.set_status(status_oder[index_b]);
436 ExpectAB(entryA, entryB, true); 453 ExpectAB(entryA, entryB, true);
437 ExpectAB(entryB, entryA, false); 454 ExpectAB(entryB, entryA, false);
438 } 455 }
439 } 456 }
440 } 457 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698