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