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_(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) {}
35 TranslateBubbleModel::ViewState
GetViewState() const override
{
36 return view_state_transition_
.view_state();
39 void SetViewState(TranslateBubbleModel::ViewState view_state
) override
{
40 view_state_transition_
.SetViewState(view_state
);
43 void ShowError(translate::TranslateErrors::Type error_type
) override
{
44 error_type_
= error_type
;
47 void GoBackFromAdvanced() override
{
48 view_state_transition_
.GoBackFromAdvanced();
51 int GetNumberOfLanguages() const override
{ return 1000; }
53 base::string16
GetLanguageNameAt(int index
) const override
{
54 return base::string16();
57 int GetOriginalLanguageIndex() const override
{
58 return original_language_index_
;
61 void UpdateOriginalLanguageIndex(int index
) override
{
62 original_language_index_
= index
;
65 int GetTargetLanguageIndex() const override
{ return target_language_index_
; }
67 void UpdateTargetLanguageIndex(int index
) override
{
68 target_language_index_
= index
;
71 void SetNeverTranslateLanguage(bool value
) override
{
72 never_translate_language_
= value
;
75 void SetNeverTranslateSite(bool value
) override
{
76 never_translate_site_
= value
;
79 bool ShouldAlwaysTranslate() const override
{
80 return should_always_translate_
;
83 void SetAlwaysTranslate(bool value
) override
{
84 should_always_translate_
= value
;
85 set_always_translate_called_count_
++;
88 void Translate() override
{
89 translate_called_
= true;
90 original_language_index_on_translation_
= original_language_index_
;
91 target_language_index_on_translation_
= target_language_index_
;
94 void RevertTranslation() override
{ revert_translation_called_
= true; }
96 void TranslationDeclined(bool explicitly_closed
) override
{
97 translation_declined_called_
= true;
100 bool IsPageTranslatedInCurrentLanguages() const override
{
101 return original_language_index_on_translation_
==
102 original_language_index_
&&
103 target_language_index_on_translation_
== target_language_index_
;
106 TranslateBubbleViewStateTransition view_state_transition_
;
107 translate::TranslateErrors::Type error_type_
;
108 int original_language_index_
;
109 int target_language_index_
;
110 bool never_translate_language_
;
111 bool never_translate_site_
;
112 bool should_always_translate_
;
113 int set_always_translate_called_count_
;
114 bool translate_called_
;
115 bool revert_translation_called_
;
116 bool translation_declined_called_
;
117 int original_language_index_on_translation_
;
118 int target_language_index_on_translation_
;
123 class TranslateBubbleViewTest
: public views::ViewsTestBase
{
125 TranslateBubbleViewTest() {
129 void SetUp() override
{
130 views::ViewsTestBase::SetUp();
132 // The bubble needs the parent as an anchor.
133 views::Widget::InitParams params
=
134 CreateParams(views::Widget::InitParams::TYPE_WINDOW
);
135 params
.ownership
= views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
137 anchor_widget_
.reset(new views::Widget());
138 anchor_widget_
->Init(params
);
139 anchor_widget_
->Show();
141 mock_model_
= new MockTranslateBubbleModel(
142 TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
);
143 scoped_ptr
<TranslateBubbleModel
> model(mock_model_
);
144 bubble_
= new TranslateBubbleView(anchor_widget_
->GetContentsView(),
146 translate::TranslateErrors::NONE
,
148 views::BubbleDelegateView::CreateBubble(bubble_
)->Show();
151 void TearDown() override
{
152 bubble_
->GetWidget()->CloseNow();
153 anchor_widget_
.reset();
155 views::ViewsTestBase::TearDown();
158 scoped_ptr
<views::Widget
> anchor_widget_
;
159 MockTranslateBubbleModel
* mock_model_
;
160 TranslateBubbleView
* bubble_
;
163 TEST_F(TranslateBubbleViewTest
, TranslateButton
) {
164 EXPECT_FALSE(mock_model_
->translate_called_
);
166 // Press the "Translate" button.
167 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_TRANSLATE
);
168 EXPECT_TRUE(mock_model_
->translate_called_
);
171 TEST_F(TranslateBubbleViewTest
, AdvancedLink
) {
172 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
173 bubble_
->GetViewState());
175 // Click the "Advanced" link.
176 bubble_
->HandleLinkClicked(TranslateBubbleView::LINK_ID_ADVANCED
);
177 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ADVANCED
, bubble_
->GetViewState());
180 TEST_F(TranslateBubbleViewTest
, ShowOriginalButton
) {
181 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE
);
183 // Click the "Show original" button to revert translation.
184 EXPECT_FALSE(mock_model_
->revert_translation_called_
);
185 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_SHOW_ORIGINAL
);
186 EXPECT_TRUE(mock_model_
->revert_translation_called_
);
189 TEST_F(TranslateBubbleViewTest
, TryAgainButton
) {
190 bubble_
->SwitchToErrorView(translate::TranslateErrors::NETWORK
);
192 EXPECT_EQ(translate::TranslateErrors::NETWORK
, mock_model_
->error_type_
);
194 // Click the "Try again" button to translate.
195 EXPECT_FALSE(mock_model_
->translate_called_
);
196 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_TRY_AGAIN
);
197 EXPECT_TRUE(mock_model_
->translate_called_
);
200 TEST_F(TranslateBubbleViewTest
, AlwaysTranslateCheckboxAndCancelButton
) {
201 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
203 // Click the "Always Translate" checkbox. Changing the state of this checkbox
204 // should NOT affect the model after pressing the cancel button.
206 // Check the initial state.
207 EXPECT_FALSE(mock_model_
->should_always_translate_
);
208 EXPECT_EQ(0, mock_model_
->set_always_translate_called_count_
);
209 EXPECT_FALSE(bubble_
->always_translate_checkbox_
->checked());
211 // Click the checkbox. The state is not saved yet.
212 bubble_
->always_translate_checkbox_
->SetChecked(true);
213 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_ALWAYS_TRANSLATE
);
214 EXPECT_FALSE(mock_model_
->should_always_translate_
);
215 EXPECT_EQ(0, mock_model_
->set_always_translate_called_count_
);
217 // Click the cancel button. The state is not saved.
218 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_CANCEL
);
219 EXPECT_FALSE(mock_model_
->should_always_translate_
);
220 EXPECT_EQ(0, mock_model_
->set_always_translate_called_count_
);
223 TEST_F(TranslateBubbleViewTest
, AlwaysTranslateCheckboxAndDoneButton
) {
224 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
226 // Click the "Always Translate" checkbox. Changing the state of this checkbox
227 // should affect the model after pressing the done button.
229 // Check the initial state.
230 EXPECT_FALSE(mock_model_
->should_always_translate_
);
231 EXPECT_EQ(0, mock_model_
->set_always_translate_called_count_
);
232 EXPECT_FALSE(bubble_
->always_translate_checkbox_
->checked());
234 // Click the checkbox. The state is not saved yet.
235 bubble_
->always_translate_checkbox_
->SetChecked(true);
236 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_ALWAYS_TRANSLATE
);
237 EXPECT_FALSE(mock_model_
->should_always_translate_
);
238 EXPECT_EQ(0, mock_model_
->set_always_translate_called_count_
);
240 // Click the done button. The state is saved.
241 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_DONE
);
242 EXPECT_TRUE(mock_model_
->should_always_translate_
);
243 EXPECT_EQ(1, mock_model_
->set_always_translate_called_count_
);
246 TEST_F(TranslateBubbleViewTest
, DoneButton
) {
247 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
249 // Click the "Done" button to translate. The selected languages by the user
251 EXPECT_FALSE(mock_model_
->translate_called_
);
252 bubble_
->source_language_combobox_
->SetSelectedIndex(10);
253 bubble_
->HandleComboboxPerformAction(
254 TranslateBubbleView::COMBOBOX_ID_SOURCE_LANGUAGE
);
255 bubble_
->target_language_combobox_
->SetSelectedIndex(20);
256 bubble_
->HandleComboboxPerformAction(
257 TranslateBubbleView::COMBOBOX_ID_TARGET_LANGUAGE
);
258 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_DONE
);
259 EXPECT_TRUE(mock_model_
->translate_called_
);
260 EXPECT_EQ(10, mock_model_
->original_language_index_
);
261 EXPECT_EQ(20, mock_model_
->target_language_index_
);
264 TEST_F(TranslateBubbleViewTest
, DoneButtonWithoutTranslating
) {
265 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
266 bubble_
->GetViewState());
268 // Translate the page once.
269 mock_model_
->Translate();
270 EXPECT_TRUE(mock_model_
->translate_called_
);
272 // Go back to the initial view.
273 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
274 bubble_
->GetViewState());
275 mock_model_
->translate_called_
= false;
277 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
278 bubble_
->GetViewState());
279 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
281 // Click the "Done" button with the current language pair. This time,
282 // translation is not performed and the view state will be back to the
284 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_DONE
);
285 EXPECT_FALSE(mock_model_
->translate_called_
);
287 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
288 bubble_
->GetViewState());
291 TEST_F(TranslateBubbleViewTest
, CancelButtonReturningBeforeTranslate
) {
292 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
);
293 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
295 // Click the "Cancel" button to go back.
296 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ADVANCED
, bubble_
->GetViewState());
297 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_CANCEL
);
298 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE
,
299 bubble_
->GetViewState());
302 TEST_F(TranslateBubbleViewTest
, CancelButtonReturningAfterTranslate
) {
303 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE
);
304 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
306 // Click the "Cancel" button to go back.
307 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ADVANCED
, bubble_
->GetViewState());
308 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_CANCEL
);
309 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE
,
310 bubble_
->GetViewState());
313 TEST_F(TranslateBubbleViewTest
, CancelButtonReturningError
) {
314 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ERROR
);
315 bubble_
->SwitchView(TranslateBubbleModel::VIEW_STATE_ADVANCED
);
317 // Click the "Cancel" button to go back.
318 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ADVANCED
, bubble_
->GetViewState());
319 bubble_
->HandleButtonPressed(TranslateBubbleView::BUTTON_ID_CANCEL
);
320 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ERROR
, bubble_
->GetViewState());