translate_bubble_view_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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
16namespace {
17
18class 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
131class 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
171TEST_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
179TEST_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
188TEST_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
197TEST_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
208TEST_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
231TEST_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
254TEST_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
272TEST_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
299TEST_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
310TEST_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
321TEST_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