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