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

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: jitter 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 }
43 47
48 base::Time AdvanceAndGetTime(base::SimpleTestClock* clock) {
49 clock->Advance(base::TimeDelta::FromMilliseconds(10));
50 return clock->Now();
51 }
52
53 } // namespace
54
44 class FakeModelTypeChangeProcessorObserver { 55 class FakeModelTypeChangeProcessorObserver {
45 public: 56 public:
46 virtual void Put(const std::string& client_tag, 57 virtual void Put(const std::string& client_tag,
47 std::unique_ptr<syncer::EntityData> entity_data, 58 std::unique_ptr<syncer::EntityData> entity_data,
48 syncer::MetadataChangeList* metadata_change_list) = 0; 59 syncer::MetadataChangeList* metadata_change_list) = 0;
49 60
50 virtual void Delete(const std::string& client_tag, 61 virtual void Delete(const std::string& client_tag,
51 syncer::MetadataChangeList* metadata_change_list) = 0; 62 syncer::MetadataChangeList* metadata_change_list) = 0;
52 }; 63 };
53 64
(...skipping 24 matching lines...) Expand all
78 public ReadingListStoreDelegate { 89 public ReadingListStoreDelegate {
79 protected: 90 protected:
80 ReadingListStoreTest() 91 ReadingListStoreTest()
81 : store_(syncer::ModelTypeStoreTestUtil::CreateInMemoryStoreForTest()) { 92 : store_(syncer::ModelTypeStoreTestUtil::CreateInMemoryStoreForTest()) {
82 ClearState(); 93 ClearState();
83 reading_list_store_ = base::MakeUnique<ReadingListStore>( 94 reading_list_store_ = base::MakeUnique<ReadingListStore>(
84 base::Bind(&syncer::ModelTypeStoreTestUtil::MoveStoreToCallback, 95 base::Bind(&syncer::ModelTypeStoreTestUtil::MoveStoreToCallback,
85 base::Passed(&store_)), 96 base::Passed(&store_)),
86 base::Bind(&ReadingListStoreTest::CreateModelTypeChangeProcessor, 97 base::Bind(&ReadingListStoreTest::CreateModelTypeChangeProcessor,
87 base::Unretained(this))); 98 base::Unretained(this)));
88 model_ = base::MakeUnique<ReadingListModelImpl>(nullptr, nullptr); 99 auto clock = base::MakeUnique<base::SimpleTestClock>();
89 reading_list_store_->SetReadingListModel(model_.get(), this); 100 clock_ = clock.get();
101 model_ = base::MakeUnique<ReadingListModelImpl>(nullptr, nullptr,
102 std::move(clock));
103 reading_list_store_->SetReadingListModel(model_.get(), this, clock_);
90 104
91 base::RunLoop().RunUntilIdle(); 105 base::RunLoop().RunUntilIdle();
92 } 106 }
93 107
94 std::unique_ptr<syncer::ModelTypeChangeProcessor> 108 std::unique_ptr<syncer::ModelTypeChangeProcessor>
95 CreateModelTypeChangeProcessor(syncer::ModelType type, 109 CreateModelTypeChangeProcessor(syncer::ModelType type,
96 syncer::ModelTypeSyncBridge* service) { 110 syncer::ModelTypeSyncBridge* service) {
97 auto processor = base::MakeUnique<TestModelTypeChangeProcessor>(); 111 auto processor = base::MakeUnique<TestModelTypeChangeProcessor>();
98 processor->SetObserver(this); 112 processor->SetObserver(this);
99 return std::move(processor); 113 return std::move(processor);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 sync_merge_called_++; 170 sync_merge_called_++;
157 sync_merged_[entry->URL().spec()] = entry->IsRead(); 171 sync_merged_[entry->URL().spec()] = entry->IsRead();
158 return model_->SyncMergeEntry(std::move(entry)); 172 return model_->SyncMergeEntry(std::move(entry));
159 } 173 }
160 174
161 // In memory model type store needs a MessageLoop. 175 // In memory model type store needs a MessageLoop.
162 base::MessageLoop message_loop_; 176 base::MessageLoop message_loop_;
163 177
164 std::unique_ptr<syncer::ModelTypeStore> store_; 178 std::unique_ptr<syncer::ModelTypeStore> store_;
165 std::unique_ptr<ReadingListModelImpl> model_; 179 std::unique_ptr<ReadingListModelImpl> model_;
180 base::SimpleTestClock* clock_;
166 std::unique_ptr<ReadingListStore> reading_list_store_; 181 std::unique_ptr<ReadingListStore> reading_list_store_;
167 int put_called_; 182 int put_called_;
168 int delete_called_; 183 int delete_called_;
169 int sync_add_called_; 184 int sync_add_called_;
170 int sync_remove_called_; 185 int sync_remove_called_;
171 int sync_merge_called_; 186 int sync_merge_called_;
172 std::map<std::string, std::unique_ptr<syncer::EntityData>> put_multimap_; 187 std::map<std::string, std::unique_ptr<syncer::EntityData>> put_multimap_;
173 std::set<std::string> delete_set_; 188 std::set<std::string> delete_set_;
174 std::map<std::string, bool> sync_added_; 189 std::map<std::string, bool> sync_added_;
175 std::set<std::string> sync_removed_; 190 std::set<std::string> sync_removed_;
176 std::map<std::string, bool> sync_merged_; 191 std::map<std::string, bool> sync_merged_;
177 }; 192 };
178 193
179 TEST_F(ReadingListStoreTest, CheckEmpties) { 194 TEST_F(ReadingListStoreTest, CheckEmpties) {
180 EXPECT_EQ(0ul, model_->size()); 195 EXPECT_EQ(0ul, model_->size());
181 } 196 }
182 197
183 TEST_F(ReadingListStoreTest, SaveOneRead) { 198 TEST_F(ReadingListStoreTest, SaveOneRead) {
184 ReadingListEntry entry(GURL("http://read.example.com/"), "read title"); 199 ReadingListEntry entry(GURL("http://read.example.com/"), "read title",
185 entry.SetRead(true); 200 AdvanceAndGetTime(clock_));
201 entry.SetRead(true, AdvanceAndGetTime(clock_));
202 AdvanceAndGetTime(clock_);
186 reading_list_store_->SaveEntry(entry); 203 reading_list_store_->SaveEntry(entry);
187 AssertCounts(1, 0, 0, 0, 0); 204 AssertCounts(1, 0, 0, 0, 0);
188 syncer::EntityData* data = put_multimap_["http://read.example.com/"].get(); 205 syncer::EntityData* data = put_multimap_["http://read.example.com/"].get();
189 const sync_pb::ReadingListSpecifics& specifics = 206 const sync_pb::ReadingListSpecifics& specifics =
190 data->specifics.reading_list(); 207 data->specifics.reading_list();
191 EXPECT_EQ(specifics.title(), "read title"); 208 EXPECT_EQ(specifics.title(), "read title");
192 EXPECT_EQ(specifics.url(), "http://read.example.com/"); 209 EXPECT_EQ(specifics.url(), "http://read.example.com/");
193 EXPECT_EQ(specifics.status(), sync_pb::ReadingListSpecifics::READ); 210 EXPECT_EQ(specifics.status(), sync_pb::ReadingListSpecifics::READ);
194 } 211 }
195 212
196 TEST_F(ReadingListStoreTest, SaveOneUnread) { 213 TEST_F(ReadingListStoreTest, SaveOneUnread) {
197 ReadingListEntry entry(GURL("http://unread.example.com/"), "unread title"); 214 ReadingListEntry entry(GURL("http://unread.example.com/"), "unread title",
215 AdvanceAndGetTime(clock_));
198 reading_list_store_->SaveEntry(entry); 216 reading_list_store_->SaveEntry(entry);
199 AssertCounts(1, 0, 0, 0, 0); 217 AssertCounts(1, 0, 0, 0, 0);
200 syncer::EntityData* data = put_multimap_["http://unread.example.com/"].get(); 218 syncer::EntityData* data = put_multimap_["http://unread.example.com/"].get();
201 const sync_pb::ReadingListSpecifics& specifics = 219 const sync_pb::ReadingListSpecifics& specifics =
202 data->specifics.reading_list(); 220 data->specifics.reading_list();
203 EXPECT_EQ(specifics.title(), "unread title"); 221 EXPECT_EQ(specifics.title(), "unread title");
204 EXPECT_EQ(specifics.url(), "http://unread.example.com/"); 222 EXPECT_EQ(specifics.url(), "http://unread.example.com/");
205 EXPECT_EQ(specifics.status(), sync_pb::ReadingListSpecifics::UNSEEN); 223 EXPECT_EQ(specifics.status(), sync_pb::ReadingListSpecifics::UNSEEN);
206 } 224 }
207 225
208 TEST_F(ReadingListStoreTest, SyncMergeOneEntry) { 226 TEST_F(ReadingListStoreTest, SyncMergeOneEntry) {
209 syncer::EntityDataMap remote_input; 227 syncer::EntityDataMap remote_input;
210 ReadingListEntry entry(GURL("http://read.example.com/"), "read title"); 228 ReadingListEntry entry(GURL("http://read.example.com/"), "read title",
211 entry.SetRead(true); 229 AdvanceAndGetTime(clock_));
230 entry.SetRead(true, AdvanceAndGetTime(clock_));
212 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = 231 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics =
213 entry.AsReadingListSpecifics(); 232 entry.AsReadingListSpecifics();
214 233
215 syncer::EntityData data; 234 syncer::EntityData data;
216 data.client_tag_hash = "http://read.example.com/"; 235 data.client_tag_hash = "http://read.example.com/";
217 *data.specifics.mutable_reading_list() = *specifics; 236 *data.specifics.mutable_reading_list() = *specifics;
218 237
219 remote_input["http://read.example.com/"] = data.PassToPtr(); 238 remote_input["http://read.example.com/"] = data.PassToPtr();
220 239
221 std::unique_ptr<syncer::MetadataChangeList> metadata_changes( 240 std::unique_ptr<syncer::MetadataChangeList> metadata_changes(
222 reading_list_store_->CreateMetadataChangeList()); 241 reading_list_store_->CreateMetadataChangeList());
223 auto error = reading_list_store_->MergeSyncData(std::move(metadata_changes), 242 auto error = reading_list_store_->MergeSyncData(std::move(metadata_changes),
224 remote_input); 243 remote_input);
225 AssertCounts(0, 0, 1, 0, 0); 244 AssertCounts(0, 0, 1, 0, 0);
226 EXPECT_EQ(sync_added_.size(), 1u); 245 EXPECT_EQ(sync_added_.size(), 1u);
227 EXPECT_EQ(sync_added_.count("http://read.example.com/"), 1u); 246 EXPECT_EQ(sync_added_.count("http://read.example.com/"), 1u);
228 EXPECT_EQ(sync_added_["http://read.example.com/"], true); 247 EXPECT_EQ(sync_added_["http://read.example.com/"], true);
229 } 248 }
230 249
231 TEST_F(ReadingListStoreTest, ApplySyncChangesOneAdd) { 250 TEST_F(ReadingListStoreTest, ApplySyncChangesOneAdd) {
232 syncer::EntityDataMap remote_input; 251 syncer::EntityDataMap remote_input;
233 ReadingListEntry entry(GURL("http://read.example.com/"), "read title"); 252 ReadingListEntry entry(GURL("http://read.example.com/"), "read title",
234 entry.SetRead(true); 253 AdvanceAndGetTime(clock_));
254 entry.SetRead(true, AdvanceAndGetTime(clock_));
235 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = 255 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics =
236 entry.AsReadingListSpecifics(); 256 entry.AsReadingListSpecifics();
237 syncer::EntityData data; 257 syncer::EntityData data;
238 data.client_tag_hash = "http://read.example.com/"; 258 data.client_tag_hash = "http://read.example.com/";
239 *data.specifics.mutable_reading_list() = *specifics; 259 *data.specifics.mutable_reading_list() = *specifics;
240 260
241 syncer::EntityChangeList add_changes; 261 syncer::EntityChangeList add_changes;
242 262
243 add_changes.push_back(syncer::EntityChange::CreateAdd( 263 add_changes.push_back(syncer::EntityChange::CreateAdd(
244 "http://read.example.com/", data.PassToPtr())); 264 "http://read.example.com/", data.PassToPtr()));
245 auto error = reading_list_store_->ApplySyncChanges( 265 auto error = reading_list_store_->ApplySyncChanges(
246 reading_list_store_->CreateMetadataChangeList(), add_changes); 266 reading_list_store_->CreateMetadataChangeList(), add_changes);
247 AssertCounts(0, 0, 1, 0, 0); 267 AssertCounts(0, 0, 1, 0, 0);
248 EXPECT_EQ(sync_added_.size(), 1u); 268 EXPECT_EQ(sync_added_.size(), 1u);
249 EXPECT_EQ(sync_added_.count("http://read.example.com/"), 1u); 269 EXPECT_EQ(sync_added_.count("http://read.example.com/"), 1u);
250 EXPECT_EQ(sync_added_["http://read.example.com/"], true); 270 EXPECT_EQ(sync_added_["http://read.example.com/"], true);
251 } 271 }
252 272
253 TEST_F(ReadingListStoreTest, ApplySyncChangesOneMerge) { 273 TEST_F(ReadingListStoreTest, ApplySyncChangesOneMerge) {
254 syncer::EntityDataMap remote_input; 274 syncer::EntityDataMap remote_input;
275 AdvanceAndGetTime(clock_);
255 model_->AddEntry(GURL("http://unread.example.com/"), "unread title", 276 model_->AddEntry(GURL("http://unread.example.com/"), "unread title",
256 reading_list::ADDED_VIA_CURRENT_APP); 277 reading_list::ADDED_VIA_CURRENT_APP);
257 base::test::ios::SpinRunLoopWithMinDelay(
258 base::TimeDelta::FromMilliseconds(10));
259 278
260 ReadingListEntry new_entry(GURL("http://unread.example.com/"), 279 ReadingListEntry new_entry(GURL("http://unread.example.com/"), "unread title",
261 "unread title"); 280 AdvanceAndGetTime(clock_));
262 new_entry.SetRead(true); 281 new_entry.SetRead(true, AdvanceAndGetTime(clock_));
263 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = 282 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics =
264 new_entry.AsReadingListSpecifics(); 283 new_entry.AsReadingListSpecifics();
265 syncer::EntityData data; 284 syncer::EntityData data;
266 data.client_tag_hash = "http://unread.example.com/"; 285 data.client_tag_hash = "http://unread.example.com/";
267 *data.specifics.mutable_reading_list() = *specifics; 286 *data.specifics.mutable_reading_list() = *specifics;
268 287
269 syncer::EntityChangeList add_changes; 288 syncer::EntityChangeList add_changes;
270 add_changes.push_back(syncer::EntityChange::CreateAdd( 289 add_changes.push_back(syncer::EntityChange::CreateAdd(
271 "http://unread.example.com/", data.PassToPtr())); 290 "http://unread.example.com/", data.PassToPtr()));
272 auto error = reading_list_store_->ApplySyncChanges( 291 auto error = reading_list_store_->ApplySyncChanges(
273 reading_list_store_->CreateMetadataChangeList(), add_changes); 292 reading_list_store_->CreateMetadataChangeList(), add_changes);
274 AssertCounts(1, 0, 0, 0, 1); 293 AssertCounts(1, 0, 0, 0, 1);
275 EXPECT_EQ(sync_merged_.size(), 1u); 294 EXPECT_EQ(sync_merged_.size(), 1u);
276 EXPECT_EQ(sync_merged_.count("http://unread.example.com/"), 1u); 295 EXPECT_EQ(sync_merged_.count("http://unread.example.com/"), 1u);
277 EXPECT_EQ(sync_merged_["http://unread.example.com/"], true); 296 EXPECT_EQ(sync_merged_["http://unread.example.com/"], true);
278 } 297 }
279 298
280 TEST_F(ReadingListStoreTest, ApplySyncChangesOneIgnored) { 299 TEST_F(ReadingListStoreTest, ApplySyncChangesOneIgnored) {
281 // Read entry but with unread URL as it must update the other one. 300 // Read entry but with unread URL as it must update the other one.
282 ReadingListEntry old_entry(GURL("http://unread.example.com/"), 301 ReadingListEntry old_entry(GURL("http://unread.example.com/"),
283 "old unread title"); 302 "old unread title", AdvanceAndGetTime(clock_));
284 old_entry.SetRead(true); 303 old_entry.SetRead(true, AdvanceAndGetTime(clock_));
285 304
286 base::test::ios::SpinRunLoopWithMinDelay(
287 base::TimeDelta::FromMilliseconds(10));
288 syncer::EntityDataMap remote_input; 305 syncer::EntityDataMap remote_input;
306 AdvanceAndGetTime(clock_);
289 model_->AddEntry(GURL("http://unread.example.com/"), "new unread title", 307 model_->AddEntry(GURL("http://unread.example.com/"), "new unread title",
290 reading_list::ADDED_VIA_CURRENT_APP); 308 reading_list::ADDED_VIA_CURRENT_APP);
291 AssertCounts(0, 0, 0, 0, 0); 309 AssertCounts(0, 0, 0, 0, 0);
292 310
293 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = 311 std::unique_ptr<sync_pb::ReadingListSpecifics> specifics =
294 old_entry.AsReadingListSpecifics(); 312 old_entry.AsReadingListSpecifics();
295 syncer::EntityData data; 313 syncer::EntityData data;
296 data.client_tag_hash = "http://unread.example.com/"; 314 data.client_tag_hash = "http://unread.example.com/";
297 *data.specifics.mutable_reading_list() = *specifics; 315 *data.specifics.mutable_reading_list() = *specifics;
298 316
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 entryB.set_status(status_oder[index_a]); 449 entryB.set_status(status_oder[index_a]);
432 ExpectAB(entryA, entryB, true); 450 ExpectAB(entryA, entryB, true);
433 ExpectAB(entryB, entryA, true); 451 ExpectAB(entryB, entryA, true);
434 for (int index_b = index_a + 1; index_b < 3; index_b++) { 452 for (int index_b = index_a + 1; index_b < 3; index_b++) {
435 entryB.set_status(status_oder[index_b]); 453 entryB.set_status(status_oder[index_b]);
436 ExpectAB(entryA, entryB, true); 454 ExpectAB(entryA, entryB, true);
437 ExpectAB(entryB, entryA, false); 455 ExpectAB(entryB, entryA, false);
438 } 456 }
439 } 457 }
440 } 458 }
OLDNEW
« no previous file with comments | « components/reading_list/ios/reading_list_store.cc ('k') | components/reading_list/ios/reading_list_store_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698