Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / test / integration / two_client_typed_urls_sync_test.cc
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 "base/i18n/number_formatting.h"
6 #include "base/memory/scoped_vector.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/sessions/session_service.h"
9 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
10 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
11 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
12 #include "chrome/browser/sync/test/integration/sync_test.h"
13 #include "chrome/browser/sync/test/integration/typed_urls_helper.h"
14 #include "components/history/core/browser/history_types.h"
15
16 using base::ASCIIToUTF16;
17 using sync_integration_test_util::AwaitCommitActivityCompletion;
18 using typed_urls_helper::AddUrlToHistory;
19 using typed_urls_helper::AddUrlToHistoryWithTimestamp;
20 using typed_urls_helper::AddUrlToHistoryWithTransition;
21 using typed_urls_helper::AreVisitsEqual;
22 using typed_urls_helper::AreVisitsUnique;
23 using typed_urls_helper::AwaitCheckAllProfilesHaveSameURLsAsVerifier;
24 using typed_urls_helper::CheckURLRowVectorsAreEqual;
25 using typed_urls_helper::DeleteUrlFromHistory;
26 using typed_urls_helper::GetTypedUrlsFromClient;
27 using typed_urls_helper::GetUrlFromClient;
28 using typed_urls_helper::GetVisitsFromClient;
29 using typed_urls_helper::RemoveVisitsFromClient;
30
31 class TwoClientTypedUrlsSyncTest : public SyncTest {
32  public:
33   TwoClientTypedUrlsSyncTest() : SyncTest(TWO_CLIENT) {}
34   ~TwoClientTypedUrlsSyncTest() override {}
35
36   ::testing::AssertionResult CheckClientsEqual() {
37     history::URLRows urls = GetTypedUrlsFromClient(0);
38     history::URLRows urls2 = GetTypedUrlsFromClient(1);
39     if (!CheckURLRowVectorsAreEqual(urls, urls2))
40       return ::testing::AssertionFailure() << "URLVectors are not equal";
41     // Now check the visits.
42     for (size_t i = 0; i < urls.size() && i < urls2.size(); i++) {
43       history::VisitVector visit1 = GetVisitsFromClient(0, urls[i].id());
44       history::VisitVector visit2 = GetVisitsFromClient(1, urls2[i].id());
45       if (!AreVisitsEqual(visit1, visit2))
46         return ::testing::AssertionFailure() << "Visits are not equal";
47     }
48     return ::testing::AssertionSuccess();
49   }
50
51   bool CheckNoDuplicateVisits() {
52     for (int i = 0; i < num_clients(); ++i) {
53       history::URLRows urls = GetTypedUrlsFromClient(i);
54       for (size_t j = 0; j < urls.size(); ++j) {
55         history::VisitVector visits = GetVisitsFromClient(i, urls[j].id());
56         if (!AreVisitsUnique(visits))
57           return false;
58       }
59     }
60     return true;
61   }
62
63   int GetVisitCountForFirstURL(int index) {
64     history::URLRows urls = GetTypedUrlsFromClient(index);
65     if (urls.size() == 0)
66       return 0;
67     else
68       return urls[0].visit_count();
69   }
70
71  private:
72   DISALLOW_COPY_AND_ASSIGN(TwoClientTypedUrlsSyncTest);
73 };
74
75 // TCM: 3728323
76 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest, Add) {
77   const base::string16 kHistoryUrl(
78       ASCIIToUTF16("http://www.add-one-history.google.com/"));
79   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
80
81   // Populate one client with a URL, should sync to the other.
82   GURL new_url(kHistoryUrl);
83   AddUrlToHistory(0, new_url);
84   history::URLRows urls = GetTypedUrlsFromClient(0);
85   ASSERT_EQ(1U, urls.size());
86   ASSERT_EQ(new_url, urls[0].url());
87
88   // Both clients should have this URL.
89   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
90 }
91
92 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest, AddExpired) {
93   const base::string16 kHistoryUrl(
94       ASCIIToUTF16("http://www.add-one-history.google.com/"));
95   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
96
97   // Populate one client with a URL, should sync to the other.
98   GURL new_url(kHistoryUrl);
99   // Create a URL with a timestamp 1 year before today.
100   base::Time timestamp = base::Time::Now() - base::TimeDelta::FromDays(365);
101   AddUrlToHistoryWithTimestamp(0,
102                                new_url,
103                                ui::PAGE_TRANSITION_TYPED,
104                                history::SOURCE_BROWSED,
105                                timestamp);
106   history::URLRows urls = GetTypedUrlsFromClient(0);
107   ASSERT_EQ(1U, urls.size());
108   ASSERT_EQ(new_url, urls[0].url());
109
110   // Let sync finish.
111   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
112
113   // Second client should still have no URLs since this one is expired.
114   urls = GetTypedUrlsFromClient(1);
115   ASSERT_EQ(0U, urls.size());
116 }
117
118 // Flake on mac: http://crbug/115526
119 #if defined(OS_MACOSX)
120 #define MAYBE_AddExpiredThenUpdate DISABLED_AddExpiredThenUpdate
121 #else
122 #define MAYBE_AddExpiredThenUpdate AddExpiredThenUpdate
123 #endif
124 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest, MAYBE_AddExpiredThenUpdate) {
125   const base::string16 kHistoryUrl(
126       ASCIIToUTF16("http://www.add-one-history.google.com/"));
127   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
128
129   // Populate one client with a URL, should sync to the other.
130   GURL new_url(kHistoryUrl);
131   // Create a URL with a timestamp 1 year before today.
132   base::Time timestamp = base::Time::Now() - base::TimeDelta::FromDays(365);
133   AddUrlToHistoryWithTimestamp(0,
134                                new_url,
135                                ui::PAGE_TRANSITION_TYPED,
136                                history::SOURCE_BROWSED,
137                                timestamp);
138   std::vector<history::URLRow> urls = GetTypedUrlsFromClient(0);
139   ASSERT_EQ(1U, urls.size());
140   ASSERT_EQ(new_url, urls[0].url());
141
142   // Let sync finish.
143   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
144
145   // Second client should still have no URLs since this one is expired.
146   urls = GetTypedUrlsFromClient(1);
147   ASSERT_EQ(0U, urls.size());
148
149   // Now drive an update on the first client.
150   AddUrlToHistory(0, new_url);
151
152   // Let sync finish again.
153   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
154
155   // Second client should have the URL now.
156   urls = GetTypedUrlsFromClient(1);
157   ASSERT_EQ(1U, urls.size());
158 }
159
160 // TCM: 3705291
161 // flaky, see crbug.com/108511
162 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest, DISABLED_AddThenDelete) {
163   const base::string16 kHistoryUrl(
164       ASCIIToUTF16("http://www.add-one-history.google.com/"));
165   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
166
167   // Populate one client with a URL, should sync to the other.
168   GURL new_url(kHistoryUrl);
169   AddUrlToHistory(0, new_url);
170   history::URLRows urls = GetTypedUrlsFromClient(0);
171   ASSERT_EQ(1U, urls.size());
172   ASSERT_EQ(new_url, urls[0].url());
173
174   // Both clients should have this URL.
175   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
176
177   // Delete from first client, should delete from second.
178   DeleteUrlFromHistory(0, new_url);
179
180   // Neither client should have this URL.
181   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
182 }
183
184 // TCM: 3643277
185 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest, DisableEnableSync) {
186   const base::string16 kUrl1(ASCIIToUTF16("http://history1.google.com/"));
187   const base::string16 kUrl2(ASCIIToUTF16("http://history2.google.com/"));
188   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
189
190   // Disable typed url sync for one client, leave it active for the other.
191   GetClient(0)->DisableSyncForDatatype(syncer::TYPED_URLS);
192
193   // Add one URL to non-syncing client, add a different URL to the other,
194   // wait for sync cycle to complete. No data should be exchanged.
195   GURL url1(kUrl1);
196   GURL url2(kUrl2);
197   AddUrlToHistory(0, url1);
198   AddUrlToHistory(1, url2);
199   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((1))));
200
201   // Make sure that no data was exchanged.
202   history::URLRows post_sync_urls = GetTypedUrlsFromClient(0);
203   ASSERT_EQ(1U, post_sync_urls.size());
204   ASSERT_EQ(url1, post_sync_urls[0].url());
205   post_sync_urls = GetTypedUrlsFromClient(1);
206   ASSERT_EQ(1U, post_sync_urls.size());
207   ASSERT_EQ(url2, post_sync_urls[0].url());
208
209   // Enable typed url sync, make both URLs are synced to each client.
210   GetClient(0)->EnableSyncForDatatype(syncer::TYPED_URLS);
211
212   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
213 }
214
215 // flaky, see crbug.com/108511
216 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest, DISABLED_AddOneDeleteOther) {
217   const base::string16 kHistoryUrl(
218       ASCIIToUTF16("http://www.add-one-delete-history.google.com/"));
219   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
220
221   // Populate one client with a URL, should sync to the other.
222   GURL new_url(kHistoryUrl);
223   AddUrlToHistory(0, new_url);
224   history::URLRows urls = GetTypedUrlsFromClient(0);
225   ASSERT_EQ(1U, urls.size());
226   ASSERT_EQ(new_url, urls[0].url());
227
228   // Both clients should have this URL.
229   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
230
231   // Now, delete the URL from the second client.
232   DeleteUrlFromHistory(1, new_url);
233   urls = GetTypedUrlsFromClient(0);
234   ASSERT_EQ(1U, urls.size());
235
236   // Both clients should have this URL removed.
237   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
238 }
239
240 // flaky, see crbug.com/108511
241 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest,
242                        DISABLED_AddOneDeleteOtherAddAgain) {
243   const base::string16 kHistoryUrl(
244       ASCIIToUTF16("http://www.add-delete-add-history.google.com/"));
245   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
246
247   // Populate one client with a URL, should sync to the other.
248   GURL new_url(kHistoryUrl);
249   AddUrlToHistory(0, new_url);
250   history::URLRows urls = GetTypedUrlsFromClient(0);
251   ASSERT_EQ(1U, urls.size());
252   ASSERT_EQ(new_url, urls[0].url());
253
254   // Both clients should have this URL.
255   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
256
257   // Now, delete the URL from the second client.
258   DeleteUrlFromHistory(1, new_url);
259   urls = GetTypedUrlsFromClient(0);
260   ASSERT_EQ(1U, urls.size());
261
262   // Both clients should have this URL removed.
263   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
264
265   // Add it to the first client again, should succeed (tests that the deletion
266   // properly disassociates that URL).
267   AddUrlToHistory(0, new_url);
268
269   // Both clients should have this URL added again.
270   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
271 }
272
273 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest,
274                        MergeTypedWithNonTypedDuringAssociation) {
275   ASSERT_TRUE(SetupClients());
276   GURL new_url("http://history.com");
277   base::Time timestamp = base::Time::Now();
278   // Put a non-typed URL in both clients with an identical timestamp.
279   // Then add a typed URL to the second client - this test makes sure that
280   // we properly merge both sets of visits together to end up with the same
281   // set of visits on both ends.
282   AddUrlToHistoryWithTimestamp(0, new_url, ui::PAGE_TRANSITION_LINK,
283                                history::SOURCE_BROWSED, timestamp);
284   AddUrlToHistoryWithTimestamp(1, new_url, ui::PAGE_TRANSITION_LINK,
285                                history::SOURCE_BROWSED, timestamp);
286   AddUrlToHistoryWithTimestamp(1, new_url, ui::PAGE_TRANSITION_TYPED,
287                                history::SOURCE_BROWSED,
288                                timestamp + base::TimeDelta::FromSeconds(1));
289
290   // Now start up sync - URLs should get merged. Fully sync client 1 first,
291   // before syncing client 0, so we have both of client 1's URLs in the sync DB
292   // at the time that client 0 does model association.
293   ASSERT_TRUE(GetClient(1)->SetupSync()) << "SetupSync() failed";
294   AwaitCommitActivityCompletion(GetSyncService((1)));
295   ASSERT_TRUE(GetClient(0)->SetupSync()) << "SetupSync() failed";
296   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
297
298   ASSERT_TRUE(CheckClientsEqual());
299   // At this point, we should have no duplicates (total visit count should be
300   // 2). We only need to check client 0 since we already verified that both
301   // clients are identical above.
302   history::URLRows urls = GetTypedUrlsFromClient(0);
303   ASSERT_EQ(1U, urls.size());
304   ASSERT_EQ(new_url, urls[0].url());
305   ASSERT_TRUE(CheckNoDuplicateVisits());
306   ASSERT_EQ(2, GetVisitCountForFirstURL(0));
307 }
308
309 // Tests transitioning a URL from non-typed to typed when both clients
310 // have already seen that URL (so a merge is required).
311 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest,
312                        MergeTypedWithNonTypedDuringChangeProcessing) {
313   ASSERT_TRUE(SetupClients());
314   GURL new_url("http://history.com");
315   base::Time timestamp = base::Time::Now();
316   // Setup both clients with the identical typed URL visit. This means we can't
317   // use the verifier in this test, because this will show up as two distinct
318   // visits in the verifier.
319   AddUrlToHistoryWithTimestamp(0, new_url, ui::PAGE_TRANSITION_LINK,
320                                history::SOURCE_BROWSED, timestamp);
321   AddUrlToHistoryWithTimestamp(1, new_url, ui::PAGE_TRANSITION_LINK,
322                                history::SOURCE_BROWSED, timestamp);
323
324   // Now start up sync. Neither URL should get synced as they do not look like
325   // typed URLs.
326   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
327   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
328   ASSERT_TRUE(CheckClientsEqual());
329   history::URLRows urls = GetTypedUrlsFromClient(0);
330   ASSERT_EQ(0U, urls.size());
331
332   // Now, add a typed visit to the first client.
333   AddUrlToHistoryWithTimestamp(0, new_url, ui::PAGE_TRANSITION_TYPED,
334                                history::SOURCE_BROWSED,
335                                timestamp + base::TimeDelta::FromSeconds(1));
336
337   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
338   ASSERT_TRUE(CheckClientsEqual());
339   ASSERT_TRUE(CheckNoDuplicateVisits());
340   urls = GetTypedUrlsFromClient(0);
341   ASSERT_EQ(1U, urls.size());
342   ASSERT_EQ(2, GetVisitCountForFirstURL(0));
343   ASSERT_EQ(2, GetVisitCountForFirstURL(1));
344 }
345
346 // Tests transitioning a URL from non-typed to typed when one of the clients
347 // has never seen that URL before (so no merge is necessary).
348 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest, UpdateToNonTypedURL) {
349   const base::string16 kHistoryUrl(
350       ASCIIToUTF16("http://www.add-delete-add-history.google.com/"));
351   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
352
353   // Populate one client with a non-typed URL, should not be synced.
354   GURL new_url(kHistoryUrl);
355   AddUrlToHistoryWithTransition(0, new_url, ui::PAGE_TRANSITION_LINK,
356                                 history::SOURCE_BROWSED);
357   history::URLRows urls = GetTypedUrlsFromClient(0);
358   ASSERT_EQ(0U, urls.size());
359
360   // Both clients should have 0 typed URLs.
361   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
362   urls = GetTypedUrlsFromClient(0);
363   ASSERT_EQ(0U, urls.size());
364
365   // Now, add a typed visit to this URL.
366   AddUrlToHistory(0, new_url);
367
368   // Let sync finish.
369   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
370
371   // Both clients should have this URL as typed and have two visits synced up.
372   ASSERT_TRUE(CheckClientsEqual());
373   urls = GetTypedUrlsFromClient(0);
374   ASSERT_EQ(1U, urls.size());
375   ASSERT_EQ(new_url, urls[0].url());
376   ASSERT_EQ(2, GetVisitCountForFirstURL(0));
377 }
378
379 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest,
380                        SkipImportedVisits) {
381
382   GURL imported_url("http://imported_url.com");
383   GURL browsed_url("http://browsed_url.com");
384   GURL browsed_and_imported_url("http://browsed_and_imported_url.com");
385   ASSERT_TRUE(SetupClients());
386
387   // Create 3 items in our first client - 1 imported, one browsed, one with
388   // both imported and browsed entries.
389   AddUrlToHistoryWithTransition(0, imported_url,
390                                 ui::PAGE_TRANSITION_TYPED,
391                                 history::SOURCE_FIREFOX_IMPORTED);
392   AddUrlToHistoryWithTransition(0, browsed_url,
393                                 ui::PAGE_TRANSITION_TYPED,
394                                 history::SOURCE_BROWSED);
395   AddUrlToHistoryWithTransition(0, browsed_and_imported_url,
396                                 ui::PAGE_TRANSITION_TYPED,
397                                 history::SOURCE_FIREFOX_IMPORTED);
398
399   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
400   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
401   history::URLRows urls = GetTypedUrlsFromClient(1);
402   ASSERT_EQ(1U, urls.size());
403   ASSERT_EQ(browsed_url, urls[0].url());
404
405   // Now browse to 3rd URL - this should cause it to be synced, even though it
406   // was initially imported.
407   AddUrlToHistoryWithTransition(0, browsed_and_imported_url,
408                                 ui::PAGE_TRANSITION_TYPED,
409                                 history::SOURCE_BROWSED);
410   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
411   urls = GetTypedUrlsFromClient(1);
412   ASSERT_EQ(2U, urls.size());
413
414   // Make sure the imported URL didn't make it over.
415   for (size_t i = 0; i < urls.size(); ++i) {
416     ASSERT_NE(imported_url, urls[i].url());
417   }
418 }
419
420 IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest, BookmarksWithTypedVisit) {
421   GURL bookmark_url("http://www.bookmark.google.com/");
422   GURL bookmark_icon_url("http://www.bookmark.google.com/favicon.ico");
423   ASSERT_TRUE(SetupClients());
424   // Create a bookmark.
425   const BookmarkNode* node = bookmarks_helper::AddURL(
426       0, bookmarks_helper::IndexedURLTitle(0), bookmark_url);
427   bookmarks_helper::SetFavicon(0, node, bookmark_icon_url,
428       bookmarks_helper::CreateFavicon(SK_ColorWHITE),
429       bookmarks_helper::FROM_UI);
430   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
431
432   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
433   // A row in the DB for client 1 should have been created as a result of the
434   // sync.
435   history::URLRow row;
436   ASSERT_TRUE(GetUrlFromClient(1, bookmark_url, &row));
437
438   // Now, add a typed visit for client 0 to the bookmark URL and sync it over
439   // - this should not cause a crash.
440   AddUrlToHistory(0, bookmark_url);
441   ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
442
443   ASSERT_TRUE(AwaitCheckAllProfilesHaveSameURLsAsVerifier());
444   history::URLRows urls = GetTypedUrlsFromClient(0);
445   ASSERT_EQ(1U, urls.size());
446   ASSERT_EQ(bookmark_url, urls[0].url());
447   ASSERT_EQ(1, GetVisitCountForFirstURL(0));
448 }