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