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/bind.h"
6#include "base/strings/utf_string_conversions.h"
7#include "base/timer/timer.h"
8#include "chrome/app/chrome_command_ids.h"
9#include "chrome/browser/bookmarks/bookmark_model_factory.h"
10#include "chrome/browser/browser_process.h"
11#include "chrome/browser/chrome_notification_types.h"
12#include "chrome/browser/profiles/profile.h"
13#include "chrome/browser/profiles/profile_manager.h"
14#include "chrome/browser/ui/browser.h"
15#include "chrome/browser/ui/browser_commands.h"
16#include "chrome/browser/ui/browser_window.h"
17#include "chrome/browser/ui/host_desktop.h"
18#include "chrome/test/base/in_process_browser_test.h"
19#include "chrome/test/base/ui_test_utils.h"
20#include "components/bookmarks/browser/bookmark_model.h"
21#include "components/bookmarks/browser/bookmark_utils.h"
22#include "components/bookmarks/test/bookmark_test_helpers.h"
23#include "content/public/browser/notification_service.h"
24#include "content/public/test/browser_test_utils.h"
25
26namespace {
27const char kPersistBookmarkURL[] = "http://www.cnn.com/";
28const char kPersistBookmarkTitle[] = "CNN";
29}
30
31class BookmarkBrowsertest : public InProcessBrowserTest {
32 public:
33  BookmarkBrowsertest() {}
34
35  bool IsVisible() {
36    return browser()->bookmark_bar_state() == BookmarkBar::SHOW;
37  }
38
39  static void CheckAnimation(Browser* browser, const base::Closure& quit_task) {
40    if (!browser->window()->IsBookmarkBarAnimating())
41      quit_task.Run();
42  }
43
44  base::TimeDelta WaitForBookmarkBarAnimationToFinish() {
45    base::Time start(base::Time::Now());
46    scoped_refptr<content::MessageLoopRunner> runner =
47        new content::MessageLoopRunner;
48
49    base::Timer timer(false, true);
50    timer.Start(
51        FROM_HERE,
52        base::TimeDelta::FromMilliseconds(15),
53        base::Bind(&CheckAnimation, browser(), runner->QuitClosure()));
54    runner->Run();
55    return base::Time::Now() - start;
56  }
57
58  BookmarkModel* WaitForBookmarkModel(Profile* profile) {
59    BookmarkModel* bookmark_model =
60        BookmarkModelFactory::GetForProfile(profile);
61    test::WaitForBookmarkModelToLoad(bookmark_model);
62    return bookmark_model;
63  }
64};
65
66// Test of bookmark bar toggling, visibility, and animation.
67IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, BookmarkBarVisibleWait) {
68  ASSERT_FALSE(IsVisible());
69  chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR);
70  base::TimeDelta delay = WaitForBookmarkBarAnimationToFinish();
71  LOG(INFO) << "Took " << delay.InMilliseconds() << " ms to show bookmark bar";
72  ASSERT_TRUE(IsVisible());
73  chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR);
74  delay = WaitForBookmarkBarAnimationToFinish();
75  LOG(INFO) << "Took " << delay.InMilliseconds() << " ms to hide bookmark bar";
76  ASSERT_FALSE(IsVisible());
77}
78
79// Verify that bookmarks persist browser restart.
80IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, PRE_Persist) {
81  BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile());
82
83  bookmarks::AddIfNotBookmarked(bookmark_model,
84                                GURL(kPersistBookmarkURL),
85                                base::ASCIIToUTF16(kPersistBookmarkTitle));
86}
87
88#if defined(THREAD_SANITIZER)
89// BookmarkBrowsertest.Persist fails under ThreadSanitizer on Linux, see
90// http://crbug.com/340223.
91#define MAYBE_Persist DISABLED_Persist
92#else
93#define MAYBE_Persist Persist
94#endif
95IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, MAYBE_Persist) {
96  BookmarkModel* bookmark_model = WaitForBookmarkModel(browser()->profile());
97
98  std::vector<BookmarkModel::URLAndTitle> urls;
99  bookmark_model->GetBookmarks(&urls);
100
101  ASSERT_EQ(1u, urls.size());
102  ASSERT_EQ(GURL(kPersistBookmarkURL), urls[0].url);
103  ASSERT_EQ(base::ASCIIToUTF16(kPersistBookmarkTitle), urls[0].title);
104}
105
106#if !defined(OS_CHROMEOS)  // No multi-profile on ChromeOS.
107
108// Sanity check that bookmarks from different profiles are separate.
109// DISABLED_ because it regularly times out: http://crbug.com/159002.
110IN_PROC_BROWSER_TEST_F(BookmarkBrowsertest, DISABLED_MultiProfile) {
111  base::ScopedTempDir temp_dir;
112  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
113
114  BookmarkModel* bookmark_model1 = WaitForBookmarkModel(browser()->profile());
115
116  ui_test_utils::BrowserAddedObserver observer;
117  g_browser_process->profile_manager()->CreateMultiProfileAsync(
118      base::string16(), base::string16(), ProfileManager::CreateCallback(),
119      std::string());
120  Browser* browser2 = observer.WaitForSingleNewBrowser();
121  BookmarkModel* bookmark_model2 = WaitForBookmarkModel(browser2->profile());
122
123  bookmarks::AddIfNotBookmarked(bookmark_model1,
124                                GURL(kPersistBookmarkURL),
125                                base::ASCIIToUTF16(kPersistBookmarkTitle));
126  std::vector<BookmarkModel::URLAndTitle> urls1, urls2;
127  bookmark_model1->GetBookmarks(&urls1);
128  bookmark_model2->GetBookmarks(&urls2);
129  ASSERT_EQ(1u, urls1.size());
130  ASSERT_TRUE(urls2.empty());
131}
132
133#endif
134