Home | History | Annotate | Download | only in sync
      1 // Copyright 2013 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/ui/views/sync/one_click_signin_bubble_view.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "chrome/browser/ui/sync/one_click_signin_bubble_delegate.h"
     11 #include "chrome/test/base/ui_test_utils.h"
     12 #include "content/public/common/page_transition_types.h"
     13 #include "ui/views/controls/button/label_button.h"
     14 #include "ui/views/test/views_test_base.h"
     15 #include "ui/views/widget/widget.h"
     16 
     17 class OneClickSigninBubbleViewTest : public views::ViewsTestBase {
     18  public:
     19   OneClickSigninBubbleViewTest()
     20       : on_start_sync_called_(false),
     21         mode_(OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST),
     22         bubble_learn_more_click_count_(0),
     23         dialog_learn_more_click_count_(0),
     24         advanced_click_count_(0),
     25         anchor_widget_(NULL) {
     26   }
     27 
     28   virtual void SetUp() OVERRIDE {
     29     views::ViewsTestBase::SetUp();
     30 
     31     // Create a widget to host the anchor view.
     32     anchor_widget_ = new views::Widget;
     33     views::Widget::InitParams widget_params = CreateParams(
     34         views::Widget::InitParams::TYPE_WINDOW);
     35     anchor_widget_->Init(widget_params);
     36     anchor_widget_->Show();
     37   }
     38 
     39   virtual void TearDown() OVERRIDE {
     40     OneClickSigninBubbleView::Hide();
     41     anchor_widget_->Close();
     42     anchor_widget_ = NULL;
     43     views::ViewsTestBase::TearDown();
     44   }
     45 
     46  protected:
     47   OneClickSigninBubbleView* ShowOneClickSigninBubble(
     48     BrowserWindow::OneClickSigninBubbleType bubble_type) {
     49 
     50     scoped_ptr<OneClickSigninBubbleDelegate> delegate;
     51     delegate.reset(new OneClickSigninBubbleTestDelegate(this));
     52 
     53     OneClickSigninBubbleView::ShowBubble(
     54         bubble_type,
     55         string16(),
     56         string16(),
     57         delegate.Pass(),
     58         anchor_widget_->GetContentsView(),
     59         base::Bind(&OneClickSigninBubbleViewTest::OnStartSync,
     60                    base::Unretained(this)));
     61 
     62     OneClickSigninBubbleView* view =
     63         OneClickSigninBubbleView::view_for_testing();
     64     EXPECT_TRUE(view != NULL);
     65     view->message_loop_for_testing_ = base::MessageLoop::current();
     66     return view;
     67   }
     68 
     69   void OnStartSync(OneClickSigninSyncStarter::StartSyncMode mode) {
     70     on_start_sync_called_ = true;
     71     mode_ = mode;
     72   }
     73 
     74   bool on_start_sync_called_;
     75   OneClickSigninSyncStarter::StartSyncMode mode_;
     76   int bubble_learn_more_click_count_;
     77   int dialog_learn_more_click_count_;
     78   int advanced_click_count_;
     79 
     80  private:
     81   friend class OneClickSigninBubbleTestDelegate;
     82 
     83   class OneClickSigninBubbleTestDelegate
     84       : public OneClickSigninBubbleDelegate {
     85    public:
     86     // |test| is not owned by this object.
     87     explicit OneClickSigninBubbleTestDelegate(
     88         OneClickSigninBubbleViewTest* test) : test_(test) {}
     89 
     90     // OneClickSigninBubbleDelegate:
     91     virtual void OnLearnMoreLinkClicked(bool is_dialog) OVERRIDE {
     92       if (is_dialog)
     93         ++test_->dialog_learn_more_click_count_;
     94       else
     95         ++test_->bubble_learn_more_click_count_;
     96     }
     97     virtual void OnAdvancedLinkClicked() OVERRIDE {
     98       ++test_->advanced_click_count_;
     99     }
    100 
    101    private:
    102     OneClickSigninBubbleViewTest* test_;
    103 
    104     DISALLOW_COPY_AND_ASSIGN(OneClickSigninBubbleTestDelegate);
    105   };
    106 
    107   // Widget to host the anchor view of the bubble. Destroys itself when closed.
    108   views::Widget* anchor_widget_;
    109 
    110   DISALLOW_COPY_AND_ASSIGN(OneClickSigninBubbleViewTest);
    111 };
    112 
    113 TEST_F(OneClickSigninBubbleViewTest, ShowBubble) {
    114   ShowOneClickSigninBubble(BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
    115   content::RunAllPendingInMessageLoop();
    116   EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
    117 }
    118 
    119 TEST_F(OneClickSigninBubbleViewTest, ShowDialog) {
    120   ShowOneClickSigninBubble(
    121     BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
    122   content::RunAllPendingInMessageLoop();
    123   EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
    124 }
    125 
    126 TEST_F(OneClickSigninBubbleViewTest, HideBubble) {
    127   ShowOneClickSigninBubble(BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
    128 
    129   OneClickSigninBubbleView::Hide();
    130   content::RunAllPendingInMessageLoop();
    131   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    132 }
    133 
    134 TEST_F(OneClickSigninBubbleViewTest, HideDialog) {
    135   ShowOneClickSigninBubble(
    136     BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
    137 
    138   OneClickSigninBubbleView::Hide();
    139   content::RunAllPendingInMessageLoop();
    140   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    141   EXPECT_TRUE(on_start_sync_called_);
    142   EXPECT_EQ(OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS, mode_);
    143 }
    144 
    145 TEST_F(OneClickSigninBubbleViewTest, BubbleOkButton) {
    146   OneClickSigninBubbleView* view =
    147     ShowOneClickSigninBubble(
    148       BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
    149 
    150   // Simulate pressing the OK button.  Set the message loop in the bubble
    151   // view so that it can be quit once the bubble is hidden.
    152   views::ButtonListener* listener = view;
    153   const ui::MouseEvent event(ui::ET_MOUSE_PRESSED,
    154                              gfx::Point(), gfx::Point(),
    155                              0);
    156   listener->ButtonPressed(view->ok_button_, event);
    157 
    158   // View should no longer be showing.  The message loop will exit once the
    159   // fade animation of the bubble is done.
    160   content::RunAllPendingInMessageLoop();
    161   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    162 }
    163 
    164 TEST_F(OneClickSigninBubbleViewTest, DialogOkButton) {
    165   OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
    166       BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
    167 
    168   // Simulate pressing the OK button.  Set the message loop in the bubble
    169   // view so that it can be quit once the bubble is hidden.
    170   views::ButtonListener* listener = view;
    171   const ui::MouseEvent event(ui::ET_MOUSE_PRESSED,
    172                              gfx::Point(), gfx::Point(),
    173                              0);
    174   listener->ButtonPressed(view->ok_button_, event);
    175 
    176   // View should no longer be showing and sync should start
    177   // The message loop will exit once the fade animation of the dialog is done.
    178   content::RunAllPendingInMessageLoop();
    179   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    180   EXPECT_TRUE(on_start_sync_called_);
    181   EXPECT_EQ(OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS, mode_);
    182 }
    183 
    184 TEST_F(OneClickSigninBubbleViewTest, DialogUndoButton) {
    185   OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
    186     BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
    187 
    188   // Simulate pressing the undo button.  Set the message loop in the bubble
    189   // view so that it can be quit once the bubble is hidden.
    190   views::ButtonListener* listener = view;
    191   const ui::MouseEvent event(ui::ET_MOUSE_PRESSED,
    192                              gfx::Point(), gfx::Point(),
    193                              0);
    194   listener->ButtonPressed(view->undo_button_, event);
    195 
    196   // View should no longer be showing.  The message loop will exit once the
    197   // fade animation of the bubble is done.
    198   content::RunAllPendingInMessageLoop();
    199   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    200   EXPECT_TRUE(on_start_sync_called_);
    201   EXPECT_EQ(OneClickSigninSyncStarter::UNDO_SYNC, mode_);
    202 }
    203 
    204 TEST_F(OneClickSigninBubbleViewTest, BubbleAdvancedLink) {
    205   OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
    206     BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
    207 
    208   // Simulate pressing a link in the bubble.
    209   views::LinkListener* listener = view;
    210   listener->LinkClicked(view->advanced_link_, 0);
    211 
    212   // View should no longer be showing and the OnAdvancedLinkClicked method
    213   // of the delegate should have been called.
    214   content::RunAllPendingInMessageLoop();
    215   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    216   EXPECT_EQ(1, advanced_click_count_);
    217 }
    218 
    219 TEST_F(OneClickSigninBubbleViewTest, DialogAdvancedLink) {
    220   OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
    221     BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
    222 
    223   // Simulate pressing a link in the bubble.
    224   views::LinkListener* listener = view;
    225   listener->LinkClicked(view->advanced_link_, 0);
    226 
    227   // View should no longer be showing. No delegate method should have been
    228   // called: the callback is responsible to open the settings page.
    229   content::RunAllPendingInMessageLoop();
    230   EXPECT_TRUE(on_start_sync_called_);
    231   EXPECT_EQ(OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST, mode_);
    232   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    233   EXPECT_EQ(0, advanced_click_count_);
    234 }
    235 
    236 TEST_F(OneClickSigninBubbleViewTest, BubbleLearnMoreLink) {
    237   OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
    238     BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
    239 
    240   views::LinkListener* listener = view;
    241   listener->LinkClicked(view->learn_more_link_, 0);
    242 
    243   // View should no longer be showing and the OnLearnMoreLinkClicked method
    244   // of the delegate should have been called with |is_dialog| == false.
    245   content::RunAllPendingInMessageLoop();
    246   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    247   EXPECT_EQ(1, bubble_learn_more_click_count_);
    248   EXPECT_EQ(0, dialog_learn_more_click_count_);
    249 }
    250 
    251 TEST_F(OneClickSigninBubbleViewTest, DialogLearnMoreLink) {
    252   OneClickSigninBubbleView* view = ShowOneClickSigninBubble(
    253       BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
    254 
    255   views::LinkListener* listener = view;
    256   listener->LinkClicked(view->learn_more_link_, 0);
    257 
    258   // View should still be showing and the OnLearnMoreLinkClicked method
    259   // of the delegate should have been called with |is_dialog| == true.
    260   content::RunAllPendingInMessageLoop();
    261   EXPECT_TRUE(OneClickSigninBubbleView::IsShowing());
    262   EXPECT_EQ(0, bubble_learn_more_click_count_);
    263   EXPECT_EQ(1, dialog_learn_more_click_count_);
    264 }
    265 
    266 TEST_F(OneClickSigninBubbleViewTest, BubblePressEnterKey) {
    267   OneClickSigninBubbleView* one_click_view = ShowOneClickSigninBubble(
    268     BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
    269 
    270   // Simulate pressing the Enter key.
    271   views::View* view = one_click_view;
    272   const ui::Accelerator accelerator(ui::VKEY_RETURN, 0);
    273   view->AcceleratorPressed(accelerator);
    274 
    275   // View should no longer be showing.  The message loop will exit once the
    276   // fade animation of the bubble is done.
    277   content::RunAllPendingInMessageLoop();
    278   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    279 }
    280 
    281 TEST_F(OneClickSigninBubbleViewTest, DialogPressEnterKey) {
    282   OneClickSigninBubbleView* one_click_view = ShowOneClickSigninBubble(
    283     BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
    284 
    285   // Simulate pressing the Enter key.
    286   views::View* view = one_click_view;
    287   const ui::Accelerator accelerator(ui::VKEY_RETURN, 0);
    288   view->AcceleratorPressed(accelerator);
    289 
    290   // View should no longer be showing.  The message loop will exit once the
    291   // fade animation of the bubble is done.
    292   content::RunAllPendingInMessageLoop();
    293   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    294   EXPECT_TRUE(on_start_sync_called_);
    295   EXPECT_EQ(OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS, mode_);
    296 }
    297 
    298 TEST_F(OneClickSigninBubbleViewTest, BubblePressEscapeKey) {
    299   OneClickSigninBubbleView* one_click_view = ShowOneClickSigninBubble(
    300     BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE);
    301 
    302   // Simulate pressing the Escape key.
    303   views::View* view = one_click_view;
    304   const ui::Accelerator accelerator(ui::VKEY_ESCAPE, 0);
    305   view->AcceleratorPressed(accelerator);
    306 
    307   // View should no longer be showing.  The message loop will exit once the
    308   // fade animation of the bubble is done.
    309   content::RunAllPendingInMessageLoop();
    310   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    311 }
    312 
    313 TEST_F(OneClickSigninBubbleViewTest, DialogPressEscapeKey) {
    314   OneClickSigninBubbleView* one_click_view = ShowOneClickSigninBubble(
    315     BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_MODAL_DIALOG);
    316 
    317   // Simulate pressing the Escape key.
    318   views::View* view = one_click_view;
    319   const ui::Accelerator accelerator(ui::VKEY_ESCAPE, 0);
    320   view->AcceleratorPressed(accelerator);
    321 
    322   // View should no longer be showing.  The message loop will exit once the
    323   // fade animation of the bubble is done.
    324   content::RunAllPendingInMessageLoop();
    325   EXPECT_FALSE(OneClickSigninBubbleView::IsShowing());
    326   EXPECT_FALSE(on_start_sync_called_);
    327 }
    328