Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / infobars / translate_infobar_unittest.mm
1 // Copyright (c) 2011 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 #import <Cocoa/Cocoa.h>
6
7 #import "base/mac/scoped_nsobject.h"
8 #import "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/infobars/infobar_service.h"
11 #import "chrome/browser/translate/chrome_translate_client.h"
12 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
13 #import "chrome/browser/ui/cocoa/infobars/before_translate_infobar_controller.h"
14 #import "chrome/browser/ui/cocoa/infobars/infobar_cocoa.h"
15 #import "chrome/browser/ui/cocoa/infobars/translate_infobar_base.h"
16 #include "chrome/test/base/testing_profile.h"
17 #import "components/translate/core/browser/options_menu_model.h"
18 #import "components/translate/core/browser/translate_infobar_delegate.h"
19 #include "components/translate/core/browser/translate_language_list.h"
20 #include "components/translate/core/browser/translate_manager.h"
21 #import "content/public/browser/web_contents.h"
22 #include "ipc/ipc_message.h"
23 #import "testing/gmock/include/gmock/gmock.h"
24 #import "testing/gtest/include/gtest/gtest.h"
25 #import "testing/platform_test.h"
26
27 using content::WebContents;
28
29 namespace {
30
31 // All states the translate toolbar can assume.
32 translate::TranslateStep kTranslateToolbarStates[] = {
33     translate::TRANSLATE_STEP_BEFORE_TRANSLATE,
34     translate::TRANSLATE_STEP_AFTER_TRANSLATE,
35     translate::TRANSLATE_STEP_TRANSLATING,
36     translate::TRANSLATE_STEP_TRANSLATE_ERROR};
37
38 class MockTranslateInfoBarDelegate
39     : public translate::TranslateInfoBarDelegate {
40  public:
41   MockTranslateInfoBarDelegate(content::WebContents* web_contents,
42                                translate::TranslateStep step,
43                                translate::TranslateErrors::Type error)
44       : translate::TranslateInfoBarDelegate(
45             ChromeTranslateClient::GetManagerFromWebContents(web_contents)
46                 ->GetWeakPtr(),
47             false,
48             step,
49             NULL,
50             "en",
51             "es",
52             error,
53             false) {}
54
55   MOCK_METHOD0(Translate, void());
56   MOCK_METHOD0(RevertTranslation, void());
57
58   MOCK_METHOD0(TranslationDeclined, void());
59
60   virtual bool IsTranslatableLanguageByPrefs() OVERRIDE { return true; }
61   MOCK_METHOD0(ToggleTranslatableLanguageByPrefs, void());
62   virtual bool IsSiteBlacklisted() OVERRIDE { return false; }
63   MOCK_METHOD0(ToggleSiteBlacklist, void());
64   virtual bool ShouldAlwaysTranslate() OVERRIDE { return false; }
65   MOCK_METHOD0(ToggleAlwaysTranslate, void());
66 };
67
68 }  // namespace
69
70 class TranslationInfoBarTest : public CocoaProfileTest {
71  public:
72   TranslationInfoBarTest() : CocoaProfileTest(), infobar_(NULL) {
73   }
74
75   // Each test gets a single Mock translate delegate for the lifetime of
76   // the test.
77   virtual void SetUp() OVERRIDE {
78     translate::TranslateLanguageList::DisableUpdate();
79     CocoaProfileTest::SetUp();
80     web_contents_.reset(
81         WebContents::Create(WebContents::CreateParams(profile())));
82     InfoBarService::CreateForWebContents(web_contents_.get());
83     ChromeTranslateClient::CreateForWebContents(web_contents_.get());
84   }
85
86   virtual void TearDown() OVERRIDE {
87     if (infobar_) {
88       infobar_->CloseSoon();
89       infobar_ = NULL;
90     }
91     CocoaProfileTest::TearDown();
92   }
93
94   void CreateInfoBar(translate::TranslateStep type) {
95     translate::TranslateErrors::Type error = translate::TranslateErrors::NONE;
96     if (type == translate::TRANSLATE_STEP_TRANSLATE_ERROR)
97       error = translate::TranslateErrors::NETWORK;
98     [[infobar_controller_ view] removeFromSuperview];
99
100     ChromeTranslateClient* chrome_translate_client =
101         ChromeTranslateClient::FromWebContents(web_contents_.get());
102     scoped_ptr<translate::TranslateInfoBarDelegate> delegate(
103         new MockTranslateInfoBarDelegate(web_contents_.get(), type, error));
104     scoped_ptr<infobars::InfoBar> infobar(
105         chrome_translate_client->CreateInfoBar(delegate.Pass()));
106     if (infobar_)
107       infobar_->CloseSoon();
108     infobar_ = static_cast<InfoBarCocoa*>(infobar.release());
109     infobar_->SetOwner(InfoBarService::FromWebContents(web_contents_.get()));
110
111     infobar_controller_.reset([static_cast<TranslateInfoBarControllerBase*>(
112         infobar_->controller()) retain]);
113
114     // We need to set the window to be wide so that the options button
115     // doesn't overlap the other buttons.
116     [test_window() setContentSize:NSMakeSize(2000, 500)];
117     [[infobar_controller_ view] setFrame:NSMakeRect(0, 0, 2000, 500)];
118     [[test_window() contentView] addSubview:[infobar_controller_ view]];
119   }
120
121   MockTranslateInfoBarDelegate* infobar_delegate() const {
122     return static_cast<MockTranslateInfoBarDelegate*>(infobar_->delegate());
123   }
124
125   scoped_ptr<WebContents> web_contents_;
126   InfoBarCocoa* infobar_;  // weak, deletes itself
127   base::scoped_nsobject<TranslateInfoBarControllerBase> infobar_controller_;
128 };
129
130 // Check that we can instantiate a Translate Infobar correctly.
131 TEST_F(TranslationInfoBarTest, Instantiate) {
132   CreateInfoBar(translate::TRANSLATE_STEP_BEFORE_TRANSLATE);
133   ASSERT_TRUE(infobar_controller_.get());
134 }
135
136 // Check that clicking the Translate button calls Translate().
137 TEST_F(TranslationInfoBarTest, TranslateCalledOnButtonPress) {
138   CreateInfoBar(translate::TRANSLATE_STEP_BEFORE_TRANSLATE);
139
140   EXPECT_CALL(*infobar_delegate(), Translate()).Times(1);
141   [infobar_controller_ ok:nil];
142 }
143
144 // Check that clicking the "Retry" button calls Translate() when we're
145 // in the error mode - http://crbug.com/41315 .
146 TEST_F(TranslationInfoBarTest, TranslateCalledInErrorMode) {
147   CreateInfoBar(translate::TRANSLATE_STEP_TRANSLATE_ERROR);
148
149   EXPECT_CALL(*infobar_delegate(), Translate()).Times(1);
150
151   [infobar_controller_ ok:nil];
152 }
153
154 // Check that clicking the "Show Original button calls RevertTranslation().
155 TEST_F(TranslationInfoBarTest, RevertCalledOnButtonPress) {
156   CreateInfoBar(translate::TRANSLATE_STEP_BEFORE_TRANSLATE);
157
158   EXPECT_CALL(*infobar_delegate(), RevertTranslation()).Times(1);
159   [infobar_controller_ showOriginal:nil];
160 }
161
162 // Check that items in the options menu are hooked up correctly.
163 TEST_F(TranslationInfoBarTest, OptionsMenuItemsHookedUp) {
164   CreateInfoBar(translate::TRANSLATE_STEP_BEFORE_TRANSLATE);
165   EXPECT_CALL(*infobar_delegate(), Translate())
166     .Times(0);
167
168   [infobar_controller_ rebuildOptionsMenu:NO];
169   NSMenu* optionsMenu = [infobar_controller_ optionsMenu];
170   NSArray* optionsMenuItems = [optionsMenu itemArray];
171
172   EXPECT_EQ(7U, [optionsMenuItems count]);
173
174   // First item is the options menu button's title, so there's no need to test
175   // that the target on that is setup correctly.
176   for (NSUInteger i = 1; i < [optionsMenuItems count]; ++i) {
177     NSMenuItem* item = [optionsMenuItems objectAtIndex:i];
178     if (![item isSeparatorItem])
179       EXPECT_EQ([item target], infobar_controller_.get());
180   }
181   NSMenuItem* alwaysTranslateLanguateItem = [optionsMenuItems objectAtIndex:1];
182   NSMenuItem* neverTranslateLanguateItem = [optionsMenuItems objectAtIndex:2];
183   NSMenuItem* neverTranslateSiteItem = [optionsMenuItems objectAtIndex:3];
184   // Separator at 4.
185   NSMenuItem* reportBadLanguageItem = [optionsMenuItems objectAtIndex:5];
186   NSMenuItem* aboutTranslateItem = [optionsMenuItems objectAtIndex:6];
187
188   {
189     EXPECT_CALL(*infobar_delegate(), ToggleAlwaysTranslate())
190     .Times(1);
191     [infobar_controller_ optionsMenuChanged:alwaysTranslateLanguateItem];
192   }
193
194   {
195     EXPECT_CALL(*infobar_delegate(), ToggleTranslatableLanguageByPrefs())
196     .Times(1);
197     [infobar_controller_ optionsMenuChanged:neverTranslateLanguateItem];
198   }
199
200   {
201     EXPECT_CALL(*infobar_delegate(), ToggleSiteBlacklist())
202     .Times(1);
203     [infobar_controller_ optionsMenuChanged:neverTranslateSiteItem];
204   }
205
206   {
207     // Can't mock these effectively, so just check that the tag is set
208     // correctly.
209     EXPECT_EQ(translate::OptionsMenuModel::REPORT_BAD_DETECTION,
210               [reportBadLanguageItem tag]);
211     EXPECT_EQ(translate::OptionsMenuModel::ABOUT_TRANSLATE,
212               [aboutTranslateItem tag]);
213   }
214 }
215
216 // Check that selecting a new item from the "Source Language" popup in "before
217 // translate" mode doesn't trigger a translation or change state.
218 // http://crbug.com/36666
219 TEST_F(TranslationInfoBarTest, Bug36666) {
220   CreateInfoBar(translate::TRANSLATE_STEP_BEFORE_TRANSLATE);
221   EXPECT_CALL(*infobar_delegate(), Translate())
222     .Times(0);
223
224   int arbitrary_index = 2;
225   [infobar_controller_ sourceLanguageModified:arbitrary_index];
226   EXPECT_CALL(*infobar_delegate(), Translate())
227     .Times(0);
228 }
229
230 // Check that the infobar lays itself out correctly when instantiated in
231 // each of the states.
232 // http://crbug.com/36895
233 TEST_F(TranslationInfoBarTest, Bug36895) {
234   for (size_t i = 0; i < arraysize(kTranslateToolbarStates); ++i) {
235     CreateInfoBar(kTranslateToolbarStates[i]);
236     EXPECT_CALL(*infobar_delegate(), Translate())
237       .Times(0);
238     EXPECT_TRUE(
239         [infobar_controller_ verifyLayout]) << "Layout wrong, for state #" << i;
240   }
241 }
242
243 // Verify that the infobar shows the "Always translate this language" button
244 // after doing 3 translations.
245 TEST_F(TranslationInfoBarTest, TriggerShowAlwaysTranslateButton) {
246   scoped_ptr<translate::TranslatePrefs> translate_prefs(
247       ChromeTranslateClient::CreateTranslatePrefs(profile()->GetPrefs()));
248   translate_prefs->ResetTranslationAcceptedCount("en");
249   for (int i = 0; i < 4; ++i) {
250     translate_prefs->IncrementTranslationAcceptedCount("en");
251   }
252   CreateInfoBar(translate::TRANSLATE_STEP_BEFORE_TRANSLATE);
253   BeforeTranslateInfobarController* controller =
254       (BeforeTranslateInfobarController*)infobar_controller_.get();
255   EXPECT_TRUE([[controller alwaysTranslateButton] superview] !=  nil);
256   EXPECT_TRUE([[controller neverTranslateButton] superview] == nil);
257 }
258
259 // Verify that the infobar shows the "Never translate this language" button
260 // after denying 3 translations.
261 TEST_F(TranslationInfoBarTest, TriggerShowNeverTranslateButton) {
262   scoped_ptr<translate::TranslatePrefs> translate_prefs(
263       ChromeTranslateClient::CreateTranslatePrefs(profile()->GetPrefs()));
264   translate_prefs->ResetTranslationDeniedCount("en");
265   for (int i = 0; i < 4; ++i) {
266     translate_prefs->IncrementTranslationDeniedCount("en");
267   }
268   CreateInfoBar(translate::TRANSLATE_STEP_BEFORE_TRANSLATE);
269   BeforeTranslateInfobarController* controller =
270       (BeforeTranslateInfobarController*)infobar_controller_.get();
271   EXPECT_TRUE([[controller alwaysTranslateButton] superview] == nil);
272   EXPECT_TRUE([[controller neverTranslateButton] superview] != nil);
273 }