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.
5 #include "chrome/browser/ui/views/translate/translate_bubble_view.h"
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"
18 class MockTranslateBubbleModel
: public TranslateBubbleModel
{
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) {
36 virtual TranslateBubbleModel::ViewState
GetViewState() const OVERRIDE
{
37 return view_state_transition_
.view_state();
40 virtual void SetViewState(TranslateBubbleModel::ViewState view_state
)
42 view_state_transition_
.SetViewState(view_state
);
45 virtual void ShowError(TranslateErrors::Type error_type
) OVERRIDE
{
46 error_type_
= error_type
;
49 virtual void GoBackFromAdvanced() OVERRIDE
{
50 view_state_transition_
.GoBackFromAdvanced();
53 virtual int GetNumberOfLanguages() const OVERRIDE
{
57 virtual base::string16
GetLanguageNameAt(int index
) const OVERRIDE
{
58 return base::string16();
61 virtual int GetOriginalLanguageIndex() const OVERRIDE
{
62 return original_language_index_
;
65 virtual void UpdateOriginalLanguageIndex(int index
) OVERRIDE
{
66 original_language_index_
= index
;
69 virtual int GetTargetLanguageIndex() const OVERRIDE
{
70 return target_language_index_
;
73 virtual void UpdateTargetLanguageIndex(int index
) OVERRIDE
{
74 target_language_index_
= index
;
77 virtual void SetNeverTranslateLanguage(bool value
) OVERRIDE
{
78 never_translate_language_
= value
;
81 virtual void SetNeverTranslateSite(bool value
) OVERRIDE
{
82 never_translate_site_
= value
;
85 virtual bool ShouldAlwaysTranslate() const OVERRIDE
{
86 return should_always_translate_
;
89 virtual void SetAlwaysTranslate(bool value
) OVERRIDE
{
90 should_always_translate_
= value
;
91 set_always_translate_called_count_
++;
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_
;
100 virtual void RevertTranslation() OVERRIDE
{
101 revert_translation_called_
= true;
104 virtual void TranslationDeclined(bool explicitly_closed
) OVERRIDE
{
105 translation_declined_called_
= true;
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_
;
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_
;
131 class TranslateBubbleViewTest
: public views::ViewsTestBase
{
133 TranslateBubbleViewTest() {
137 virtual void SetUp() OVERRIDE
{
138 views::ViewsTestBase::SetUp();
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
;
145 anchor_widget_
.reset(new views::Widget());
146 anchor_widget_
->Init(params
);
147 anchor_widget_
->Show();
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(),
154 TranslateErrors::NONE
,
156 views::BubbleDelegateView::CreateBubble(bubble_
)->Show();
159 virtual void TearDown() OVERRIDE
{
160 bubble_
->GetWidget()->CloseNow();
161 anchor_widget_
.reset();
163 views::ViewsTestBase::TearDown();
166 scoped_ptr
<views::Widget
> anchor_widget_
;
167 MockTranslateBubbleModel
* mock_model_
;
168 TranslateBubbleView
* bubble_
;
171 TEST_F(TranslateBubbleViewTest
, TranslateButton
) {
172 EXPECT_FALSE(mock_model_
->translate_called_
);
174 // Press the "Translate" button.
175 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_TRANSLATE
);
176 EXPECT_TRUE(mock_model_
->translate_called_
);
179 TEST_F(TranslateBubbleViewTest
, AdvancedLink
) {
180 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
181 bubble_
->GetViewState());
183 // Click the "Advanced" link.
184 bubble_
->HandleLinkClicked(TranslateBubbleView::LINK_ID_ADVANCED
);
185 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ADVANCED
, bubble_
->GetViewState());
188 TEST_F(TranslateBubbleViewTest
, ShowOriginalButton
) {
189 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE
);
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_
);
197 TEST_F(TranslateBubbleViewTest
, TryAgainButton
) {
198 bubble_
->SwitchToErrorView(TranslateErrors::NETWORK
);
200 EXPECT_EQ(TranslateErrors::NETWORK
, mock_model_
->error_type_
);
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_
);
208 TEST_F(TranslateBubbleViewTest
, AlwaysTranslateCheckboxAndCancelButton
) {
209 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
211 // Click the "Always Translate" checkbox. Changing the state of this checkbox
212 // should NOT affect the model after pressing the cancel button.
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());
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_
);
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_
);
231 TEST_F(TranslateBubbleViewTest
, AlwaysTranslateCheckboxAndDoneButton
) {
232 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
234 // Click the "Always Translate" checkbox. Changing the state of this checkbox
235 // should affect the model after pressing the done button.
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());
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_
);
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_
);
254 TEST_F(TranslateBubbleViewTest
, DoneButton
) {
255 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
257 // Click the "Done" button to translate. The selected languages by the user
259 EXPECT_FALSE(mock_model_
->translate_called_
);
260 bubble_
->source_language_combobox_
->SetSelectedIndex(10);
261 bubble_
->HandleComboboxSelectedIndexChanged(
262 TranslateBubbleView::COMBOBOX_ID_SOURCE_LANGUAGE
);
263 bubble_
->target_language_combobox_
->SetSelectedIndex(20);
264 bubble_
->HandleComboboxSelectedIndexChanged(
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_
);
272 TEST_F(TranslateBubbleViewTest
, DoneButtonWithoutTranslating
) {
273 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
274 bubble_
->GetViewState());
276 // Translate the page once.
277 mock_model_
->Translate();
278 EXPECT_TRUE(mock_model_
->translate_called_
);
280 // Go back to the initial view.
281 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
282 bubble_
->GetViewState());
283 mock_model_
->translate_called_
= false;
285 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
286 bubble_
->GetViewState());
287 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
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
292 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_DONE
);
293 EXPECT_FALSE(mock_model_
->translate_called_
);
295 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
296 bubble_
->GetViewState());
299 TEST_F(TranslateBubbleViewTest
, CancelButtonReturningBeforeTranslate
) {
300 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
);
301 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
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());
310 TEST_F(TranslateBubbleViewTest
, CancelButtonReturningAfterTranslate
) {
311 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE
);
312 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
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());
321 TEST_F(TranslateBubbleViewTest
, CancelButtonReturningError
) {
322 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ERROR
);
323 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
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());