single_client_bookmarks_sync_test.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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/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/sync_integration_test_util.h" 10#include "chrome/browser/sync/test/integration/sync_test.h" 11#include "components/bookmarks/browser/bookmark_model.h" 12#include "components/bookmarks/browser/bookmark_service.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 "ui/base/layout.h" 17 18using bookmarks_helper::AddFolder; 19using bookmarks_helper::AddURL; 20using bookmarks_helper::CountBookmarksWithTitlesMatching; 21using bookmarks_helper::Create1xFaviconFromPNGFile; 22using bookmarks_helper::GetBookmarkBarNode; 23using bookmarks_helper::GetBookmarkModel; 24using bookmarks_helper::GetOtherNode; 25using bookmarks_helper::ModelMatchesVerifier; 26using bookmarks_helper::Move; 27using bookmarks_helper::Remove; 28using bookmarks_helper::RemoveAll; 29using bookmarks_helper::SetFavicon; 30using bookmarks_helper::SetTitle; 31using sync_integration_test_util::AwaitCommitActivityCompletion; 32 33class SingleClientBookmarksSyncTest : public SyncTest { 34 public: 35 SingleClientBookmarksSyncTest() : SyncTest(SINGLE_CLIENT) {} 36 virtual ~SingleClientBookmarksSyncTest() {} 37 38 // Verify that the local bookmark model (for the Profile corresponding to 39 // |index|) matches the data on the FakeServer. It is assumed that FakeServer 40 // is being used and each bookmark has a unique title. Folders are not 41 // verified. 42 void VerifyBookmarkModelMatchesFakeServer(int index); 43 44 private: 45 DISALLOW_COPY_AND_ASSIGN(SingleClientBookmarksSyncTest); 46}; 47 48void SingleClientBookmarksSyncTest::VerifyBookmarkModelMatchesFakeServer( 49 int index) { 50 fake_server::FakeServerVerifier fake_server_verifier(GetFakeServer()); 51 std::vector<BookmarkService::URLAndTitle> local_bookmarks; 52 GetBookmarkModel(index)->GetBookmarks(&local_bookmarks); 53 54 // Verify that the number of local bookmarks matches the number in the 55 // server. 56 ASSERT_TRUE(fake_server_verifier.VerifyEntityCountByType( 57 local_bookmarks.size(), 58 syncer::BOOKMARKS)); 59 60 // Verify that all local bookmark titles exist once on the server. 61 std::vector<BookmarkService::URLAndTitle>::const_iterator it; 62 for (it = local_bookmarks.begin(); it != local_bookmarks.end(); ++it) { 63 ASSERT_TRUE(fake_server_verifier.VerifyEntityCountByTypeAndName( 64 1, 65 syncer::BOOKMARKS, 66 base::UTF16ToUTF8(it->title))); 67 } 68} 69 70IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, Sanity) { 71 ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; 72 73 // Starting state: 74 // other_node 75 // -> top 76 // -> tier1_a 77 // -> http://mail.google.com "tier1_a_url0" 78 // -> http://www.pandora.com "tier1_a_url1" 79 // -> http://www.facebook.com "tier1_a_url2" 80 // -> tier1_b 81 // -> http://www.nhl.com "tier1_b_url0" 82 const BookmarkNode* top = AddFolder(0, GetOtherNode(0), 0, L"top"); 83 const BookmarkNode* tier1_a = AddFolder(0, top, 0, L"tier1_a"); 84 const BookmarkNode* tier1_b = AddFolder(0, top, 1, L"tier1_b"); 85 const BookmarkNode* tier1_a_url0 = AddURL( 86 0, tier1_a, 0, L"tier1_a_url0", GURL("http://mail.google.com")); 87 const BookmarkNode* tier1_a_url1 = AddURL( 88 0, tier1_a, 1, L"tier1_a_url1", GURL("http://www.pandora.com")); 89 const BookmarkNode* tier1_a_url2 = AddURL( 90 0, tier1_a, 2, L"tier1_a_url2", GURL("http://www.facebook.com")); 91 const BookmarkNode* tier1_b_url0 = AddURL( 92 0, tier1_b, 0, L"tier1_b_url0", GURL("http://www.nhl.com")); 93 94 // Setup sync, wait for its completion, and make sure changes were synced. 95 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 96 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); 97 ASSERT_TRUE(ModelMatchesVerifier(0)); 98 99 // Ultimately we want to end up with the following model; but this test is 100 // more about the journey than the destination. 101 // 102 // bookmark_bar 103 // -> CNN (www.cnn.com) 104 // -> tier1_a 105 // -> tier1_a_url2 (www.facebook.com) 106 // -> tier1_a_url1 (www.pandora.com) 107 // -> Porsche (www.porsche.com) 108 // -> Bank of America (www.bankofamerica.com) 109 // -> Seattle Bubble 110 // other_node 111 // -> top 112 // -> tier1_b 113 // -> Wired News (www.wired.com) 114 // -> tier2_b 115 // -> tier1_b_url0 116 // -> tier3_b 117 // -> Toronto Maple Leafs (mapleleafs.nhl.com) 118 // -> Wynn (www.wynnlasvegas.com) 119 // -> tier1_a_url0 120 const BookmarkNode* bar = GetBookmarkBarNode(0); 121 const BookmarkNode* cnn = AddURL(0, bar, 0, L"CNN", 122 GURL("http://www.cnn.com")); 123 ASSERT_TRUE(cnn != NULL); 124 Move(0, tier1_a, bar, 1); 125 126 // Wait for the bookmark position change to sync. 127 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); 128 ASSERT_TRUE(ModelMatchesVerifier(0)); 129 130 const BookmarkNode* porsche = AddURL(0, bar, 2, L"Porsche", 131 GURL("http://www.porsche.com")); 132 // Rearrange stuff in tier1_a. 133 ASSERT_EQ(tier1_a, tier1_a_url2->parent()); 134 ASSERT_EQ(tier1_a, tier1_a_url1->parent()); 135 Move(0, tier1_a_url2, tier1_a, 0); 136 Move(0, tier1_a_url1, tier1_a, 2); 137 138 // Wait for the rearranged hierarchy to sync. 139 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); 140 ASSERT_TRUE(ModelMatchesVerifier(0)); 141 142 ASSERT_EQ(1, tier1_a_url0->parent()->GetIndexOf(tier1_a_url0)); 143 Move(0, tier1_a_url0, bar, bar->child_count()); 144 const BookmarkNode* boa = AddURL(0, bar, bar->child_count(), 145 L"Bank of America", GURL("https://www.bankofamerica.com")); 146 ASSERT_TRUE(boa != NULL); 147 Move(0, tier1_a_url0, top, top->child_count()); 148 const BookmarkNode* bubble = AddURL( 149 0, bar, bar->child_count(), L"Seattle Bubble", 150 GURL("http://seattlebubble.com")); 151 ASSERT_TRUE(bubble != NULL); 152 const BookmarkNode* wired = AddURL(0, bar, 2, L"Wired News", 153 GURL("http://www.wired.com")); 154 const BookmarkNode* tier2_b = AddFolder( 155 0, tier1_b, 0, L"tier2_b"); 156 Move(0, tier1_b_url0, tier2_b, 0); 157 Move(0, porsche, bar, 0); 158 SetTitle(0, wired, L"News Wired"); 159 SetTitle(0, porsche, L"ICanHazPorsche?"); 160 161 // Wait for the title change to sync. 162 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); 163 ASSERT_TRUE(ModelMatchesVerifier(0)); 164 165 ASSERT_EQ(tier1_a_url0->id(), top->GetChild(top->child_count() - 1)->id()); 166 Remove(0, top, top->child_count() - 1); 167 Move(0, wired, tier1_b, 0); 168 Move(0, porsche, bar, 3); 169 const BookmarkNode* tier3_b = AddFolder(0, tier2_b, 1, L"tier3_b"); 170 const BookmarkNode* leafs = AddURL( 171 0, tier1_a, 0, L"Toronto Maple Leafs", GURL("http://mapleleafs.nhl.com")); 172 const BookmarkNode* wynn = AddURL(0, bar, 1, L"Wynn", 173 GURL("http://www.wynnlasvegas.com")); 174 175 Move(0, wynn, tier3_b, 0); 176 Move(0, leafs, tier3_b, 0); 177 178 // Wait for newly added bookmarks to sync. 179 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); 180 ASSERT_TRUE(ModelMatchesVerifier(0)); 181 182 // Only verify FakeServer data if FakeServer is being used. 183 // TODO(pvalenzuela): Use this style of verification in more tests once it is 184 // proven stable. 185 if (GetFakeServer()) 186 VerifyBookmarkModelMatchesFakeServer(0); 187} 188 189IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, InjectedBookmark) { 190 std::string title = "Montreal Canadiens"; 191 fake_server::EntityBuilderFactory entity_builder_factory; 192 scoped_ptr<fake_server::FakeServerEntity> entity = 193 entity_builder_factory.NewBookmarkEntityBuilder( 194 title, GURL("http://canadiens.nhl.com")).Build(); 195 fake_server_->InjectEntity(entity.Pass()); 196 197 DisableVerifier(); 198 ASSERT_TRUE(SetupClients()); 199 ASSERT_TRUE(SetupSync()); 200 201 ASSERT_EQ(1, CountBookmarksWithTitlesMatching(0, base::UTF8ToWide(title))); 202} 203 204// Test that a client doesn't mutate the favicon data in the process 205// of storing the favicon data from sync to the database or in the process 206// of requesting data from the database for sync. 207IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, 208 SetFaviconHiDPIDifferentCodec) { 209 // Set the supported scale factors to 1x and 2x such that 210 // BookmarkModel::GetFavicon() requests both 1x and 2x. 211 // 1x -> for sync, 2x -> for the UI. 212 std::vector<ui::ScaleFactor> supported_scale_factors; 213 supported_scale_factors.push_back(ui::SCALE_FACTOR_100P); 214 supported_scale_factors.push_back(ui::SCALE_FACTOR_200P); 215 ui::SetSupportedScaleFactors(supported_scale_factors); 216 217 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 218 ASSERT_TRUE(ModelMatchesVerifier(0)); 219 220 const GURL page_url("http://www.google.com"); 221 const GURL icon_url("http://www.google.com/favicon.ico"); 222 const BookmarkNode* bookmark = AddURL(0, L"title", page_url); 223 224 // Simulate receiving a favicon from sync encoded by a different PNG encoder 225 // than the one native to the OS. This tests the PNG data is not decoded to 226 // SkBitmap (or any other image format) then encoded back to PNG on the path 227 // between sync and the database. 228 gfx::Image original_favicon = Create1xFaviconFromPNGFile( 229 "favicon_cocoa_png_codec.png"); 230 ASSERT_FALSE(original_favicon.IsEmpty()); 231 SetFavicon(0, bookmark, icon_url, original_favicon, 232 bookmarks_helper::FROM_SYNC); 233 234 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); 235 ASSERT_TRUE(ModelMatchesVerifier(0)); 236 237 scoped_refptr<base::RefCountedMemory> original_favicon_bytes = 238 original_favicon.As1xPNGBytes(); 239 gfx::Image final_favicon = GetBookmarkModel(0)->GetFavicon(bookmark); 240 scoped_refptr<base::RefCountedMemory> final_favicon_bytes = 241 final_favicon.As1xPNGBytes(); 242 243 // Check that the data was not mutated from the original. 244 EXPECT_TRUE(original_favicon_bytes.get()); 245 EXPECT_TRUE(original_favicon_bytes->Equals(final_favicon_bytes)); 246} 247 248IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, 249 BookmarkAllNodesRemovedEvent) { 250 ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; 251 // Starting state: 252 // other_node 253 // -> folder0 254 // -> tier1_a 255 // -> http://mail.google.com 256 // -> http://www.google.com 257 // -> http://news.google.com 258 // -> http://yahoo.com 259 // -> http://www.cnn.com 260 // bookmark_bar 261 // -> empty_folder 262 // -> folder1 263 // -> http://yahoo.com 264 // -> http://gmail.com 265 266 const BookmarkNode* folder0 = AddFolder(0, GetOtherNode(0), 0, L"folder0"); 267 const BookmarkNode* tier1_a = AddFolder(0, folder0, 0, L"tier1_a"); 268 ASSERT_TRUE(AddURL(0, folder0, 1, L"News", GURL("http://news.google.com"))); 269 ASSERT_TRUE(AddURL(0, folder0, 2, L"Yahoo", GURL("http://www.yahoo.com"))); 270 ASSERT_TRUE(AddURL(0, tier1_a, 0, L"Gmail", GURL("http://mail.google.com"))); 271 ASSERT_TRUE(AddURL(0, tier1_a, 1, L"Google", GURL("http://www.google.com"))); 272 ASSERT_TRUE( 273 AddURL(0, GetOtherNode(0), 1, L"CNN", GURL("http://www.cnn.com"))); 274 275 ASSERT_TRUE(AddFolder(0, GetBookmarkBarNode(0), 0, L"empty_folder")); 276 const BookmarkNode* folder1 = 277 AddFolder(0, GetBookmarkBarNode(0), 1, L"folder1"); 278 ASSERT_TRUE(AddURL(0, folder1, 0, L"Yahoo", GURL("http://www.yahoo.com"))); 279 ASSERT_TRUE( 280 AddURL(0, GetBookmarkBarNode(0), 2, L"Gmail", GURL("http://gmail.com"))); 281 282 // Set up sync, wait for its completion and verify that changes propagated. 283 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 284 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); 285 ASSERT_TRUE(ModelMatchesVerifier(0)); 286 287 // Remove all bookmarks and wait for sync completion. 288 RemoveAll(0); 289 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); 290 // Verify other node has no children now. 291 EXPECT_EQ(0, GetOtherNode(0)->child_count()); 292 EXPECT_EQ(0, GetBookmarkBarNode(0)->child_count()); 293 // Verify model matches verifier. 294 ASSERT_TRUE(ModelMatchesVerifier(0)); 295} 296