Home | History | Annotate | Download | only in translate
      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/translate/translate_bubble_view.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "chrome/browser/ui/translate/translate_bubble_model.h"
      9 #include "chrome/browser/ui/translate/translate_bubble_view_state_transition.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 #include "ui/views/controls/button/checkbox.h"
     12 #include "ui/views/controls/combobox/combobox.h"
     13 #include "ui/views/test/views_test_base.h"
     14 #include "ui/views/widget/widget.h"
     15 
     16 namespace {
     17 
     18 class MockTranslateBubbleModel : public TranslateBubbleModel {
     19  public:
     20   explicit MockTranslateBubbleModel(TranslateBubbleModel::ViewState view_state)
     21       : view_state_transition_(view_state),
     22         error_type_(TranslateErrors::NONE),
     23         original_language_index_(0),
     24         target_language_index_(1),
     25         never_translate_language_(false),
     26         never_translate_site_(false),
     27         should_always_translate_(false),
     28         set_always_translate_called_count_(0),
     29         translate_called_(false),
     30         revert_translation_called_(false),
     31         translation_declined_called_(false),
     32         original_language_index_on_translation_(-1),
     33         target_language_index_on_translation_(-1) {
     34   }
     35 
     36   virtual TranslateBubbleModel::ViewState GetViewState() const OVERRIDE {
     37     return view_state_transition_.view_state();
     38   }
     39 
     40   virtual void SetViewState(TranslateBubbleModel::ViewState view_state)
     41       OVERRIDE {
     42     view_state_transition_.SetViewState(view_state);
     43   }
     44 
     45   virtual void ShowError(TranslateErrors::Type error_type) OVERRIDE {
     46     error_type_ = error_type;
     47   }
     48 
     49   virtual void GoBackFromAdvanced() OVERRIDE {
     50     view_state_transition_.GoBackFromAdvanced();
     51   }
     52 
     53   virtual int GetNumberOfLanguages() const OVERRIDE {
     54     return 1000;
     55   }
     56 
     57   virtual base::string16 GetLanguageNameAt(int index) const OVERRIDE {
     58     return base::string16();
     59   }
     60 
     61   virtual int GetOriginalLanguageIndex() const OVERRIDE {
     62     return original_language_index_;
     63   }
     64 
     65   virtual void UpdateOriginalLanguageIndex(int index) OVERRIDE {
     66     original_language_index_ = index;
     67   }
     68 
     69   virtual int GetTargetLanguageIndex() const OVERRIDE {
     70     return target_language_index_;
     71   }
     72 
     73   virtual void UpdateTargetLanguageIndex(int index) OVERRIDE {
     74     target_language_index_ = index;
     75   }
     76 
     77   virtual void SetNeverTranslateLanguage(bool value) OVERRIDE {
     78     never_translate_language_ = value;
     79   }
     80 
     81   virtual void SetNeverTranslateSite(bool value) OVERRIDE {
     82     never_translate_site_ = value;
     83   }
     84 
     85   virtual bool ShouldAlwaysTranslate() const OVERRIDE {
     86     return should_always_translate_;
     87   }
     88 
     89   virtual void SetAlwaysTranslate(bool value) OVERRIDE {
     90     should_always_translate_ = value;
     91     set_always_translate_called_count_++;
     92   }
     93 
     94   virtual void Translate() OVERRIDE {
     95     translate_called_ = true;
     96     original_language_index_on_translation_ = original_language_index_;
     97     target_language_index_on_translation_ = target_language_index_;
     98   }
     99 
    100   virtual void RevertTranslation() OVERRIDE {
    101     revert_translation_called_ = true;
    102   }
    103 
    104   virtual void TranslationDeclined(bool explicitly_closed) OVERRIDE {
    105     translation_declined_called_ = true;
    106   }
    107 
    108   virtual bool IsPageTranslatedInCurrentLanguages() const OVERRIDE {
    109     return original_language_index_on_translation_ ==
    110         original_language_index_ &&
    111         target_language_index_on_translation_ == target_language_index_;
    112   }
    113 
    114   TranslateBubbleViewStateTransition view_state_transition_;
    115   TranslateErrors::Type error_type_;
    116   int original_language_index_;
    117   int target_language_index_;
    118   bool never_translate_language_;
    119   bool never_translate_site_;
    120   bool should_always_translate_;
    121   int set_always_translate_called_count_;
    122   bool translate_called_;
    123   bool revert_translation_called_;
    124   bool translation_declined_called_;
    125   int original_language_index_on_translation_;
    126   int target_language_index_on_translation_;
    127 };
    128 
    129 }  // namespace
    130 
    131 class TranslateBubbleViewTest : public views::ViewsTestBase {
    132  public:
    133   TranslateBubbleViewTest() {
    134   }
    135 
    136  protected:
    137   virtual void SetUp() OVERRIDE {
    138     views::ViewsTestBase::SetUp();
    139 
    140     // The bubble needs the parent as an anchor.
    141     views::Widget::InitParams params =
    142         CreateParams(views::Widget::InitParams::TYPE_WINDOW);
    143     params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    144 
    145     anchor_widget_.reset(new views::Widget());
    146     anchor_widget_->Init(params);
    147     anchor_widget_->Show();
    148 
    149     mock_model_ = new MockTranslateBubbleModel(
    150         TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE);
    151     scoped_ptr<TranslateBubbleModel> model(mock_model_);
    152     bubble_ = new TranslateBubbleView(anchor_widget_->GetContentsView(),
    153                                       model.Pass(),
    154                                       TranslateErrors::NONE,
    155                                       NULL);
    156     views::BubbleDelegateView::CreateBubble(bubble_)->Show();
    157   }
    158 
    159   virtual void TearDown() OVERRIDE {
    160     bubble_->GetWidget()->CloseNow();
    161     anchor_widget_.reset();
    162 
    163     views::ViewsTestBase::TearDown();
    164   }
    165 
    166   scoped_ptr<views::Widget> anchor_widget_;
    167   MockTranslateBubbleModel* mock_model_;
    168   TranslateBubbleView* bubble_;
    169 };
    170 
    171 TEST_F(TranslateBubbleViewTest, TranslateButton) {
    172   EXPECT_FALSE(mock_model_->translate_called_);
    173 
    174   // Press the "Translate" button.
    175   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_TRANSLATE);
    176   EXPECT_TRUE(mock_model_->translate_called_);
    177 }
    178 
    179 TEST_F(TranslateBubbleViewTest, AdvancedLink) {
    180   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE,
    181             bubble_->GetViewState());
    182 
    183   // Click the "Advanced" link.
    184   bubble_->HandleLinkClicked(TranslateBubbleView::LINK_ID_ADVANCED);
    185   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ADVANCED, bubble_->GetViewState());
    186 }
    187 
    188 TEST_F(TranslateBubbleViewTest, ShowOriginalButton) {
    189   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE);
    190 
    191   // Click the "Show original" button to revert translation.
    192   EXPECT_FALSE(mock_model_->revert_translation_called_);
    193   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_SHOW_ORIGINAL);
    194   EXPECT_TRUE(mock_model_->revert_translation_called_);
    195 }
    196 
    197 TEST_F(TranslateBubbleViewTest, TryAgainButton) {
    198   bubble_->SwitchToErrorView(TranslateErrors::NETWORK);
    199 
    200   EXPECT_EQ(TranslateErrors::NETWORK, mock_model_->error_type_);
    201 
    202   // Click the "Try again" button to translate.
    203   EXPECT_FALSE(mock_model_->translate_called_);
    204   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_TRY_AGAIN);
    205   EXPECT_TRUE(mock_model_->translate_called_);
    206 }
    207 
    208 TEST_F(TranslateBubbleViewTest, AlwaysTranslateCheckboxAndCancelButton) {
    209   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED);
    210 
    211   // Click the "Always Translate" checkbox. Changing the state of this checkbox
    212   // should NOT affect the model after pressing the cancel button.
    213 
    214   // Check the initial state.
    215   EXPECT_FALSE(mock_model_->should_always_translate_);
    216   EXPECT_EQ(0, mock_model_->set_always_translate_called_count_);
    217   EXPECT_FALSE(bubble_->always_translate_checkbox_->checked());
    218 
    219   // Click the checkbox. The state is not saved yet.
    220   bubble_->always_translate_checkbox_->SetChecked(true);
    221   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_ALWAYS_TRANSLATE);
    222   EXPECT_FALSE(mock_model_->should_always_translate_);
    223   EXPECT_EQ(0, mock_model_->set_always_translate_called_count_);
    224 
    225   // Click the cancel button. The state is not saved.
    226   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_CANCEL);
    227   EXPECT_FALSE(mock_model_->should_always_translate_);
    228   EXPECT_EQ(0, mock_model_->set_always_translate_called_count_);
    229 }
    230 
    231 TEST_F(TranslateBubbleViewTest, AlwaysTranslateCheckboxAndDoneButton) {
    232   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED);
    233 
    234   // Click the "Always Translate" checkbox. Changing the state of this checkbox
    235   // should affect the model after pressing the done button.
    236 
    237   // Check the initial state.
    238   EXPECT_FALSE(mock_model_->should_always_translate_);
    239   EXPECT_EQ(0, mock_model_->set_always_translate_called_count_);
    240   EXPECT_FALSE(bubble_->always_translate_checkbox_->checked());
    241 
    242   // Click the checkbox. The state is not saved yet.
    243   bubble_->always_translate_checkbox_->SetChecked(true);
    244   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_ALWAYS_TRANSLATE);
    245   EXPECT_FALSE(mock_model_->should_always_translate_);
    246   EXPECT_EQ(0, mock_model_->set_always_translate_called_count_);
    247 
    248   // Click the done button. The state is saved.
    249   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_DONE);
    250   EXPECT_TRUE(mock_model_->should_always_translate_);
    251   EXPECT_EQ(1, mock_model_->set_always_translate_called_count_);
    252 }
    253 
    254 TEST_F(TranslateBubbleViewTest, DoneButton) {
    255   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED);
    256 
    257   // Click the "Done" button to translate. The selected languages by the user
    258   // are applied.
    259   EXPECT_FALSE(mock_model_->translate_called_);
    260   bubble_->source_language_combobox_->SetSelectedIndex(10);
    261   bubble_->HandleComboboxPerformAction(
    262       TranslateBubbleView::COMBOBOX_ID_SOURCE_LANGUAGE);
    263   bubble_->target_language_combobox_->SetSelectedIndex(20);
    264   bubble_->HandleComboboxPerformAction(
    265       TranslateBubbleView::COMBOBOX_ID_TARGET_LANGUAGE);
    266   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_DONE);
    267   EXPECT_TRUE(mock_model_->translate_called_);
    268   EXPECT_EQ(10, mock_model_->original_language_index_);
    269   EXPECT_EQ(20, mock_model_->target_language_index_);
    270 }
    271 
    272 TEST_F(TranslateBubbleViewTest, DoneButtonWithoutTranslating) {
    273   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE,
    274             bubble_->GetViewState());
    275 
    276   // Translate the page once.
    277   mock_model_->Translate();
    278   EXPECT_TRUE(mock_model_->translate_called_);
    279 
    280   // Go back to the initial view.
    281   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE,
    282             bubble_->GetViewState());
    283   mock_model_->translate_called_ = false;
    284 
    285   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE,
    286             bubble_->GetViewState());
    287   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED);
    288 
    289   // Click the "Done" button with the current language pair. This time,
    290   // translation is not performed and the view state will be back to the
    291   // previous view.
    292   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_DONE);
    293   EXPECT_FALSE(mock_model_->translate_called_);
    294 
    295   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE,
    296             bubble_->GetViewState());
    297 }
    298 
    299 TEST_F(TranslateBubbleViewTest, CancelButtonReturningBeforeTranslate) {
    300   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE);
    301   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED);
    302 
    303   // Click the "Cancel" button to go back.
    304   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ADVANCED, bubble_->GetViewState());
    305   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_CANCEL);
    306   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE,
    307             bubble_->GetViewState());
    308 }
    309 
    310 TEST_F(TranslateBubbleViewTest, CancelButtonReturningAfterTranslate) {
    311   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE);
    312   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED);
    313 
    314   // Click the "Cancel" button to go back.
    315   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ADVANCED, bubble_->GetViewState());
    316   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_CANCEL);
    317   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE,
    318             bubble_->GetViewState());
    319 }
    320 
    321 TEST_F(TranslateBubbleViewTest, CancelButtonReturningError) {
    322   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_ERROR);
    323   bubble_->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED);
    324 
    325   // Click the "Cancel" button to go back.
    326   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ADVANCED, bubble_->GetViewState());
    327   bubble_->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_CANCEL);
    328   EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ERROR, bubble_->GetViewState());
    329 }
    330