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 "chrome/browser/profiles/profile.h" 6 #include "chrome/browser/sync/profile_sync_service_harness.h" 7 #include "chrome/browser/sync/test/integration/bookmarks_helper.h" 8 #include "chrome/browser/sync/test/integration/sync_test.h" 9 #include "ui/base/layout.h" 10 11 using bookmarks_helper::AddFolder; 12 using bookmarks_helper::AddURL; 13 using bookmarks_helper::Create1xFaviconFromPNGFile; 14 using bookmarks_helper::GetBookmarkBarNode; 15 using bookmarks_helper::GetBookmarkModel; 16 using bookmarks_helper::GetOtherNode; 17 using bookmarks_helper::ModelMatchesVerifier; 18 using bookmarks_helper::Move; 19 using bookmarks_helper::Remove; 20 using bookmarks_helper::RemoveAll; 21 using bookmarks_helper::SetFavicon; 22 using bookmarks_helper::SetTitle; 23 24 class SingleClientBookmarksSyncTest : public SyncTest { 25 public: 26 SingleClientBookmarksSyncTest() : SyncTest(SINGLE_CLIENT) {} 27 virtual ~SingleClientBookmarksSyncTest() {} 28 29 private: 30 DISALLOW_COPY_AND_ASSIGN(SingleClientBookmarksSyncTest); 31 }; 32 33 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, OfflineToOnline) { 34 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 35 36 DisableNetwork(GetProfile(0)); 37 const BookmarkNode* node = AddFolder(0, L"title"); 38 SetTitle(0, node, L"new_title"); 39 // Expect that we backoff exponentially while we are unable to contact the 40 // server. 41 ASSERT_TRUE(GetClient(0)->AwaitExponentialBackoffVerification()); 42 43 EnableNetwork(GetProfile(0)); 44 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion("Commit changes.")); 45 ASSERT_TRUE(ModelMatchesVerifier(0)); 46 } 47 48 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, Sanity) { 49 ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; 50 51 // Starting state: 52 // other_node 53 // -> top 54 // -> tier1_a 55 // -> http://mail.google.com "tier1_a_url0" 56 // -> http://www.pandora.com "tier1_a_url1" 57 // -> http://www.facebook.com "tier1_a_url2" 58 // -> tier1_b 59 // -> http://www.nhl.com "tier1_b_url0" 60 const BookmarkNode* top = AddFolder(0, GetOtherNode(0), 0, L"top"); 61 const BookmarkNode* tier1_a = AddFolder(0, top, 0, L"tier1_a"); 62 const BookmarkNode* tier1_b = AddFolder(0, top, 1, L"tier1_b"); 63 const BookmarkNode* tier1_a_url0 = AddURL( 64 0, tier1_a, 0, L"tier1_a_url0", GURL("http://mail.google.com")); 65 const BookmarkNode* tier1_a_url1 = AddURL( 66 0, tier1_a, 1, L"tier1_a_url1", GURL("http://www.pandora.com")); 67 const BookmarkNode* tier1_a_url2 = AddURL( 68 0, tier1_a, 2, L"tier1_a_url2", GURL("http://www.facebook.com")); 69 const BookmarkNode* tier1_b_url0 = AddURL( 70 0, tier1_b, 0, L"tier1_b_url0", GURL("http://www.nhl.com")); 71 72 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 73 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion( 74 "Waiting for initial sync completed.")); 75 ASSERT_TRUE(ModelMatchesVerifier(0)); 76 77 // Ultimately we want to end up with the following model; but this test is 78 // more about the journey than the destination. 79 // 80 // bookmark_bar 81 // -> CNN (www.cnn.com) 82 // -> tier1_a 83 // -> tier1_a_url2 (www.facebook.com) 84 // -> tier1_a_url1 (www.pandora.com) 85 // -> Porsche (www.porsche.com) 86 // -> Bank of America (www.bankofamerica.com) 87 // -> Seattle Bubble 88 // other_node 89 // -> top 90 // -> tier1_b 91 // -> Wired News (www.wired.com) 92 // -> tier2_b 93 // -> tier1_b_url0 94 // -> tier3_b 95 // -> Toronto Maple Leafs (mapleleafs.nhl.com) 96 // -> Wynn (www.wynnlasvegas.com) 97 // -> tier1_a_url0 98 const BookmarkNode* bar = GetBookmarkBarNode(0); 99 const BookmarkNode* cnn = AddURL(0, bar, 0, L"CNN", 100 GURL("http://www.cnn.com")); 101 ASSERT_TRUE(cnn != NULL); 102 Move(0, tier1_a, bar, 1); 103 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion("Bookmark moved.")); 104 ASSERT_TRUE(ModelMatchesVerifier(0)); 105 106 const BookmarkNode* porsche = AddURL(0, bar, 2, L"Porsche", 107 GURL("http://www.porsche.com")); 108 // Rearrange stuff in tier1_a. 109 ASSERT_EQ(tier1_a, tier1_a_url2->parent()); 110 ASSERT_EQ(tier1_a, tier1_a_url1->parent()); 111 Move(0, tier1_a_url2, tier1_a, 0); 112 Move(0, tier1_a_url1, tier1_a, 2); 113 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion( 114 "Rearrange stuff in tier1_a")); 115 ASSERT_TRUE(ModelMatchesVerifier(0)); 116 117 ASSERT_EQ(1, tier1_a_url0->parent()->GetIndexOf(tier1_a_url0)); 118 Move(0, tier1_a_url0, bar, bar->child_count()); 119 const BookmarkNode* boa = AddURL(0, bar, bar->child_count(), 120 L"Bank of America", GURL("https://www.bankofamerica.com")); 121 ASSERT_TRUE(boa != NULL); 122 Move(0, tier1_a_url0, top, top->child_count()); 123 const BookmarkNode* bubble = AddURL( 124 0, bar, bar->child_count(), L"Seattle Bubble", 125 GURL("http://seattlebubble.com")); 126 ASSERT_TRUE(bubble != NULL); 127 const BookmarkNode* wired = AddURL(0, bar, 2, L"Wired News", 128 GURL("http://www.wired.com")); 129 const BookmarkNode* tier2_b = AddFolder( 130 0, tier1_b, 0, L"tier2_b"); 131 Move(0, tier1_b_url0, tier2_b, 0); 132 Move(0, porsche, bar, 0); 133 SetTitle(0, wired, L"News Wired"); 134 SetTitle(0, porsche, L"ICanHazPorsche?"); 135 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion("Change title.")); 136 ASSERT_TRUE(ModelMatchesVerifier(0)); 137 138 ASSERT_EQ(tier1_a_url0->id(), top->GetChild(top->child_count() - 1)->id()); 139 Remove(0, top, top->child_count() - 1); 140 Move(0, wired, tier1_b, 0); 141 Move(0, porsche, bar, 3); 142 const BookmarkNode* tier3_b = AddFolder(0, tier2_b, 1, L"tier3_b"); 143 const BookmarkNode* leafs = AddURL( 144 0, tier1_a, 0, L"Toronto Maple Leafs", GURL("http://mapleleafs.nhl.com")); 145 const BookmarkNode* wynn = AddURL(0, bar, 1, L"Wynn", 146 GURL("http://www.wynnlasvegas.com")); 147 148 Move(0, wynn, tier3_b, 0); 149 Move(0, leafs, tier3_b, 0); 150 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion( 151 "Move after addition of bookmarks.")); 152 ASSERT_TRUE(ModelMatchesVerifier(0)); 153 } 154 155 // Test that a client doesn't mutate the favicon data in the process 156 // of storing the favicon data from sync to the database or in the process 157 // of requesting data from the database for sync. 158 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, 159 SetFaviconHiDPIDifferentCodec) { 160 // Set the supported scale factors to 1x and 2x such that 161 // BookmarkModel::GetFavicon() requests both 1x and 2x. 162 // 1x -> for sync, 2x -> for the UI. 163 std::vector<ui::ScaleFactor> supported_scale_factors; 164 supported_scale_factors.push_back(ui::SCALE_FACTOR_100P); 165 supported_scale_factors.push_back(ui::SCALE_FACTOR_200P); 166 ui::test::SetSupportedScaleFactors(supported_scale_factors); 167 168 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 169 ASSERT_TRUE(ModelMatchesVerifier(0)); 170 171 const GURL page_url("http://www.google.com"); 172 const GURL icon_url("http://www.google.com/favicon.ico"); 173 const BookmarkNode* bookmark = AddURL(0, L"title", page_url); 174 175 // Simulate receiving a favicon from sync encoded by a different PNG encoder 176 // than the one native to the OS. This tests the PNG data is not decoded to 177 // SkBitmap (or any other image format) then encoded back to PNG on the path 178 // between sync and the database. 179 gfx::Image original_favicon = Create1xFaviconFromPNGFile( 180 "favicon_cocoa_png_codec.png"); 181 ASSERT_FALSE(original_favicon.IsEmpty()); 182 SetFavicon(0, bookmark, icon_url, original_favicon, 183 bookmarks_helper::FROM_SYNC); 184 185 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion("Added bookmark")); 186 ASSERT_TRUE(ModelMatchesVerifier(0)); 187 188 scoped_refptr<base::RefCountedMemory> original_favicon_bytes = 189 original_favicon.As1xPNGBytes(); 190 gfx::Image final_favicon = GetBookmarkModel(0)->GetFavicon(bookmark); 191 scoped_refptr<base::RefCountedMemory> final_favicon_bytes = 192 final_favicon.As1xPNGBytes(); 193 194 // Check that the data was not mutated from the original. 195 EXPECT_TRUE(original_favicon_bytes.get()); 196 EXPECT_TRUE(original_favicon_bytes->Equals(final_favicon_bytes)); 197 } 198 199 IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, 200 BookmarkAllNodesRemovedEvent) { 201 ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; 202 // Starting state: 203 // other_node 204 // -> folder0 205 // -> tier1_a 206 // -> http://mail.google.com 207 // -> http://www.google.com 208 // -> http://news.google.com 209 // -> http://yahoo.com 210 // -> http://www.cnn.com 211 // bookmark_bar 212 // -> empty_folder 213 // -> folder1 214 // -> http://yahoo.com 215 // -> http://gmail.com 216 217 const BookmarkNode* folder0 = AddFolder(0, GetOtherNode(0), 0, L"folder0"); 218 const BookmarkNode* tier1_a = AddFolder(0, folder0, 0, L"tier1_a"); 219 ASSERT_TRUE(AddURL(0, folder0, 1, L"News", GURL("http://news.google.com"))); 220 ASSERT_TRUE(AddURL(0, folder0, 2, L"Yahoo", GURL("http://www.yahoo.com"))); 221 ASSERT_TRUE(AddURL(0, tier1_a, 0, L"Gmail", GURL("http://mail.google.com"))); 222 ASSERT_TRUE(AddURL(0, tier1_a, 1, L"Google", GURL("http://www.google.com"))); 223 ASSERT_TRUE( 224 AddURL(0, GetOtherNode(0), 1, L"CNN", GURL("http://www.cnn.com"))); 225 226 ASSERT_TRUE(AddFolder(0, GetBookmarkBarNode(0), 0, L"empty_folder")); 227 const BookmarkNode* folder1 = 228 AddFolder(0, GetBookmarkBarNode(0), 1, L"folder1"); 229 ASSERT_TRUE(AddURL(0, folder1, 0, L"Yahoo", GURL("http://www.yahoo.com"))); 230 ASSERT_TRUE( 231 AddURL(0, GetBookmarkBarNode(0), 2, L"Gmail", GURL("http://gmail.com"))); 232 233 ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; 234 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion( 235 "Waiting for initial sync completed.")); 236 ASSERT_TRUE(ModelMatchesVerifier(0)); 237 238 // Remove all 239 RemoveAll(0); 240 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion("All Bookmarks removed.")); 241 // Verify other node has no children now. 242 EXPECT_EQ(0, GetOtherNode(0)->child_count()); 243 EXPECT_EQ(0, GetBookmarkBarNode(0)->child_count()); 244 // Verify model matches verifier. 245 ASSERT_TRUE(ModelMatchesVerifier(0)); 246 } 247