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

Side by Side Diff: components/browser_sync/browser/profile_sync_service_typed_url_unittest.cc

Issue 2345843003: [Sync] Merge //components/browser_sync into one directory. (Closed)
Patch Set: Address comment + rebase. Created 4 years, 3 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include <memory>
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "base/bind.h"
14 #include "base/bind_helpers.h"
15 #include "base/callback.h"
16 #include "base/location.h"
17 #include "base/macros.h"
18 #include "base/memory/ptr_util.h"
19 #include "base/memory/ref_counted.h"
20 #include "base/run_loop.h"
21 #include "base/strings/string16.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/threading/thread.h"
24 #include "base/threading/thread_task_runner_handle.h"
25 #include "base/time/time.h"
26 #include "components/browser_sync/browser/abstract_profile_sync_service_test.h"
27 #include "components/browser_sync/browser/test_profile_sync_service.h"
28 #include "components/history/core/browser/history_backend.h"
29 #include "components/history/core/browser/history_backend_client.h"
30 #include "components/history/core/browser/history_backend_notifier.h"
31 #include "components/history/core/browser/history_db_task.h"
32 #include "components/history/core/browser/history_service.h"
33 #include "components/history/core/browser/typed_url_data_type_controller.h"
34 #include "components/signin/core/browser/signin_manager.h"
35 #include "components/sync/api/data_type_error_handler_mock.h"
36 #include "components/sync/core/read_node.h"
37 #include "components/sync/core/read_transaction.h"
38 #include "components/sync/core/write_node.h"
39 #include "components/sync/core/write_transaction.h"
40 #include "components/sync/driver/data_type_manager_impl.h"
41 #include "components/sync/protocol/typed_url_specifics.pb.h"
42 #include "testing/gmock/include/gmock/gmock.h"
43 #include "testing/gtest/include/gtest/gtest.h"
44 #include "url/gurl.h"
45
46 using browser_sync::TypedUrlDataTypeController;
47 using history::HistoryBackend;
48 using history::HistoryBackendNotifier;
49 using history::TypedUrlSyncableService;
50 using testing::DoAll;
51 using testing::Return;
52 using testing::SetArgumentPointee;
53 using testing::_;
54
55 namespace {
56
57 const char kDummySavingBrowserHistoryDisabled[] = "dummyPref";
58
59 // Visits with this timestamp are treated as expired.
60 static const int EXPIRED_VISIT = -1;
61
62 ACTION(ReturnNewDataTypeManager) {
63 return new sync_driver::DataTypeManagerImpl(arg0, arg1, arg2, arg3, arg4);
64 }
65
66 class HistoryBackendMock : public HistoryBackend {
67 public:
68 HistoryBackendMock()
69 : HistoryBackend(nullptr, nullptr, base::ThreadTaskRunnerHandle::Get()) {}
70 bool IsExpiredVisitTime(const base::Time& time) override {
71 return time.ToInternalValue() == EXPIRED_VISIT;
72 }
73 MOCK_METHOD1(GetAllTypedURLs, bool(history::URLRows* entries));
74 MOCK_METHOD3(GetMostRecentVisitsForURL, bool(history::URLID id,
75 int max_visits,
76 history::VisitVector* visits));
77 MOCK_METHOD2(UpdateURL, bool(history::URLID id, const history::URLRow& url));
78 MOCK_METHOD3(AddVisits, bool(const GURL& url,
79 const std::vector<history::VisitInfo>& visits,
80 history::VisitSource visit_source));
81 MOCK_METHOD2(GetURL, bool(const GURL& url_id, history::URLRow* url_row));
82 MOCK_METHOD2(SetPageTitle, void(const GURL& url,
83 const base::string16& title));
84 MOCK_METHOD1(DeleteURL, void(const GURL& url));
85
86 private:
87 friend class ProfileSyncServiceTypedUrlTest;
88
89 virtual ~HistoryBackendMock() {}
90 };
91
92 class HistoryServiceMock : public history::HistoryService {
93 public:
94 HistoryServiceMock() : history::HistoryService(), backend_(nullptr) {}
95
96 base::CancelableTaskTracker::TaskId ScheduleDBTask(
97 std::unique_ptr<history::HistoryDBTask> task,
98 base::CancelableTaskTracker* tracker) override {
99 // Explicitly copy out the raw pointer -- compilers might decide to
100 // evaluate task.release() before the arguments for the first Bind().
101 history::HistoryDBTask* task_raw = task.get();
102 task_runner_->PostTaskAndReply(
103 FROM_HERE,
104 base::Bind(&HistoryServiceMock::RunTaskOnDBThread,
105 base::Unretained(this), task_raw),
106 base::Bind(&base::DeletePointer<history::HistoryDBTask>,
107 task.release()));
108 return base::CancelableTaskTracker::kBadTaskId; // unused
109 }
110
111 ~HistoryServiceMock() override {}
112
113 void set_task_runner(
114 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
115 DCHECK(task_runner.get());
116 task_runner_ = task_runner;
117 }
118
119 void set_backend(scoped_refptr<history::HistoryBackend> backend) {
120 backend_ = backend;
121 }
122
123 private:
124 void RunTaskOnDBThread(history::HistoryDBTask* task) {
125 EXPECT_TRUE(task->RunOnDBThread(backend_.get(), NULL));
126 }
127
128 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
129 scoped_refptr<history::HistoryBackend> backend_;
130 };
131
132 class TestTypedUrlSyncableService : public TypedUrlSyncableService {
133 // TODO(gangwu): remove TestProfileSyncService or even remove whole test
134 // suite, and make sure typed_url_syncable_service_unittest.cc and the various
135 // typed url integration tests.
136 public:
137 explicit TestTypedUrlSyncableService(history::HistoryBackend* history_backend)
138 : TypedUrlSyncableService(history_backend) {}
139
140 static void WriteToSyncNode(const history::URLRow& url,
141 const history::VisitVector& visits,
142 syncer::WriteNode* node) {
143 sync_pb::TypedUrlSpecifics typed_url;
144 WriteToTypedUrlSpecifics(url, visits, &typed_url);
145 node->SetTypedUrlSpecifics(typed_url);
146 }
147
148 protected:
149 // Don't clear error stats - that way we can verify their values in our
150 // tests.
151 void ClearErrorStats() override {}
152 };
153
154 class ProfileSyncServiceTypedUrlTest : public AbstractProfileSyncServiceTest {
155 public:
156 void AddTypedUrlSyncNode(const history::URLRow& url,
157 const history::VisitVector& visits) {
158 syncer::WriteTransaction trans(FROM_HERE, sync_service()->GetUserShare());
159
160 syncer::WriteNode node(&trans);
161 std::string tag = url.url().spec();
162 syncer::WriteNode::InitUniqueByCreationResult result =
163 node.InitUniqueByCreation(syncer::TYPED_URLS, tag);
164 ASSERT_EQ(syncer::WriteNode::INIT_SUCCESS, result);
165 TestTypedUrlSyncableService::WriteToSyncNode(url, visits, &node);
166 }
167
168 protected:
169 ProfileSyncServiceTypedUrlTest() {
170 profile_sync_service_bundle()
171 ->pref_service()
172 ->registry()
173 ->RegisterBooleanPref(kDummySavingBrowserHistoryDisabled, false);
174
175 data_type_thread()->Start();
176 base::RunLoop run_loop;
177 data_type_thread()->task_runner()->PostTaskAndReply(
178 FROM_HERE,
179 base::Bind(&ProfileSyncServiceTypedUrlTest::CreateHistoryService,
180 base::Unretained(this)),
181 run_loop.QuitClosure());
182 run_loop.Run();
183 history_service_ = base::WrapUnique(new HistoryServiceMock);
184 history_service_->set_task_runner(data_type_thread()->task_runner());
185 history_service_->set_backend(history_backend_);
186
187 browser_sync::ProfileSyncServiceBundle::SyncClientBuilder builder(
188 profile_sync_service_bundle());
189 builder.SetHistoryService(history_service_.get());
190 builder.SetSyncServiceCallback(GetSyncServiceCallback());
191 builder.SetSyncableServiceCallback(
192 base::Bind(&ProfileSyncServiceTypedUrlTest::GetSyncableServiceForType,
193 base::Unretained(this)));
194 builder.set_activate_model_creation();
195 sync_client_ = builder.Build();
196 }
197
198 void CreateHistoryService() {
199 history_backend_ = new HistoryBackendMock();
200 syncable_service_ =
201 base::MakeUnique<TestTypedUrlSyncableService>(history_backend_.get());
202 }
203
204 void DeleteSyncableService() {
205 syncable_service_.reset();
206 history_backend_ = nullptr;
207 }
208
209 ~ProfileSyncServiceTypedUrlTest() override {
210 history_service_->Shutdown();
211
212 // Request stop to get deletion tasks related to the HistoryService posted
213 // on the Sync thread. It is important to not Shutdown at this moment,
214 // because after shutdown the Sync thread is not returned to the sync
215 // service, so we could not get the thread's message loop to wait for the
216 // deletions to be finished.
217 sync_service()->RequestStop(sync_driver::SyncService::CLEAR_DATA);
218 // Spin the sync thread.
219 {
220 base::RunLoop run_loop;
221 sync_service()->GetSyncLoopForTest()->task_runner()->PostTaskAndReply(
222 FROM_HERE, base::Bind(&base::DoNothing), run_loop.QuitClosure());
223 run_loop.Run();
224 }
225
226 // Spin the loop again for deletion tasks posted from the Sync thread.
227 base::RunLoop().RunUntilIdle();
228
229 {
230 base::RunLoop run_loop;
231 data_type_thread()->task_runner()->PostTaskAndReply(
232 FROM_HERE,
233 base::Bind(&ProfileSyncServiceTypedUrlTest::DeleteSyncableService,
234 base::Unretained(this)),
235 run_loop.QuitClosure());
236 run_loop.Run();
237 }
238 }
239
240 TypedUrlSyncableService* StartSyncService(const base::Closure& callback) {
241 if (!sync_service()) {
242 std::string account_id =
243 profile_sync_service_bundle()->account_tracker()->SeedAccountInfo(
244 "gaia_id", "test");
245 SigninManagerBase* signin =
246 profile_sync_service_bundle()->signin_manager();
247 signin->SetAuthenticatedAccountInfo("gaia_id", "test");
248 CreateSyncService(std::move(sync_client_), callback);
249 EXPECT_CALL(*profile_sync_service_bundle()->component_factory(),
250 CreateDataTypeManager(_, _, _, _, _))
251 .WillOnce(ReturnNewDataTypeManager());
252
253 profile_sync_service_bundle()->auth_service()->UpdateCredentials(
254 account_id, "oauth2_login_token");
255
256 sync_service()->RegisterDataTypeController(
257 base::MakeUnique<TypedUrlDataTypeController>(
258 base::Bind(&base::DoNothing), sync_service()->GetSyncClient(),
259 kDummySavingBrowserHistoryDisabled));
260
261 sync_service()->Initialize();
262 base::RunLoop().Run();
263 }
264 return syncable_service_.get();
265 }
266
267 void GetTypedUrlsFromSyncDB(history::URLRows* urls) {
268 urls->clear();
269 syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare());
270 syncer::ReadNode typed_url_root(&trans);
271 if (typed_url_root.InitTypeRoot(syncer::TYPED_URLS) !=
272 syncer::BaseNode::INIT_OK)
273 return;
274
275 int64_t child_id = typed_url_root.GetFirstChildId();
276 while (child_id != syncer::kInvalidId) {
277 syncer::ReadNode child_node(&trans);
278 if (child_node.InitByIdLookup(child_id) != syncer::BaseNode::INIT_OK)
279 return;
280
281 const sync_pb::TypedUrlSpecifics& typed_url(
282 child_node.GetTypedUrlSpecifics());
283 history::URLRow new_url(GURL(typed_url.url()));
284
285 new_url.set_title(base::UTF8ToUTF16(typed_url.title()));
286 DCHECK(typed_url.visits_size());
287 DCHECK_EQ(typed_url.visits_size(), typed_url.visit_transitions_size());
288 new_url.set_last_visit(base::Time::FromInternalValue(
289 typed_url.visits(typed_url.visits_size() - 1)));
290 new_url.set_hidden(typed_url.hidden());
291
292 urls->push_back(new_url);
293 child_id = child_node.GetSuccessorId();
294 }
295 }
296
297 void SetIdleChangeProcessorExpectations() {
298 EXPECT_CALL((history_backend()), SetPageTitle(_, _)).Times(0);
299 EXPECT_CALL((history_backend()), UpdateURL(_, _)).Times(0);
300 EXPECT_CALL((history_backend()), GetURL(_, _)).Times(0);
301 EXPECT_CALL((history_backend()), DeleteURL(_)).Times(0);
302 }
303
304 void SendNotification(const base::Closure& task) {
305 data_type_thread()->task_runner()->PostTaskAndReply(
306 FROM_HERE, task,
307 base::Bind(&base::MessageLoop::QuitNow,
308 base::Unretained(base::MessageLoop::current())));
309 base::RunLoop().Run();
310 }
311
312 void SendNotificationURLVisited(ui::PageTransition transition,
313 const history::URLRow& row) {
314 base::Time visit_time;
315 history::RedirectList redirects;
316 SendNotification(
317 base::Bind(&HistoryBackendNotifier::NotifyURLVisited,
318 base::Unretained(history_backend_.get()),
319 transition,
320 row,
321 redirects,
322 visit_time));
323 }
324
325 void SendNotificationURLsModified(const history::URLRows& rows) {
326 SendNotification(base::Bind(&HistoryBackendNotifier::NotifyURLsModified,
327 base::Unretained(history_backend_.get()),
328 rows));
329 }
330
331 void SendNotificationURLsDeleted(bool all_history,
332 bool expired,
333 const history::URLRows& deleted_rows,
334 const std::set<GURL>& favicon_urls) {
335 SendNotification(base::Bind(&HistoryBackendNotifier::NotifyURLsDeleted,
336 base::Unretained(history_backend_.get()),
337 all_history, expired, deleted_rows,
338 favicon_urls));
339 }
340
341 static bool URLsEqual(const history::URLRow& lhs,
342 const history::URLRow& rhs) {
343 // Only verify the fields we explicitly sync (i.e. don't verify typed_count
344 // or visit_count because we rely on the history DB to manage those values
345 // and they are left unchanged by HistoryBackendMock).
346 return (lhs.url().spec().compare(rhs.url().spec()) == 0) &&
347 (lhs.title().compare(rhs.title()) == 0) &&
348 (lhs.last_visit() == rhs.last_visit()) &&
349 (lhs.hidden() == rhs.hidden());
350 }
351
352 static history::URLRow MakeTypedUrlEntry(const char* url,
353 const char* title,
354 int typed_count,
355 int64_t last_visit,
356 bool hidden,
357 history::VisitVector* visits) {
358 // Give each URL a unique ID, to mimic the behavior of the real database.
359 static int unique_url_id = 0;
360 GURL gurl(url);
361 history::URLRow history_url(gurl, ++unique_url_id);
362 history_url.set_title(base::UTF8ToUTF16(title));
363 history_url.set_typed_count(typed_count);
364 history_url.set_last_visit(
365 base::Time::FromInternalValue(last_visit));
366 history_url.set_hidden(hidden);
367 visits->push_back(history::VisitRow(
368 history_url.id(), history_url.last_visit(), 0,
369 ui::PAGE_TRANSITION_TYPED, 0));
370 history_url.set_visit_count(visits->size());
371 return history_url;
372 }
373
374 base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
375 syncer::ModelType type) {
376 DCHECK_EQ(syncer::TYPED_URLS, type);
377 return syncable_service_->AsWeakPtr();
378 }
379
380 HistoryBackendMock& history_backend() { return *history_backend_.get(); }
381
382 private:
383 scoped_refptr<HistoryBackendMock> history_backend_;
384 std::unique_ptr<HistoryServiceMock> history_service_;
385 syncer::DataTypeErrorHandlerMock error_handler_;
386 std::unique_ptr<TestTypedUrlSyncableService> syncable_service_;
387 std::unique_ptr<sync_driver::FakeSyncClient> sync_client_;
388
389 DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceTypedUrlTest);
390 };
391
392 void AddTypedUrlEntries(ProfileSyncServiceTypedUrlTest* test,
393 const history::URLRows& entries) {
394 test->CreateRoot(syncer::TYPED_URLS);
395 for (size_t i = 0; i < entries.size(); ++i) {
396 history::VisitVector visits;
397 visits.push_back(history::VisitRow(
398 entries[i].id(), entries[i].last_visit(), 0,
399 ui::PageTransitionFromInt(0), 0));
400 test->AddTypedUrlSyncNode(entries[i], visits);
401 }
402 }
403
404 } // namespace
405
406 TEST_F(ProfileSyncServiceTypedUrlTest, EmptyNativeEmptySync) {
407 EXPECT_CALL((history_backend()), GetAllTypedURLs(_)).WillOnce(Return(true));
408 SetIdleChangeProcessorExpectations();
409 CreateRootHelper create_root(this, syncer::TYPED_URLS);
410 TypedUrlSyncableService* syncable_service =
411 StartSyncService(create_root.callback());
412 history::URLRows sync_entries;
413 GetTypedUrlsFromSyncDB(&sync_entries);
414 EXPECT_EQ(0U, sync_entries.size());
415 ASSERT_EQ(0, syncable_service->GetErrorPercentage());
416 }
417
418 TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeEmptySync) {
419 history::URLRows entries;
420 history::VisitVector visits;
421 entries.push_back(MakeTypedUrlEntry("http://foo.com", "bar",
422 2, 15, false, &visits));
423
424 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
425 .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
426 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
427 .WillRepeatedly(DoAll(SetArgumentPointee<2>(visits), Return(true)));
428 SetIdleChangeProcessorExpectations();
429 CreateRootHelper create_root(this, syncer::TYPED_URLS);
430 TypedUrlSyncableService* syncable_service =
431 StartSyncService(create_root.callback());
432 history::URLRows sync_entries;
433 GetTypedUrlsFromSyncDB(&sync_entries);
434 ASSERT_EQ(1U, sync_entries.size());
435 EXPECT_TRUE(URLsEqual(entries[0], sync_entries[0]));
436 ASSERT_EQ(0, syncable_service->GetErrorPercentage());
437 }
438
439 TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeErrorReadingVisits) {
440 history::URLRows entries;
441 history::VisitVector visits;
442 history::URLRow native_entry1(MakeTypedUrlEntry("http://foo.com", "bar",
443 2, 15, false, &visits));
444 history::URLRow native_entry2(MakeTypedUrlEntry("http://foo2.com", "bar",
445 3, 15, false, &visits));
446 entries.push_back(native_entry1);
447 entries.push_back(native_entry2);
448 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
449 .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
450 // Return an error from GetMostRecentVisitsForURL() for the second URL.
451 EXPECT_CALL((history_backend()),
452 GetMostRecentVisitsForURL(native_entry1.id(), _, _))
453 .WillRepeatedly(Return(true));
454 EXPECT_CALL((history_backend()),
455 GetMostRecentVisitsForURL(native_entry2.id(), _, _))
456 .WillRepeatedly(Return(false));
457 SetIdleChangeProcessorExpectations();
458 CreateRootHelper create_root(this, syncer::TYPED_URLS);
459 StartSyncService(create_root.callback());
460 history::URLRows sync_entries;
461 GetTypedUrlsFromSyncDB(&sync_entries);
462 ASSERT_EQ(1U, sync_entries.size());
463 EXPECT_TRUE(URLsEqual(native_entry1, sync_entries[0]));
464 }
465
466 TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeWithBlankEmptySync) {
467 std::vector<history::URLRow> entries;
468 history::VisitVector visits;
469 // Add an empty URL.
470 entries.push_back(MakeTypedUrlEntry("", "bar",
471 2, 15, false, &visits));
472 entries.push_back(MakeTypedUrlEntry("http://foo.com", "bar",
473 2, 15, false, &visits));
474 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
475 .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
476 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
477 .WillRepeatedly(DoAll(SetArgumentPointee<2>(visits), Return(true)));
478 SetIdleChangeProcessorExpectations();
479 CreateRootHelper create_root(this, syncer::TYPED_URLS);
480 StartSyncService(create_root.callback());
481 std::vector<history::URLRow> sync_entries;
482 GetTypedUrlsFromSyncDB(&sync_entries);
483 // The empty URL should be ignored.
484 ASSERT_EQ(1U, sync_entries.size());
485 EXPECT_TRUE(URLsEqual(entries[1], sync_entries[0]));
486 }
487
488 TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeHasSyncNoMerge) {
489 history::VisitVector native_visits;
490 history::VisitVector sync_visits;
491 history::URLRow native_entry(MakeTypedUrlEntry("http://native.com", "entry",
492 2, 15, false, &native_visits));
493 history::URLRow sync_entry(MakeTypedUrlEntry("http://sync.com", "entry",
494 3, 16, false, &sync_visits));
495
496 history::URLRows native_entries;
497 native_entries.push_back(native_entry);
498 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
499 .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
500 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
501 .WillRepeatedly(
502 DoAll(SetArgumentPointee<2>(native_visits), Return(true)));
503 EXPECT_CALL((history_backend()), AddVisits(_, _, history::SOURCE_SYNCED))
504 .WillRepeatedly(Return(true));
505
506 history::URLRows sync_entries;
507 sync_entries.push_back(sync_entry);
508
509 EXPECT_CALL((history_backend()), UpdateURL(_, _))
510 .WillRepeatedly(Return(true));
511 StartSyncService(base::Bind(&AddTypedUrlEntries, this, sync_entries));
512
513 std::map<std::string, history::URLRow> expected;
514 expected[native_entry.url().spec()] = native_entry;
515 expected[sync_entry.url().spec()] = sync_entry;
516
517 history::URLRows new_sync_entries;
518 GetTypedUrlsFromSyncDB(&new_sync_entries);
519
520 EXPECT_TRUE(new_sync_entries.size() == expected.size());
521 for (history::URLRows::iterator entry = new_sync_entries.begin();
522 entry != new_sync_entries.end(); ++entry) {
523 EXPECT_TRUE(URLsEqual(expected[entry->url().spec()], *entry));
524 }
525 }
526
527 TEST_F(ProfileSyncServiceTypedUrlTest, EmptyNativeExpiredSync) {
528 history::VisitVector sync_visits;
529 history::URLRow sync_entry(MakeTypedUrlEntry("http://sync.com", "entry",
530 3, EXPIRED_VISIT, false,
531 &sync_visits));
532 history::URLRows sync_entries;
533 sync_entries.push_back(sync_entry);
534
535 // Since all our URLs are expired, no backend calls to add new URLs will be
536 // made.
537 EXPECT_CALL((history_backend()), GetAllTypedURLs(_)).WillOnce(Return(true));
538 SetIdleChangeProcessorExpectations();
539
540 StartSyncService(base::Bind(&AddTypedUrlEntries, this, sync_entries));
541 }
542
543 TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeHasSyncMerge) {
544 history::VisitVector native_visits;
545 history::URLRow native_entry(MakeTypedUrlEntry("http://native.com", "entry",
546 2, 15, false, &native_visits));
547 history::VisitVector sync_visits;
548 history::URLRow sync_entry(MakeTypedUrlEntry("http://native.com", "name",
549 1, 17, false, &sync_visits));
550 history::VisitVector merged_visits;
551 merged_visits.push_back(history::VisitRow(
552 sync_entry.id(), base::Time::FromInternalValue(15), 0,
553 ui::PageTransitionFromInt(0), 0));
554
555 history::URLRow merged_entry(MakeTypedUrlEntry("http://native.com", "name",
556 2, 17, false, &merged_visits));
557
558 history::URLRows native_entries;
559 native_entries.push_back(native_entry);
560 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
561 .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
562 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
563 .WillRepeatedly(
564 DoAll(SetArgumentPointee<2>(native_visits), Return(true)));
565 EXPECT_CALL((history_backend()), AddVisits(_, _, history::SOURCE_SYNCED))
566 .WillRepeatedly(Return(true));
567
568 history::URLRows sync_entries;
569 sync_entries.push_back(sync_entry);
570
571 EXPECT_CALL((history_backend()), UpdateURL(_, _))
572 .WillRepeatedly(Return(true));
573 EXPECT_CALL((history_backend()), SetPageTitle(_, _)).WillRepeatedly(Return());
574 StartSyncService(base::Bind(&AddTypedUrlEntries, this, sync_entries));
575
576 history::URLRows new_sync_entries;
577 GetTypedUrlsFromSyncDB(&new_sync_entries);
578 ASSERT_EQ(1U, new_sync_entries.size());
579 EXPECT_TRUE(URLsEqual(merged_entry, new_sync_entries[0]));
580 }
581
582 TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeWithErrorHasSyncMerge) {
583 history::VisitVector native_visits;
584 history::URLRow native_entry(MakeTypedUrlEntry("http://native.com", "native",
585 2, 15, false, &native_visits));
586 history::VisitVector sync_visits;
587 history::URLRow sync_entry(MakeTypedUrlEntry("http://native.com", "sync",
588 1, 17, false, &sync_visits));
589
590 history::URLRows native_entries;
591 native_entries.push_back(native_entry);
592 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
593 .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
594 // Return an error getting the visits for the native URL.
595 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
596 .WillRepeatedly(Return(false));
597 EXPECT_CALL((history_backend()), GetURL(_, _))
598 .WillRepeatedly(DoAll(SetArgumentPointee<1>(native_entry), Return(true)));
599 EXPECT_CALL((history_backend()), AddVisits(_, _, history::SOURCE_SYNCED))
600 .WillRepeatedly(Return(true));
601
602 history::URLRows sync_entries;
603 sync_entries.push_back(sync_entry);
604
605 EXPECT_CALL((history_backend()), UpdateURL(_, _))
606 .WillRepeatedly(Return(true));
607 EXPECT_CALL((history_backend()), SetPageTitle(_, _)).WillRepeatedly(Return());
608 StartSyncService(base::Bind(&AddTypedUrlEntries, this, sync_entries));
609
610 history::URLRows new_sync_entries;
611 GetTypedUrlsFromSyncDB(&new_sync_entries);
612 ASSERT_EQ(1U, new_sync_entries.size());
613 EXPECT_TRUE(URLsEqual(sync_entry, new_sync_entries[0]));
614 }
615
616 TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeAdd) {
617 history::VisitVector added_visits;
618 history::URLRow added_entry(MakeTypedUrlEntry("http://added.com", "entry",
619 2, 15, false, &added_visits));
620
621 EXPECT_CALL((history_backend()), GetAllTypedURLs(_)).WillOnce(Return(true));
622 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
623 .WillOnce(DoAll(SetArgumentPointee<2>(added_visits), Return(true)));
624
625 SetIdleChangeProcessorExpectations();
626 CreateRootHelper create_root(this, syncer::TYPED_URLS);
627 StartSyncService(create_root.callback());
628
629 history::URLRows changed_urls;
630 changed_urls.push_back(added_entry);
631 SendNotificationURLsModified(changed_urls);
632
633 history::URLRows new_sync_entries;
634 GetTypedUrlsFromSyncDB(&new_sync_entries);
635 ASSERT_EQ(1U, new_sync_entries.size());
636 EXPECT_TRUE(URLsEqual(added_entry, new_sync_entries[0]));
637 }
638
639 TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeAddWithBlank) {
640 history::VisitVector added_visits;
641 history::URLRow empty_entry(MakeTypedUrlEntry("", "entry",
642 2, 15, false, &added_visits));
643 history::URLRow added_entry(MakeTypedUrlEntry("http://added.com", "entry",
644 2, 15, false, &added_visits));
645
646 EXPECT_CALL((history_backend()), GetAllTypedURLs(_)).WillOnce(Return(true));
647 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
648 .WillRepeatedly(DoAll(SetArgumentPointee<2>(added_visits), Return(true)));
649
650 SetIdleChangeProcessorExpectations();
651 CreateRootHelper create_root(this, syncer::TYPED_URLS);
652 StartSyncService(create_root.callback());
653
654 history::URLRows changed_urls;
655 changed_urls.push_back(empty_entry);
656 changed_urls.push_back(added_entry);
657 SendNotificationURLsModified(changed_urls);
658
659 std::vector<history::URLRow> new_sync_entries;
660 GetTypedUrlsFromSyncDB(&new_sync_entries);
661 ASSERT_EQ(1U, new_sync_entries.size());
662 EXPECT_TRUE(URLsEqual(added_entry, new_sync_entries[0]));
663 }
664
665 TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeUpdate) {
666 history::VisitVector original_visits;
667 history::URLRow original_entry(MakeTypedUrlEntry("http://mine.com", "entry",
668 2, 15, false,
669 &original_visits));
670 history::URLRows original_entries;
671 original_entries.push_back(original_entry);
672
673 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
674 .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
675 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
676 .WillOnce(DoAll(SetArgumentPointee<2>(original_visits), Return(true)));
677 CreateRootHelper create_root(this, syncer::TYPED_URLS);
678 StartSyncService(create_root.callback());
679
680 history::VisitVector updated_visits;
681 history::URLRow updated_entry(MakeTypedUrlEntry("http://mine.com", "entry",
682 7, 17, false,
683 &updated_visits));
684 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
685 .WillOnce(DoAll(SetArgumentPointee<2>(updated_visits), Return(true)));
686
687 history::URLRows changed_urls;
688 changed_urls.push_back(updated_entry);
689 SendNotificationURLsModified(changed_urls);
690
691 history::URLRows new_sync_entries;
692 GetTypedUrlsFromSyncDB(&new_sync_entries);
693 ASSERT_EQ(1U, new_sync_entries.size());
694 EXPECT_TRUE(URLsEqual(updated_entry, new_sync_entries[0]));
695 }
696
697 TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeAddFromVisit) {
698 history::VisitVector added_visits;
699 history::URLRow added_entry(MakeTypedUrlEntry("http://added.com", "entry",
700 2, 15, false, &added_visits));
701
702 EXPECT_CALL((history_backend()), GetAllTypedURLs(_)).WillOnce(Return(true));
703 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
704 .WillOnce(DoAll(SetArgumentPointee<2>(added_visits), Return(true)));
705
706 SetIdleChangeProcessorExpectations();
707 CreateRootHelper create_root(this, syncer::TYPED_URLS);
708 StartSyncService(create_root.callback());
709
710 SendNotificationURLVisited(ui::PAGE_TRANSITION_TYPED, added_entry);
711
712 history::URLRows new_sync_entries;
713 GetTypedUrlsFromSyncDB(&new_sync_entries);
714 ASSERT_EQ(1U, new_sync_entries.size());
715 EXPECT_TRUE(URLsEqual(added_entry, new_sync_entries[0]));
716 }
717
718 TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeUpdateFromVisit) {
719 history::VisitVector original_visits;
720 history::URLRow original_entry(MakeTypedUrlEntry("http://mine.com", "entry",
721 2, 15, false,
722 &original_visits));
723 history::URLRows original_entries;
724 original_entries.push_back(original_entry);
725
726 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
727 .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
728 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
729 .WillOnce(DoAll(SetArgumentPointee<2>(original_visits), Return(true)));
730 CreateRootHelper create_root(this, syncer::TYPED_URLS);
731 StartSyncService(create_root.callback());
732
733 history::VisitVector updated_visits;
734 history::URLRow updated_entry(MakeTypedUrlEntry("http://mine.com", "entry",
735 7, 17, false,
736 &updated_visits));
737 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
738 .WillOnce(DoAll(SetArgumentPointee<2>(updated_visits), Return(true)));
739
740 SendNotificationURLVisited(ui::PAGE_TRANSITION_TYPED, updated_entry);
741
742 history::URLRows new_sync_entries;
743 GetTypedUrlsFromSyncDB(&new_sync_entries);
744 ASSERT_EQ(1U, new_sync_entries.size());
745 EXPECT_TRUE(URLsEqual(updated_entry, new_sync_entries[0]));
746 }
747
748 TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserIgnoreChangeUpdateFromVisit) {
749 history::VisitVector original_visits;
750 history::URLRow original_entry(MakeTypedUrlEntry("http://mine.com", "entry",
751 2, 15, false,
752 &original_visits));
753 history::URLRows original_entries;
754 original_entries.push_back(original_entry);
755
756 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
757 .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
758 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
759 .WillRepeatedly(
760 DoAll(SetArgumentPointee<2>(original_visits), Return(true)));
761 CreateRootHelper create_root(this, syncer::TYPED_URLS);
762 StartSyncService(create_root.callback());
763 history::URLRows new_sync_entries;
764 GetTypedUrlsFromSyncDB(&new_sync_entries);
765 ASSERT_EQ(1U, new_sync_entries.size());
766 EXPECT_TRUE(URLsEqual(original_entry, new_sync_entries[0]));
767
768 history::VisitVector updated_visits;
769 history::URLRow updated_entry(MakeTypedUrlEntry("http://mine.com", "entry",
770 7, 15, false,
771 &updated_visits));
772
773 // Should ignore this change because it's not TYPED.
774 SendNotificationURLVisited(ui::PAGE_TRANSITION_RELOAD, updated_entry);
775 GetTypedUrlsFromSyncDB(&new_sync_entries);
776
777 // Should be no changes to the sync DB from this notification.
778 ASSERT_EQ(1U, new_sync_entries.size());
779 EXPECT_TRUE(URLsEqual(original_entry, new_sync_entries[0]));
780
781 // Now, try updating it with a large number of visits not divisible by 10
782 // (should ignore this visit).
783 history::URLRow twelve_visits(MakeTypedUrlEntry("http://mine.com", "entry",
784 12, 15, false,
785 &updated_visits));
786 SendNotificationURLVisited(ui::PAGE_TRANSITION_TYPED, twelve_visits);
787 GetTypedUrlsFromSyncDB(&new_sync_entries);
788
789 // Should be no changes to the sync DB from this notification.
790 ASSERT_EQ(1U, new_sync_entries.size());
791 EXPECT_TRUE(URLsEqual(original_entry, new_sync_entries[0]));
792
793 // Now, try updating it with a large number of visits that is divisible by 10
794 // (should *not* be ignored).
795 history::URLRow twenty_visits(MakeTypedUrlEntry("http://mine.com", "entry",
796 20, 15, false,
797 &updated_visits));
798 SendNotificationURLVisited(ui::PAGE_TRANSITION_TYPED, twenty_visits);
799 GetTypedUrlsFromSyncDB(&new_sync_entries);
800
801 ASSERT_EQ(1U, new_sync_entries.size());
802 EXPECT_TRUE(URLsEqual(twenty_visits, new_sync_entries[0]));
803 }
804
805 TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeRemove) {
806 history::VisitVector original_visits1;
807 history::URLRow original_entry1(MakeTypedUrlEntry("http://mine.com", "entry",
808 2, 15, false,
809 &original_visits1));
810 history::VisitVector original_visits2;
811 history::URLRow original_entry2(MakeTypedUrlEntry("http://mine2.com",
812 "entry2",
813 3, 15, false,
814 &original_visits2));
815 history::URLRows original_entries;
816 original_entries.push_back(original_entry1);
817 original_entries.push_back(original_entry2);
818
819 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
820 .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
821 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
822 .WillRepeatedly(
823 DoAll(SetArgumentPointee<2>(original_visits1), Return(true)));
824 CreateRootHelper create_root(this, syncer::TYPED_URLS);
825 StartSyncService(create_root.callback());
826
827 history::URLRows rows;
828 rows.push_back(history::URLRow(GURL("http://mine.com")));
829 SendNotificationURLsDeleted(false, false, rows, std::set<GURL>());
830 history::URLRows new_sync_entries;
831 GetTypedUrlsFromSyncDB(&new_sync_entries);
832 ASSERT_EQ(1U, new_sync_entries.size());
833 EXPECT_TRUE(URLsEqual(original_entry2, new_sync_entries[0]));
834 }
835
836 TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeRemoveExpired) {
837 history::VisitVector original_visits1;
838 history::URLRow original_entry1(MakeTypedUrlEntry("http://mine.com", "entry",
839 2, 15, false,
840 &original_visits1));
841 history::VisitVector original_visits2;
842 history::URLRow original_entry2(MakeTypedUrlEntry("http://mine2.com",
843 "entry2",
844 3, 15, false,
845 &original_visits2));
846 history::URLRows original_entries;
847 original_entries.push_back(original_entry1);
848 original_entries.push_back(original_entry2);
849
850 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
851 .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
852 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
853 .WillRepeatedly(
854 DoAll(SetArgumentPointee<2>(original_visits1), Return(true)));
855 CreateRootHelper create_root(this, syncer::TYPED_URLS);
856 StartSyncService(create_root.callback());
857
858 // Setting expired=true should cause the sync code to ignore this deletion.
859 history::URLRows rows;
860 rows.push_back(history::URLRow(GURL("http://mine.com")));
861 SendNotificationURLsDeleted(false, true, rows, std::set<GURL>());
862 history::URLRows new_sync_entries;
863 GetTypedUrlsFromSyncDB(&new_sync_entries);
864 // Both URLs should still be there.
865 ASSERT_EQ(2U, new_sync_entries.size());
866 }
867
868 TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeRemoveAll) {
869 history::VisitVector original_visits1;
870 history::URLRow original_entry1(MakeTypedUrlEntry("http://mine.com", "entry",
871 2, 15, false,
872 &original_visits1));
873 history::VisitVector original_visits2;
874 history::URLRow original_entry2(MakeTypedUrlEntry("http://mine2.com",
875 "entry2",
876 3, 15, false,
877 &original_visits2));
878 history::URLRows original_entries;
879 original_entries.push_back(original_entry1);
880 original_entries.push_back(original_entry2);
881
882 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
883 .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
884 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
885 .WillRepeatedly(
886 DoAll(SetArgumentPointee<2>(original_visits1), Return(true)));
887 CreateRootHelper create_root(this, syncer::TYPED_URLS);
888 StartSyncService(create_root.callback());
889
890 history::URLRows new_sync_entries;
891 GetTypedUrlsFromSyncDB(&new_sync_entries);
892 ASSERT_EQ(2U, new_sync_entries.size());
893
894 SendNotificationURLsDeleted(true, false, history::URLRows(),
895 std::set<GURL>());
896
897 GetTypedUrlsFromSyncDB(&new_sync_entries);
898 ASSERT_EQ(0U, new_sync_entries.size());
899 }
900
901 TEST_F(ProfileSyncServiceTypedUrlTest, FailWriteToHistoryBackend) {
902 history::VisitVector native_visits;
903 history::VisitVector sync_visits;
904 history::URLRow native_entry(MakeTypedUrlEntry("http://native.com", "entry",
905 2, 15, false, &native_visits));
906 history::URLRow sync_entry(MakeTypedUrlEntry("http://sync.com", "entry",
907 3, 16, false, &sync_visits));
908
909 history::URLRows native_entries;
910 native_entries.push_back(native_entry);
911 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
912 .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
913 EXPECT_CALL((history_backend()), GetURL(_, _))
914 .WillOnce(DoAll(SetArgumentPointee<1>(native_entry), Return(false)));
915 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
916 .WillRepeatedly(
917 DoAll(SetArgumentPointee<2>(native_visits), Return(true)));
918 EXPECT_CALL((history_backend()), AddVisits(_, _, history::SOURCE_SYNCED))
919 .WillRepeatedly(Return(false));
920
921 history::URLRows sync_entries;
922 sync_entries.push_back(sync_entry);
923
924 EXPECT_CALL((history_backend()), UpdateURL(_, _))
925 .WillRepeatedly(Return(false));
926 TypedUrlSyncableService* syncable_service =
927 StartSyncService(base::Bind(&AddTypedUrlEntries, this, sync_entries));
928 // Errors writing to the DB should be recorded, but should not cause an
929 // unrecoverable error.
930 ASSERT_FALSE(sync_service()->data_type_status_table().GetFailedTypes().Has(
931 syncer::TYPED_URLS));
932 // Some calls should have succeeded, so the error percentage should be
933 // somewhere > 0 and < 100.
934 ASSERT_NE(0, syncable_service->GetErrorPercentage());
935 ASSERT_NE(100, syncable_service->GetErrorPercentage());
936 }
937
938 TEST_F(ProfileSyncServiceTypedUrlTest, FailToGetTypedURLs) {
939 history::VisitVector native_visits;
940 history::VisitVector sync_visits;
941 history::URLRow native_entry(MakeTypedUrlEntry("http://native.com", "entry",
942 2, 15, false, &native_visits));
943 history::URLRow sync_entry(MakeTypedUrlEntry("http://sync.com", "entry",
944 3, 16, false, &sync_visits));
945
946 history::URLRows native_entries;
947 native_entries.push_back(native_entry);
948 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
949 .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(false)));
950
951 history::URLRows sync_entries;
952 sync_entries.push_back(sync_entry);
953
954 StartSyncService(base::Bind(&AddTypedUrlEntries, this, sync_entries));
955 // Errors getting typed URLs will cause an unrecoverable error (since we can
956 // do *nothing* in that case).
957 ASSERT_TRUE(sync_service()->data_type_status_table().GetFailedTypes().Has(
958 syncer::TYPED_URLS));
959 ASSERT_EQ(1u,
960 sync_service()->data_type_status_table().GetFailedTypes().Size());
961 // Can't check GetErrorPercentage(), because generating an unrecoverable
962 // error will free the model associator.
963 }
964
965 TEST_F(ProfileSyncServiceTypedUrlTest, IgnoreLocalFileURL) {
966 history::VisitVector original_visits;
967 // Create http and file url.
968 history::URLRow url_entry(MakeTypedUrlEntry("http://yey.com",
969 "yey", 12, 15, false,
970 &original_visits));
971 history::URLRow file_entry(MakeTypedUrlEntry("file:///kitty.jpg",
972 "kitteh", 12, 15, false,
973 &original_visits));
974
975 history::URLRows original_entries;
976 original_entries.push_back(url_entry);
977 original_entries.push_back(file_entry);
978
979 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
980 .WillRepeatedly(
981 DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
982 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
983 .WillRepeatedly(
984 DoAll(SetArgumentPointee<2>(original_visits), Return(true)));
985 CreateRootHelper create_root(this, syncer::TYPED_URLS);
986 StartSyncService(create_root.callback());
987
988 history::VisitVector updated_visits;
989 // Create updates for the previous urls + a new file one.
990 history::URLRow updated_url_entry(MakeTypedUrlEntry("http://yey.com",
991 "yey", 20, 15, false,
992 &updated_visits));
993 history::URLRow updated_file_entry(MakeTypedUrlEntry("file:///cat.jpg",
994 "cat", 20, 15, false,
995 &updated_visits));
996 history::URLRow new_file_entry(MakeTypedUrlEntry("file:///dog.jpg",
997 "dog", 20, 15, false,
998 &updated_visits));
999
1000 history::URLRows changed_urls;
1001 changed_urls.push_back(updated_url_entry);
1002 changed_urls.push_back(updated_file_entry);
1003 changed_urls.push_back(new_file_entry);
1004 SendNotificationURLsModified(changed_urls);
1005
1006 history::URLRows new_sync_entries;
1007 GetTypedUrlsFromSyncDB(&new_sync_entries);
1008
1009 // We should ignore the local file urls (existing and updated),
1010 // and only be left with the updated http url.
1011 ASSERT_EQ(1U, new_sync_entries.size());
1012 EXPECT_TRUE(URLsEqual(updated_url_entry, new_sync_entries[0]));
1013 }
1014
1015 TEST_F(ProfileSyncServiceTypedUrlTest, IgnoreLocalhostURL) {
1016 history::VisitVector original_visits;
1017 // Create http and localhost url.
1018 history::URLRow url_entry(MakeTypedUrlEntry("http://yey.com",
1019 "yey", 12, 15, false,
1020 &original_visits));
1021 history::URLRow localhost_entry(MakeTypedUrlEntry("http://localhost",
1022 "localhost", 12, 15, false,
1023 &original_visits));
1024
1025 history::URLRows original_entries;
1026 original_entries.push_back(url_entry);
1027 original_entries.push_back(localhost_entry);
1028
1029 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
1030 .WillRepeatedly(
1031 DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
1032 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
1033 .WillRepeatedly(
1034 DoAll(SetArgumentPointee<2>(original_visits), Return(true)));
1035 CreateRootHelper create_root(this, syncer::TYPED_URLS);
1036 StartSyncService(create_root.callback());
1037
1038 history::VisitVector updated_visits;
1039 // Update the previous entries and add a new localhost.
1040 history::URLRow updated_url_entry(MakeTypedUrlEntry("http://yey.com",
1041 "yey", 20, 15, false,
1042 &updated_visits));
1043 history::URLRow updated_localhost_entry(MakeTypedUrlEntry(
1044 "http://localhost:80",
1045 "localhost", 20, 15, false,
1046 &original_visits));
1047 history::URLRow localhost_ip_entry(MakeTypedUrlEntry("http://127.0.0.1",
1048 "localhost", 12, 15, false,
1049 &original_visits));
1050
1051 history::URLRows changed_urls;
1052 changed_urls.push_back(updated_url_entry);
1053 changed_urls.push_back(updated_localhost_entry);
1054 changed_urls.push_back(localhost_ip_entry);
1055 SendNotificationURLsModified(changed_urls);
1056
1057 history::URLRows new_sync_entries;
1058 GetTypedUrlsFromSyncDB(&new_sync_entries);
1059
1060 // We should ignore the localhost urls and left only with http url.
1061 ASSERT_EQ(1U, new_sync_entries.size());
1062 EXPECT_TRUE(URLsEqual(updated_url_entry, new_sync_entries[0]));
1063 }
1064
1065 TEST_F(ProfileSyncServiceTypedUrlTest, IgnoreModificationWithoutValidVisit) {
1066 EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
1067 .WillRepeatedly(Return(true));
1068 EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
1069 .WillRepeatedly(Return(true));
1070
1071 CreateRootHelper create_root(this, syncer::TYPED_URLS);
1072 StartSyncService(create_root.callback());
1073
1074 history::VisitVector updated_visits;
1075 history::URLRow updated_url_entry(MakeTypedUrlEntry("http://yey.com",
1076 "yey", 20, 0, false,
1077 &updated_visits));
1078
1079 history::URLRows changed_urls;
1080 changed_urls.push_back(updated_url_entry);
1081 SendNotificationURLsModified(changed_urls);
1082
1083 history::URLRows new_sync_entries;
1084 GetTypedUrlsFromSyncDB(&new_sync_entries);
1085
1086 // The change should be ignored.
1087 ASSERT_EQ(0U, new_sync_entries.size());
1088 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698