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