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