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