single_client_bookmarks_sync_test.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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
11using bookmarks_helper::AddFolder;
12using bookmarks_helper::AddURL;
13using bookmarks_helper::Create1xFaviconFromPNGFile;
14using bookmarks_helper::GetBookmarkBarNode;
15using bookmarks_helper::GetBookmarkModel;
16using bookmarks_helper::GetOtherNode;
17using bookmarks_helper::ModelMatchesVerifier;
18using bookmarks_helper::Move;
19using bookmarks_helper::Remove;
20using bookmarks_helper::RemoveAll;
21using bookmarks_helper::SetFavicon;
22using bookmarks_helper::SetTitle;
23
24class SingleClientBookmarksSyncTest : public SyncTest {
25 public:
26  SingleClientBookmarksSyncTest() : SyncTest(SINGLE_CLIENT) {}
27  virtual ~SingleClientBookmarksSyncTest() {}
28
29 private:
30  DISALLOW_COPY_AND_ASSIGN(SingleClientBookmarksSyncTest);
31};
32
33IN_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
48IN_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// Restart the sync service on a client and make sure sync is up and running.
156IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest,
157                       DISABLED_RestartSyncService) {
158  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
159
160  ASSERT_TRUE(AddURL(0, L"Google", GURL("http://www.google.com")));
161  ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion("Added a bookmark."));
162  ASSERT_TRUE(ModelMatchesVerifier(0));
163
164  RestartSyncService(0);
165  ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion("Restarted sync."));
166  ASSERT_TRUE(ModelMatchesVerifier(0));
167}
168
169// Test that a client doesn't mutate the favicon data in the process
170// of storing the favicon data from sync to the database or in the process
171// of requesting data from the database for sync.
172IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest,
173                       SetFaviconHiDPIDifferentCodec) {
174  // Set the supported scale factors to 1x and 2x such that
175  // BookmarkModel::GetFavicon() requests both 1x and 2x.
176  // 1x -> for sync, 2x -> for the UI.
177  std::vector<ui::ScaleFactor> supported_scale_factors;
178  supported_scale_factors.push_back(ui::SCALE_FACTOR_100P);
179  supported_scale_factors.push_back(ui::SCALE_FACTOR_200P);
180  ui::test::SetSupportedScaleFactors(supported_scale_factors);
181
182  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
183  ASSERT_TRUE(ModelMatchesVerifier(0));
184
185  const GURL page_url("http://www.google.com");
186  const GURL icon_url("http://www.google.com/favicon.ico");
187  const BookmarkNode* bookmark = AddURL(0, L"title", page_url);
188
189  // Simulate receiving a favicon from sync encoded by a different PNG encoder
190  // than the one native to the OS. This tests the PNG data is not decoded to
191  // SkBitmap (or any other image format) then encoded back to PNG on the path
192  // between sync and the database.
193  gfx::Image original_favicon = Create1xFaviconFromPNGFile(
194      "favicon_cocoa_png_codec.png");
195  ASSERT_FALSE(original_favicon.IsEmpty());
196  SetFavicon(0, bookmark, icon_url, original_favicon,
197             bookmarks_helper::FROM_SYNC);
198
199  ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion("Added bookmark"));
200  ASSERT_TRUE(ModelMatchesVerifier(0));
201
202  scoped_refptr<base::RefCountedMemory> original_favicon_bytes =
203      original_favicon.As1xPNGBytes();
204  gfx::Image final_favicon = GetBookmarkModel(0)->GetFavicon(bookmark);
205  scoped_refptr<base::RefCountedMemory> final_favicon_bytes =
206      final_favicon.As1xPNGBytes();
207
208  // Check that the data was not mutated from the original.
209  EXPECT_TRUE(original_favicon_bytes.get());
210  EXPECT_TRUE(original_favicon_bytes->Equals(final_favicon_bytes));
211}
212
213IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest,
214                       BookmarkAllNodesRemovedEvent) {
215  ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
216  // Starting state:
217  // other_node
218  //    -> folder0
219  //      -> tier1_a
220  //        -> http://mail.google.com
221  //        -> http://www.google.com
222  //      -> http://news.google.com
223  //      -> http://yahoo.com
224  //    -> http://www.cnn.com
225  // bookmark_bar
226  // -> empty_folder
227  // -> folder1
228  //    -> http://yahoo.com
229  // -> http://gmail.com
230
231  const BookmarkNode* folder0 = AddFolder(0, GetOtherNode(0), 0, L"folder0");
232  const BookmarkNode* tier1_a = AddFolder(0, folder0, 0, L"tier1_a");
233  ASSERT_TRUE(AddURL(0, folder0, 1, L"News", GURL("http://news.google.com")));
234  ASSERT_TRUE(AddURL(0, folder0, 2, L"Yahoo", GURL("http://www.yahoo.com")));
235  ASSERT_TRUE(AddURL(0, tier1_a, 0, L"Gmail", GURL("http://mail.google.com")));
236  ASSERT_TRUE(AddURL(0, tier1_a, 1, L"Google", GURL("http://www.google.com")));
237  ASSERT_TRUE(
238      AddURL(0, GetOtherNode(0), 1, L"CNN", GURL("http://www.cnn.com")));
239
240  ASSERT_TRUE(AddFolder(0, GetBookmarkBarNode(0), 0, L"empty_folder"));
241  const BookmarkNode* folder1 =
242      AddFolder(0, GetBookmarkBarNode(0), 1, L"folder1");
243  ASSERT_TRUE(AddURL(0, folder1, 0, L"Yahoo", GURL("http://www.yahoo.com")));
244  ASSERT_TRUE(
245      AddURL(0, GetBookmarkBarNode(0), 2, L"Gmail", GURL("http://gmail.com")));
246
247  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
248  ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion(
249      "Waiting for initial sync completed."));
250  ASSERT_TRUE(ModelMatchesVerifier(0));
251
252  // Remove all
253  RemoveAll(0);
254  ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion("All Bookmarks removed."));
255  // Verify other node has no children now.
256  EXPECT_EQ(0, GetOtherNode(0)->child_count());
257  EXPECT_EQ(0, GetBookmarkBarNode(0)->child_count());
258  // Verify model matches verifier.
259  ASSERT_TRUE(ModelMatchesVerifier(0));
260}
261