BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / chrome / browser / sync / test / integration / single_client_bookmarks_sync_test.cc
blob80587fc19d09952d8044183ed00a24ec49bd5a32
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.
5 #include "base/strings/utf_string_conversions.h"
6 #include "chrome/browser/profiles/profile.h"
7 #include "chrome/browser/sync/profile_sync_service.h"
8 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
9 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
10 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
11 #include "chrome/browser/sync/test/integration/sync_test.h"
12 #include "components/bookmarks/browser/bookmark_model.h"
13 #include "sync/test/fake_server/bookmark_entity_builder.h"
14 #include "sync/test/fake_server/entity_builder_factory.h"
15 #include "sync/test/fake_server/fake_server_verifier.h"
16 #include "sync/test/fake_server/tombstone_entity.h"
17 #include "ui/base/layout.h"
19 using bookmarks::BookmarkModel;
20 using bookmarks::BookmarkNode;
21 using bookmarks_helper::AddFolder;
22 using bookmarks_helper::AddURL;
23 using bookmarks_helper::AwaitCountBookmarksWithTitlesMatching;
24 using bookmarks_helper::AwaitCountBookmarksWithUrlsMatching;
25 using bookmarks_helper::CountBookmarksWithTitlesMatching;
26 using bookmarks_helper::CountBookmarksWithUrlsMatching;
27 using bookmarks_helper::CountFoldersWithTitlesMatching;
28 using bookmarks_helper::Create1xFaviconFromPNGFile;
29 using bookmarks_helper::GetBookmarkBarNode;
30 using bookmarks_helper::GetBookmarkModel;
31 using bookmarks_helper::GetOtherNode;
32 using bookmarks_helper::ModelMatchesVerifier;
33 using bookmarks_helper::Move;
34 using bookmarks_helper::Remove;
35 using bookmarks_helper::RemoveAll;
36 using bookmarks_helper::SetFavicon;
37 using bookmarks_helper::SetTitle;
38 using sync_integration_test_util::AwaitCommitActivityCompletion;
40 // All tests in this file utilize a single profile.
41 // TODO(pvalenzuela): Standardize this pattern by moving this constant to
42 // SyncTest and using it in all single client tests.
43 const int kSingleProfileIndex = 0;
45 class SingleClientBookmarksSyncTest : public SyncTest {
46 public:
47 SingleClientBookmarksSyncTest() : SyncTest(SINGLE_CLIENT) {}
48 ~SingleClientBookmarksSyncTest() override {}
50 // Verify that the local bookmark model (for the Profile corresponding to
51 // |index|) matches the data on the FakeServer. It is assumed that FakeServer
52 // is being used and each bookmark has a unique title. Folders are not
53 // verified.
54 void VerifyBookmarkModelMatchesFakeServer(int index);
56 private:
57 DISALLOW_COPY_AND_ASSIGN(SingleClientBookmarksSyncTest);
60 void SingleClientBookmarksSyncTest::VerifyBookmarkModelMatchesFakeServer(
61 int index) {
62 fake_server::FakeServerVerifier fake_server_verifier(GetFakeServer());
63 std::vector<BookmarkModel::URLAndTitle> local_bookmarks;
64 GetBookmarkModel(index)->GetBookmarks(&local_bookmarks);
66 // Verify that all local bookmark titles exist once on the server.
67 std::vector<BookmarkModel::URLAndTitle>::const_iterator it;
68 for (it = local_bookmarks.begin(); it != local_bookmarks.end(); ++it) {
69 ASSERT_TRUE(fake_server_verifier.VerifyEntityCountByTypeAndName(
71 syncer::BOOKMARKS,
72 base::UTF16ToUTF8(it->title)));
76 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, Sanity) {
77 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
79 // Starting state:
80 // other_node
81 // -> top
82 // -> tier1_a
83 // -> http://mail.google.com "tier1_a_url0"
84 // -> http://www.pandora.com "tier1_a_url1"
85 // -> http://www.facebook.com "tier1_a_url2"
86 // -> tier1_b
87 // -> http://www.nhl.com "tier1_b_url0"
88 const BookmarkNode* top = AddFolder(
89 kSingleProfileIndex, GetOtherNode(kSingleProfileIndex), 0, "top");
90 const BookmarkNode* tier1_a = AddFolder(
91 kSingleProfileIndex, top, 0, "tier1_a");
92 const BookmarkNode* tier1_b = AddFolder(
93 kSingleProfileIndex, top, 1, "tier1_b");
94 const BookmarkNode* tier1_a_url0 = AddURL(
95 kSingleProfileIndex, tier1_a, 0, "tier1_a_url0",
96 GURL("http://mail.google.com"));
97 const BookmarkNode* tier1_a_url1 = AddURL(
98 kSingleProfileIndex, tier1_a, 1, "tier1_a_url1",
99 GURL("http://www.pandora.com"));
100 const BookmarkNode* tier1_a_url2 = AddURL(
101 kSingleProfileIndex, tier1_a, 2, "tier1_a_url2",
102 GURL("http://www.facebook.com"));
103 const BookmarkNode* tier1_b_url0 = AddURL(
104 kSingleProfileIndex, tier1_b, 0, "tier1_b_url0",
105 GURL("http://www.nhl.com"));
107 // Setup sync, wait for its completion, and make sure changes were synced.
108 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
109 ASSERT_TRUE(AwaitCommitActivityCompletion(
110 GetSyncService((kSingleProfileIndex))));
111 ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex));
113 // Ultimately we want to end up with the following model; but this test is
114 // more about the journey than the destination.
116 // bookmark_bar
117 // -> CNN (www.cnn.com)
118 // -> tier1_a
119 // -> tier1_a_url2 (www.facebook.com)
120 // -> tier1_a_url1 (www.pandora.com)
121 // -> Porsche (www.porsche.com)
122 // -> Bank of America (www.bankofamerica.com)
123 // -> Seattle Bubble
124 // other_node
125 // -> top
126 // -> tier1_b
127 // -> Wired News (www.wired.com)
128 // -> tier2_b
129 // -> tier1_b_url0
130 // -> tier3_b
131 // -> Toronto Maple Leafs (mapleleafs.nhl.com)
132 // -> Wynn (www.wynnlasvegas.com)
133 // -> tier1_a_url0
134 const BookmarkNode* bar = GetBookmarkBarNode(kSingleProfileIndex);
135 const BookmarkNode* cnn = AddURL(
136 kSingleProfileIndex, bar, 0, "CNN", GURL("http://www.cnn.com"));
137 ASSERT_TRUE(cnn != NULL);
138 Move(kSingleProfileIndex, tier1_a, bar, 1);
140 // Wait for the bookmark position change to sync.
141 ASSERT_TRUE(AwaitCommitActivityCompletion(
142 GetSyncService((kSingleProfileIndex))));
143 ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex));
145 const BookmarkNode* porsche = AddURL(
146 kSingleProfileIndex, bar, 2, "Porsche", GURL("http://www.porsche.com"));
147 // Rearrange stuff in tier1_a.
148 ASSERT_EQ(tier1_a, tier1_a_url2->parent());
149 ASSERT_EQ(tier1_a, tier1_a_url1->parent());
150 Move(kSingleProfileIndex, tier1_a_url2, tier1_a, 0);
151 Move(kSingleProfileIndex, tier1_a_url1, tier1_a, 2);
153 // Wait for the rearranged hierarchy to sync.
154 ASSERT_TRUE(AwaitCommitActivityCompletion(
155 GetSyncService((kSingleProfileIndex))));
156 ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex));
158 ASSERT_EQ(1, tier1_a_url0->parent()->GetIndexOf(tier1_a_url0));
159 Move(kSingleProfileIndex, tier1_a_url0, bar, bar->child_count());
160 const BookmarkNode* boa = AddURL(
161 kSingleProfileIndex, bar, bar->child_count(),
162 "Bank of America", GURL("https://www.bankofamerica.com"));
163 ASSERT_TRUE(boa != NULL);
164 Move(kSingleProfileIndex, tier1_a_url0, top, top->child_count());
165 const BookmarkNode* bubble = AddURL(
166 kSingleProfileIndex, bar, bar->child_count(), "Seattle Bubble",
167 GURL("http://seattlebubble.com"));
168 ASSERT_TRUE(bubble != NULL);
169 const BookmarkNode* wired = AddURL(
170 kSingleProfileIndex, bar, 2, "Wired News", GURL("http://www.wired.com"));
171 const BookmarkNode* tier2_b = AddFolder(
172 kSingleProfileIndex, tier1_b, 0, "tier2_b");
173 Move(kSingleProfileIndex, tier1_b_url0, tier2_b, 0);
174 Move(kSingleProfileIndex, porsche, bar, 0);
175 SetTitle(kSingleProfileIndex, wired, "News Wired");
176 SetTitle(kSingleProfileIndex, porsche, "ICanHazPorsche?");
178 // Wait for the title change to sync.
179 ASSERT_TRUE(AwaitCommitActivityCompletion(
180 GetSyncService((kSingleProfileIndex))));
181 ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex));
183 ASSERT_EQ(tier1_a_url0->id(), top->GetChild(top->child_count() - 1)->id());
184 Remove(kSingleProfileIndex, top, top->child_count() - 1);
185 Move(kSingleProfileIndex, wired, tier1_b, 0);
186 Move(kSingleProfileIndex, porsche, bar, 3);
187 const BookmarkNode* tier3_b = AddFolder(
188 kSingleProfileIndex, tier2_b, 1, "tier3_b");
189 const BookmarkNode* leafs = AddURL(
190 kSingleProfileIndex, tier1_a, 0, "Toronto Maple Leafs",
191 GURL("http://mapleleafs.nhl.com"));
192 const BookmarkNode* wynn = AddURL(
193 kSingleProfileIndex, bar, 1, "Wynn", GURL("http://www.wynnlasvegas.com"));
195 Move(kSingleProfileIndex, wynn, tier3_b, 0);
196 Move(kSingleProfileIndex, leafs, tier3_b, 0);
198 // Wait for newly added bookmarks to sync.
199 ASSERT_TRUE(AwaitCommitActivityCompletion(
200 GetSyncService((kSingleProfileIndex))));
201 ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex));
203 // Only verify FakeServer data if FakeServer is being used.
204 // TODO(pvalenzuela): Use this style of verification in more tests once it is
205 // proven stable.
206 if (GetFakeServer())
207 VerifyBookmarkModelMatchesFakeServer(kSingleProfileIndex);
210 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, InjectedBookmark) {
211 std::string title = "Montreal Canadiens";
212 fake_server::EntityBuilderFactory entity_builder_factory;
213 fake_server::BookmarkEntityBuilder bookmark_builder =
214 entity_builder_factory.NewBookmarkEntityBuilder(title);
215 fake_server_->InjectEntity(bookmark_builder.BuildBookmark(
216 GURL("http://canadiens.nhl.com")));
218 DisableVerifier();
219 ASSERT_TRUE(SetupClients());
220 ASSERT_TRUE(SetupSync());
222 ASSERT_EQ(1, CountBookmarksWithTitlesMatching(kSingleProfileIndex, title));
225 // Test that a client doesn't mutate the favicon data in the process
226 // of storing the favicon data from sync to the database or in the process
227 // of requesting data from the database for sync.
228 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest,
229 SetFaviconHiDPIDifferentCodec) {
230 // Set the supported scale factors to 1x and 2x such that
231 // BookmarkModel::GetFavicon() requests both 1x and 2x.
232 // 1x -> for sync, 2x -> for the UI.
233 std::vector<ui::ScaleFactor> supported_scale_factors;
234 supported_scale_factors.push_back(ui::SCALE_FACTOR_100P);
235 supported_scale_factors.push_back(ui::SCALE_FACTOR_200P);
236 ui::SetSupportedScaleFactors(supported_scale_factors);
238 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
239 ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex));
241 const GURL page_url("http://www.google.com");
242 const GURL icon_url("http://www.google.com/favicon.ico");
243 const BookmarkNode* bookmark = AddURL(kSingleProfileIndex, "title", page_url);
245 // Simulate receiving a favicon from sync encoded by a different PNG encoder
246 // than the one native to the OS. This tests the PNG data is not decoded to
247 // SkBitmap (or any other image format) then encoded back to PNG on the path
248 // between sync and the database.
249 gfx::Image original_favicon = Create1xFaviconFromPNGFile(
250 "favicon_cocoa_png_codec.png");
251 ASSERT_FALSE(original_favicon.IsEmpty());
252 SetFavicon(kSingleProfileIndex, bookmark, icon_url, original_favicon,
253 bookmarks_helper::FROM_SYNC);
255 ASSERT_TRUE(AwaitCommitActivityCompletion(
256 GetSyncService((kSingleProfileIndex))));
257 ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex));
259 scoped_refptr<base::RefCountedMemory> original_favicon_bytes =
260 original_favicon.As1xPNGBytes();
261 gfx::Image final_favicon =
262 GetBookmarkModel(kSingleProfileIndex)->GetFavicon(bookmark);
263 scoped_refptr<base::RefCountedMemory> final_favicon_bytes =
264 final_favicon.As1xPNGBytes();
266 // Check that the data was not mutated from the original.
267 EXPECT_TRUE(original_favicon_bytes.get());
268 EXPECT_TRUE(original_favicon_bytes->Equals(final_favicon_bytes));
271 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest,
272 BookmarkAllNodesRemovedEvent) {
273 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
274 // Starting state:
275 // other_node
276 // -> folder0
277 // -> tier1_a
278 // -> http://mail.google.com
279 // -> http://www.google.com
280 // -> http://news.google.com
281 // -> http://yahoo.com
282 // -> http://www.cnn.com
283 // bookmark_bar
284 // -> empty_folder
285 // -> folder1
286 // -> http://yahoo.com
287 // -> http://gmail.com
289 const BookmarkNode* folder0 = AddFolder(
290 kSingleProfileIndex, GetOtherNode(kSingleProfileIndex), 0, "folder0");
291 const BookmarkNode* tier1_a = AddFolder(
292 kSingleProfileIndex, folder0, 0, "tier1_a");
293 ASSERT_TRUE(AddURL(
294 kSingleProfileIndex, folder0, 1, "News", GURL("http://news.google.com")));
295 ASSERT_TRUE(AddURL(
296 kSingleProfileIndex, folder0, 2, "Yahoo", GURL("http://www.yahoo.com")));
297 ASSERT_TRUE(AddURL(
298 kSingleProfileIndex, tier1_a, 0, "Gmai", GURL("http://mail.google.com")));
299 ASSERT_TRUE(AddURL(
300 kSingleProfileIndex, tier1_a, 1, "Google", GURL("http://www.google.com")));
301 ASSERT_TRUE(AddURL(
302 kSingleProfileIndex, GetOtherNode(kSingleProfileIndex), 1, "CNN",
303 GURL("http://www.cnn.com")));
305 ASSERT_TRUE(AddFolder(
306 kSingleProfileIndex, GetBookmarkBarNode(kSingleProfileIndex), 0,
307 "empty_folder"));
308 const BookmarkNode* folder1 = AddFolder(
309 kSingleProfileIndex, GetBookmarkBarNode(kSingleProfileIndex), 1,
310 "folder1");
311 ASSERT_TRUE(AddURL(
312 kSingleProfileIndex, folder1, 0, "Yahoo", GURL("http://www.yahoo.com")));
313 ASSERT_TRUE(AddURL(
314 kSingleProfileIndex, GetBookmarkBarNode(0), 2, "Gmai",
315 GURL("http://gmail.com")));
317 // Set up sync, wait for its completion and verify that changes propagated.
318 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
319 ASSERT_TRUE(AwaitCommitActivityCompletion(
320 GetSyncService((kSingleProfileIndex))));
321 ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex));
323 // Remove all bookmarks and wait for sync completion.
324 RemoveAll(kSingleProfileIndex);
325 ASSERT_TRUE(AwaitCommitActivityCompletion(
326 GetSyncService((kSingleProfileIndex))));
327 // Verify other node has no children now.
328 EXPECT_EQ(0, GetOtherNode(kSingleProfileIndex)->child_count());
329 EXPECT_EQ(0, GetBookmarkBarNode(kSingleProfileIndex)->child_count());
330 // Verify model matches verifier.
331 ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex));
334 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest,
335 DownloadDeletedBookmark) {
336 std::string title = "Patrick Star";
337 fake_server::EntityBuilderFactory entity_builder_factory;
338 fake_server::BookmarkEntityBuilder bookmark_builder =
339 entity_builder_factory.NewBookmarkEntityBuilder(title);
340 fake_server_->InjectEntity(bookmark_builder.BuildBookmark(
341 GURL("http://en.wikipedia.org/wiki/Patrick_Star")));
343 DisableVerifier();
344 ASSERT_TRUE(SetupSync());
346 ASSERT_EQ(1, CountBookmarksWithTitlesMatching(kSingleProfileIndex, title));
348 std::vector<sync_pb::SyncEntity> server_bookmarks =
349 GetFakeServer()->GetSyncEntitiesByModelType(syncer::BOOKMARKS);
350 ASSERT_EQ(1ul, server_bookmarks.size());
351 std::string entity_id = server_bookmarks[0].id_string();
352 scoped_ptr<fake_server::FakeServerEntity> tombstone(
353 fake_server::TombstoneEntity::Create(entity_id));
354 GetFakeServer()->InjectEntity(tombstone.Pass());
356 const syncer::ModelTypeSet kBookmarksType(syncer::BOOKMARKS);
357 TriggerSyncForModelTypes(kSingleProfileIndex, kBookmarksType);
359 const int kExpectedCountAfterDeletion = 0;
360 ASSERT_TRUE(AwaitCountBookmarksWithTitlesMatching(
361 kSingleProfileIndex, title, kExpectedCountAfterDeletion));
364 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest,
365 DownloadModifiedBookmark) {
366 std::string title = "Syrup";
367 GURL original_url = GURL("https://en.wikipedia.org/?title=Maple_syrup");
368 GURL updated_url = GURL("https://en.wikipedia.org/wiki/Xylem");
370 fake_server::EntityBuilderFactory entity_builder_factory;
371 fake_server::BookmarkEntityBuilder bookmark_builder =
372 entity_builder_factory.NewBookmarkEntityBuilder(title);
373 fake_server_->InjectEntity(bookmark_builder.BuildBookmark(original_url));
375 DisableVerifier();
376 ASSERT_TRUE(SetupSync());
378 ASSERT_EQ(1, CountBookmarksWithTitlesMatching(kSingleProfileIndex, title));
379 ASSERT_EQ(1, CountBookmarksWithUrlsMatching(kSingleProfileIndex,
380 original_url));
381 ASSERT_EQ(0, CountBookmarksWithUrlsMatching(kSingleProfileIndex,
382 updated_url));
384 std::vector<sync_pb::SyncEntity> server_bookmarks =
385 GetFakeServer()->GetSyncEntitiesByModelType(syncer::BOOKMARKS);
386 ASSERT_EQ(1ul, server_bookmarks.size());
387 std::string entity_id = server_bookmarks[0].id_string();
389 sync_pb::EntitySpecifics specifics = server_bookmarks[0].specifics();
390 sync_pb::BookmarkSpecifics* bookmark_specifics = specifics.mutable_bookmark();
391 bookmark_specifics->set_url(updated_url.spec());
392 ASSERT_TRUE(GetFakeServer()->ModifyEntitySpecifics(entity_id, specifics));
394 const syncer::ModelTypeSet kBookmarksType(syncer::BOOKMARKS);
395 TriggerSyncForModelTypes(kSingleProfileIndex, kBookmarksType);
397 ASSERT_TRUE(AwaitCountBookmarksWithUrlsMatching(
398 kSingleProfileIndex, updated_url, 1));
399 ASSERT_EQ(0, CountBookmarksWithUrlsMatching(kSingleProfileIndex,
400 original_url));
401 ASSERT_EQ(1, CountBookmarksWithTitlesMatching(kSingleProfileIndex, title));
404 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, DownloadBookmarkFolder) {
405 const std::string title = "Seattle Sounders FC";
406 fake_server::EntityBuilderFactory entity_builder_factory;
407 fake_server::BookmarkEntityBuilder bookmark_builder =
408 entity_builder_factory.NewBookmarkEntityBuilder(title);
409 fake_server_->InjectEntity(bookmark_builder.BuildFolder());
411 DisableVerifier();
412 ASSERT_TRUE(SetupClients());
413 ASSERT_EQ(0, CountFoldersWithTitlesMatching(kSingleProfileIndex, title));
415 ASSERT_TRUE(SetupSync());
417 ASSERT_EQ(1, CountFoldersWithTitlesMatching(kSingleProfileIndex, title));