blob: 1b63937b5b6076a9460b229577347c467f9453b7 [file] [log] [blame]
[email protected]2253b3b2012-06-03 22:39:151// Copyright (c) 2012 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
6#include <algorithm>
7#include <set>
8#include <vector>
9
10#include "base/json/json_writer.h"
11#include "base/memory/scoped_ptr.h"
[email protected]03b9b4e2012-10-22 20:01:5212#include "base/prefs/public/pref_change_registrar.h"
[email protected]2253b3b2012-06-03 22:39:1513#include "base/stringprintf.h"
14#include "base/utf_string_conversions.h"
15#include "base/values.h"
16#include "chrome/app/chrome_command_ids.h"
[email protected]4f822f022012-12-20 19:11:4217#include "chrome/browser/api/infobars/infobar_service.h"
[email protected]2253b3b2012-06-03 22:39:1518#include "chrome/browser/extensions/test_extension_system.h"
19#include "chrome/browser/infobars/infobar.h"
[email protected]2253b3b2012-06-03 22:39:1520#include "chrome/browser/prefs/pref_service.h"
[email protected]f8a2e132012-08-31 18:16:2021#include "chrome/browser/prefs/session_startup_pref.h"
[email protected]2253b3b2012-06-03 22:39:1522#include "chrome/browser/tab_contents/render_view_context_menu.h"
23#include "chrome/browser/translate/translate_infobar_delegate.h"
24#include "chrome/browser/translate/translate_manager.h"
25#include "chrome/browser/translate/translate_prefs.h"
[email protected]f8a2e132012-08-31 18:16:2026#include "chrome/browser/translate/translate_tab_helper.h"
27#include "chrome/browser/ui/browser.h"
28#include "chrome/browser/ui/browser_tabstrip.h"
[email protected]2253b3b2012-06-03 22:39:1529#include "chrome/common/chrome_notification_types.h"
30#include "chrome/common/pref_names.h"
31#include "chrome/common/render_messages.h"
[email protected]f8a2e132012-08-31 18:16:2032#include "chrome/common/url_constants.h"
[email protected]292ccc92012-10-17 12:46:0233#include "chrome/test/base/chrome_render_view_host_test_harness.h"
[email protected]f8a2e132012-08-31 18:16:2034#include "chrome/test/base/in_process_browser_test.h"
[email protected]2253b3b2012-06-03 22:39:1535#include "chrome/test/base/testing_browser_process.h"
36#include "chrome/test/base/testing_profile.h"
[email protected]f8a2e132012-08-31 18:16:2037#include "chrome/test/base/ui_test_utils.h"
[email protected]2253b3b2012-06-03 22:39:1538#include "content/public/browser/navigation_details.h"
39#include "content/public/browser/navigation_entry.h"
40#include "content/public/browser/notification_details.h"
41#include "content/public/browser/notification_registrar.h"
42#include "content/public/browser/web_contents.h"
43#include "content/public/test/mock_notification_observer.h"
44#include "content/public/test/mock_render_process_host.h"
[email protected]899617f2012-06-04 02:27:1445#include "content/public/test/render_view_test.h"
[email protected]e97882f2012-06-04 02:23:1746#include "content/public/test/test_browser_thread.h"
[email protected]b1e3f202012-06-04 14:45:5047#include "content/public/test/test_renderer_host.h"
[email protected]2253b3b2012-06-03 22:39:1548#include "grit/generated_resources.h"
49#include "ipc/ipc_test_sink.h"
[email protected]8f2d8bdd2012-06-19 23:44:0550#include "net/url_request/test_url_fetcher_factory.h"
[email protected]2253b3b2012-06-03 22:39:1551#include "testing/gmock/include/gmock/gmock.h"
[email protected]8f2d8bdd2012-06-19 23:44:0552#include "third_party/cld/languages/public/languages.h"
[email protected]2253b3b2012-06-03 22:39:1553#include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
54#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
[email protected]2253b3b2012-06-03 22:39:1555
56using content::BrowserThread;
57using content::NavigationController;
58using content::RenderViewHostTester;
59using content::WebContents;
60using testing::_;
61using testing::Pointee;
62using testing::Property;
63using WebKit::WebContextMenuData;
64
[email protected]f8a2e132012-08-31 18:16:2065// An observer that keeps track of whether a navigation entry was committed.
66class NavEntryCommittedObserver : public content::NotificationObserver {
67 public:
68 explicit NavEntryCommittedObserver(WebContents* web_contents) {
69 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
70 content::Source<NavigationController>(
71 &web_contents->GetController()));
72 }
73
74 virtual void Observe(int type,
75 const content::NotificationSource& source,
76 const content::NotificationDetails& details) {
77 DCHECK(type == content::NOTIFICATION_NAV_ENTRY_COMMITTED);
78 details_ =
79 *(content::Details<content::LoadCommittedDetails>(details).ptr());
80 }
81
82 const content::LoadCommittedDetails&
83 get_load_commited_details() const {
84 return details_;
85 }
86
87 private:
88 content::LoadCommittedDetails details_;
89 content::NotificationRegistrar registrar_;
90
91 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver);
92};
93
[email protected]292ccc92012-10-17 12:46:0294class TranslateManagerTest : public ChromeRenderViewHostTestHarness,
[email protected]116129e02012-11-21 17:26:2795 public content::NotificationObserver {
[email protected]2253b3b2012-06-03 22:39:1596 public:
97 TranslateManagerTest()
[email protected]116129e02012-11-21 17:26:2798 : pref_callback_(base::Bind(&TranslateManagerTest::OnPreferenceChanged,
99 base::Unretained(this))),
100 ui_thread_(BrowserThread::UI, &message_loop_) {
[email protected]2253b3b2012-06-03 22:39:15101 }
102
103 // Simulates navigating to a page and getting the page contents and language
104 // for that navigation.
105 void SimulateNavigation(const GURL& url,
106 const std::string& lang,
107 bool page_translatable) {
108 NavigateAndCommit(url);
109 SimulateOnTranslateLanguageDetermined(lang, page_translatable);
110 }
111
112 void SimulateOnTranslateLanguageDetermined(const std::string& lang,
113 bool page_translatable) {
114 RenderViewHostTester::TestOnMessageReceived(
115 rvh(),
116 ChromeViewHostMsg_TranslateLanguageDetermined(
117 0, lang, page_translatable));
118 }
119
120 bool GetTranslateMessage(int* page_id,
121 std::string* original_lang,
122 std::string* target_lang) {
123 const IPC::Message* message =
124 process()->sink().GetFirstMessageMatching(
125 ChromeViewMsg_TranslatePage::ID);
126 if (!message)
127 return false;
128 Tuple4<int, std::string, std::string, std::string> translate_param;
129 ChromeViewMsg_TranslatePage::Read(message, &translate_param);
130 if (page_id)
131 *page_id = translate_param.a;
132 // Ignore translate_param.b which is the script injected in the page.
133 if (original_lang)
134 *original_lang = translate_param.c;
135 if (target_lang)
136 *target_lang = translate_param.d;
137 return true;
138 }
139
[email protected]4f822f022012-12-20 19:11:42140 InfoBarService* infobar_service() {
141 return InfoBarService::FromWebContents(web_contents());
[email protected]2253b3b2012-06-03 22:39:15142 }
143
144 // Returns the translate infobar if there is 1 infobar and it is a translate
145 // infobar.
146 TranslateInfoBarDelegate* GetTranslateInfoBar() {
[email protected]4f822f022012-12-20 19:11:42147 return (infobar_service()->GetInfoBarCount() == 1) ?
148 infobar_service()->GetInfoBarDelegateAt(0)->
[email protected]2253b3b2012-06-03 22:39:15149 AsTranslateInfoBarDelegate() : NULL;
150 }
151
152 // If there is 1 infobar and it is a translate infobar, closes it and returns
153 // true. Returns false otherwise.
154 bool CloseTranslateInfoBar() {
155 InfoBarDelegate* infobar = GetTranslateInfoBar();
156 if (!infobar)
157 return false;
158 infobar->InfoBarDismissed(); // Simulates closing the infobar.
[email protected]4f822f022012-12-20 19:11:42159 infobar_service()->RemoveInfoBar(infobar);
[email protected]2253b3b2012-06-03 22:39:15160 return true;
161 }
162
163 // Checks whether |infobar| has been removed and clears the removed infobar
164 // list.
165 bool CheckInfoBarRemovedAndReset(InfoBarDelegate* delegate) {
166 bool found = removed_infobars_.count(delegate) != 0;
167 removed_infobars_.clear();
168 return found;
169 }
170
171 // Returns true if at least one infobar was closed.
172 bool InfoBarRemoved() {
173 return !removed_infobars_.empty();
174 }
175
176 // Clears the list of stored removed infobars.
177 void ClearRemovedInfoBars() {
178 removed_infobars_.clear();
179 }
180
181 void ExpireTranslateScriptImmediately() {
182 TranslateManager::GetInstance()->set_translate_script_expiration_delay(0);
183 }
184
185 // If there is 1 infobar and it is a translate infobar, deny translation and
186 // returns true. Returns false otherwise.
187 bool DenyTranslation() {
188 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
189 if (!infobar)
190 return false;
191 infobar->TranslationDeclined();
[email protected]4f822f022012-12-20 19:11:42192 infobar_service()->RemoveInfoBar(infobar);
[email protected]2253b3b2012-06-03 22:39:15193 return true;
194 }
195
[email protected]f8a2e132012-08-31 18:16:20196 void ReloadAndWait() {
[email protected]921441c2012-10-19 22:16:01197 NavEntryCommittedObserver nav_observer(web_contents());
[email protected]f8a2e132012-08-31 18:16:20198 Reload();
199
200 // Ensures it is really handled a reload.
201 const content::LoadCommittedDetails& nav_details =
202 nav_observer.get_load_commited_details();
203 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation.
204 EXPECT_EQ(content::NAVIGATION_TYPE_EXISTING_PAGE, nav_details.type);
205
206 // The TranslateManager class processes the navigation entry committed
207 // notification in a posted task; process that task.
[email protected]b8f50ce2012-11-17 12:37:57208 MessageLoop::current()->RunUntilIdle();
[email protected]f8a2e132012-08-31 18:16:20209 }
210
[email protected]2253b3b2012-06-03 22:39:15211 virtual void Observe(int type,
212 const content::NotificationSource& source,
213 const content::NotificationDetails& details) {
214 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
215 removed_infobars_.insert(
216 content::Details<InfoBarRemovedDetails>(details)->first);
217 }
218
[email protected]116129e02012-11-21 17:26:27219 MOCK_METHOD1(OnPreferenceChanged, void(const std::string&));
[email protected]a6a7ced2012-11-01 17:24:18220
[email protected]2253b3b2012-06-03 22:39:15221 protected:
222 virtual void SetUp() {
[email protected]899617f2012-06-04 02:27:14223 WebKit::initialize(webkit_platform_support_.Get());
[email protected]2253b3b2012-06-03 22:39:15224 // Access the TranslateManager singleton so it is created before we call
[email protected]292ccc92012-10-17 12:46:02225 // ChromeRenderViewHostTestHarness::SetUp() to match what's done in Chrome,
[email protected]2253b3b2012-06-03 22:39:15226 // where the TranslateManager is created before the WebContents. This
227 // matters as they both register for similar events and we want the
228 // notifications to happen in the same sequence (TranslateManager first,
229 // WebContents second). Also clears the translate script so it is fetched
230 // everytime and sets the expiration delay to a large value by default (in
231 // case it was zeroed in a previous test).
232 TranslateManager::GetInstance()->ClearTranslateScript();
233 TranslateManager::GetInstance()->
234 set_translate_script_expiration_delay(60 * 60 * 1000);
235
[email protected]292ccc92012-10-17 12:46:02236 ChromeRenderViewHostTestHarness::SetUp();
[email protected]4f822f022012-12-20 19:11:42237 InfoBarService::CreateForWebContents(web_contents());
[email protected]292ccc92012-10-17 12:46:02238 TranslateTabHelper::CreateForWebContents(web_contents());
[email protected]2253b3b2012-06-03 22:39:15239
240 notification_registrar_.Add(this,
241 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
[email protected]4f822f022012-12-20 19:11:42242 content::Source<InfoBarService>(infobar_service()));
[email protected]2253b3b2012-06-03 22:39:15243 }
244
245 virtual void TearDown() {
246 process()->sink().ClearMessages();
247
248 notification_registrar_.Remove(this,
249 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
[email protected]4f822f022012-12-20 19:11:42250 content::Source<InfoBarService>(infobar_service()));
[email protected]2253b3b2012-06-03 22:39:15251
[email protected]292ccc92012-10-17 12:46:02252 ChromeRenderViewHostTestHarness::TearDown();
[email protected]2253b3b2012-06-03 22:39:15253 WebKit::shutdown();
254 }
255
256 void SimulateTranslateScriptURLFetch(bool success) {
[email protected]8f2d8bdd2012-06-19 23:44:05257 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
[email protected]2253b3b2012-06-03 22:39:15258 ASSERT_TRUE(fetcher);
259 net::URLRequestStatus status;
260 status.set_status(success ? net::URLRequestStatus::SUCCESS :
261 net::URLRequestStatus::FAILED);
262 fetcher->set_url(fetcher->GetOriginalURL());
263 fetcher->set_status(status);
264 fetcher->set_response_code(success ? 200 : 500);
265 fetcher->delegate()->OnURLFetchComplete(fetcher);
266 }
267
268 void SimulateSupportedLanguagesURLFetch(
269 bool success, const std::vector<std::string>& languages) {
[email protected]8f2d8bdd2012-06-19 23:44:05270 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(1);
[email protected]2253b3b2012-06-03 22:39:15271 ASSERT_TRUE(fetcher);
272 net::URLRequestStatus status;
273 status.set_status(success ? net::URLRequestStatus::SUCCESS :
274 net::URLRequestStatus::FAILED);
275
276 std::string data;
277 if (success) {
278 data = base::StringPrintf("%s{'sl': {'bla': 'bla'}, '%s': {",
279 TranslateManager::kLanguageListCallbackName,
280 TranslateManager::kTargetLanguagesKey);
281 const char* comma = "";
282 for (size_t i = 0; i < languages.size(); ++i) {
283 data += base::StringPrintf(
284 "%s'%s': 'UnusedFullName'", comma, languages[i].c_str());
285 if (i == 0)
286 comma = ",";
287 }
288 data += "}})";
289 }
290 fetcher->set_url(fetcher->GetOriginalURL());
291 fetcher->set_status(status);
292 fetcher->set_response_code(success ? 200 : 500);
293 fetcher->SetResponseString(data);
294 fetcher->delegate()->OnURLFetchComplete(fetcher);
295 }
296
297 void SetPrefObserverExpectation(const char* path) {
[email protected]116129e02012-11-21 17:26:27298 EXPECT_CALL(*this, OnPreferenceChanged(std::string(path)));
[email protected]2253b3b2012-06-03 22:39:15299 }
300
[email protected]116129e02012-11-21 17:26:27301 PrefChangeRegistrar::NamedChangeCallback pref_callback_;
302
[email protected]2253b3b2012-06-03 22:39:15303 private:
304 content::NotificationRegistrar notification_registrar_;
[email protected]8f2d8bdd2012-06-19 23:44:05305 net::TestURLFetcherFactory url_fetcher_factory_;
[email protected]2253b3b2012-06-03 22:39:15306 content::TestBrowserThread ui_thread_;
307 content::RenderViewTest::RendererWebKitPlatformSupportImplNoSandbox
308 webkit_platform_support_;
309
310 // The infobars that have been removed.
311 // WARNING: the pointers point to deleted objects, use only for comparison.
312 std::set<InfoBarDelegate*> removed_infobars_;
313
314 DISALLOW_COPY_AND_ASSIGN(TranslateManagerTest);
315};
316
[email protected]2253b3b2012-06-03 22:39:15317namespace {
318
319class TestRenderViewContextMenu : public RenderViewContextMenu {
320 public:
321 static TestRenderViewContextMenu* CreateContextMenu(
322 WebContents* web_contents) {
323 content::ContextMenuParams params;
324 params.media_type = WebKit::WebContextMenuData::MediaTypeNone;
325 params.x = 0;
326 params.y = 0;
327 params.is_image_blocked = false;
328 params.media_flags = 0;
329 params.spellcheck_enabled = false;
330 params.is_editable = false;
331 params.page_url = web_contents->GetController().GetActiveEntry()->GetURL();
332#if defined(OS_MACOSX)
333 params.writing_direction_default = 0;
334 params.writing_direction_left_to_right = 0;
335 params.writing_direction_right_to_left = 0;
336#endif // OS_MACOSX
337 params.edit_flags = WebContextMenuData::CanTranslate;
338 return new TestRenderViewContextMenu(web_contents, params);
339 }
340
341 bool IsItemPresent(int id) {
342 return menu_model_.GetIndexOfCommandId(id) != -1;
343 }
344
345 virtual void PlatformInit() { }
346 virtual void PlatformCancel() { }
347 virtual bool GetAcceleratorForCommandId(
348 int command_id,
349 ui::Accelerator* accelerator) { return false; }
350
351 private:
352 TestRenderViewContextMenu(WebContents* web_contents,
353 const content::ContextMenuParams& params)
354 : RenderViewContextMenu(web_contents, params) {
355 }
356
357 DISALLOW_COPY_AND_ASSIGN(TestRenderViewContextMenu);
358};
359
360} // namespace
361
362TEST_F(TranslateManagerTest, NormalTranslate) {
363 // Simulate navigating to a page.
364 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
365
366 // We should have an infobar.
367 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
368 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:27369 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
370 infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:15371
372 // Simulate clicking translate.
373 process()->sink().ClearMessages();
374 infobar->Translate();
375
376 // The "Translating..." infobar should be showing.
377 infobar = GetTranslateInfoBar();
378 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:27379 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:15380
381 // Simulate the translate script being retrieved (it only needs to be done
382 // once in the test as it is cached).
383 SimulateTranslateScriptURLFetch(true);
384
385 // Test that we sent the right message to the renderer.
386 int page_id = 0;
387 std::string original_lang, target_lang;
388 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
389 EXPECT_EQ("fr", original_lang);
390 EXPECT_EQ("en", target_lang);
391
392 // Simulate the render notifying the translation has been done.
393 RenderViewHostTester::TestOnMessageReceived(
394 rvh(),
395 ChromeViewHostMsg_PageTranslated(
396 0, 0, "fr", "en", TranslateErrors::NONE));
397
398 // The after translate infobar should be showing.
399 infobar = GetTranslateInfoBar();
400 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:27401 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE, infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:15402
[email protected]9f943482012-09-21 01:05:13403 // Simulate changing the original language and translating.
[email protected]2253b3b2012-06-03 22:39:15404 process()->sink().ClearMessages();
[email protected]9f943482012-09-21 01:05:13405 std::string new_original_lang = infobar->language_code_at(0);
406 infobar->set_original_language_index(0);
407 infobar->Translate();
[email protected]2253b3b2012-06-03 22:39:15408 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
409 EXPECT_EQ(new_original_lang, original_lang);
410 EXPECT_EQ("en", target_lang);
411 // Simulate the render notifying the translation has been done.
412 RenderViewHostTester::TestOnMessageReceived(
413 rvh(),
414 ChromeViewHostMsg_PageTranslated(
415 0, 0, new_original_lang, "en", TranslateErrors::NONE));
416 // infobar is now invalid.
417 TranslateInfoBarDelegate* new_infobar = GetTranslateInfoBar();
418 ASSERT_TRUE(new_infobar != NULL);
419 infobar = new_infobar;
420
[email protected]9f943482012-09-21 01:05:13421 // Simulate changing the target language and translating.
[email protected]2253b3b2012-06-03 22:39:15422 process()->sink().ClearMessages();
[email protected]9f943482012-09-21 01:05:13423 std::string new_target_lang = infobar->language_code_at(1);
424 infobar->set_target_language_index(1);
425 infobar->Translate();
[email protected]2253b3b2012-06-03 22:39:15426 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
427 EXPECT_EQ(new_original_lang, original_lang);
428 EXPECT_EQ(new_target_lang, target_lang);
429 // Simulate the render notifying the translation has been done.
430 RenderViewHostTester::TestOnMessageReceived(
431 rvh(),
432 ChromeViewHostMsg_PageTranslated(
433 0, 0, new_original_lang, new_target_lang, TranslateErrors::NONE));
434 // infobar is now invalid.
435 new_infobar = GetTranslateInfoBar();
436 ASSERT_TRUE(new_infobar != NULL);
[email protected]f8a2e132012-08-31 18:16:20437
438 // Verify reload keeps the same settings.
439 ReloadAndWait();
440 new_infobar = GetTranslateInfoBar();
441 ASSERT_TRUE(new_infobar != NULL);
[email protected]9f943482012-09-21 01:05:13442 ASSERT_EQ(new_target_lang, infobar->target_language_code());
[email protected]2253b3b2012-06-03 22:39:15443}
444
445TEST_F(TranslateManagerTest, TranslateScriptNotAvailable) {
446 // Simulate navigating to a page.
447 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
448
449 // We should have an infobar.
450 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
451 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:27452 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
453 infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:15454
455 // Simulate clicking translate.
456 process()->sink().ClearMessages();
457 infobar->Translate();
458 // Simulate a failure retrieving the translate script.
459 SimulateTranslateScriptURLFetch(false);
460
461 // We should not have sent any message to translate to the renderer.
462 EXPECT_FALSE(GetTranslateMessage(NULL, NULL, NULL));
463
464 // And we should have an error infobar showing.
465 infobar = GetTranslateInfoBar();
466 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:27467 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
468 infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:15469}
470
471// Ensures we deal correctly with pages for which the browser does not recognize
472// the language (the translate server may or not detect the language).
473TEST_F(TranslateManagerTest, TranslateUnknownLanguage) {
474 // Simulate navigating to a page ("und" is the string returned by the CLD for
475 // languages it does not recognize).
476 SimulateNavigation(GURL("http://www.google.mys"), "und", true);
477
478 // We should not have an infobar as we don't know the language.
479 ASSERT_TRUE(GetTranslateInfoBar() == NULL);
480
481 // Translate the page anyway throught the context menu.
482 scoped_ptr<TestRenderViewContextMenu> menu(
[email protected]921441c2012-10-19 22:16:01483 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:15484 menu->Init();
485 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE);
486
487 // To test that bug #49018 if fixed, make sure we deal correctly with errors.
488 // Simulate a failure to fetch the translate script.
489 SimulateTranslateScriptURLFetch(false);
490 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
491 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:27492 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
493 infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:15494 EXPECT_TRUE(infobar->IsError());
495 infobar->MessageInfoBarButtonPressed();
496 SimulateTranslateScriptURLFetch(true); // This time succeed.
497
498 // Simulate the render notifying the translation has been done, the server
499 // having detected the page was in a known and supported language.
500 RenderViewHostTester::TestOnMessageReceived(
501 rvh(),
502 ChromeViewHostMsg_PageTranslated(
503 0, 0, "fr", "en", TranslateErrors::NONE));
504
505 // The after translate infobar should be showing.
506 infobar = GetTranslateInfoBar();
507 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:27508 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE, infobar->infobar_type());
[email protected]9f943482012-09-21 01:05:13509 EXPECT_EQ("fr", infobar->original_language_code());
510 EXPECT_EQ("en", infobar->target_language_code());
[email protected]2253b3b2012-06-03 22:39:15511
512 // Let's run the same steps but this time the server detects the page is
513 // already in English.
514 SimulateNavigation(GURL("http://www.google.com"), "und", true);
[email protected]921441c2012-10-19 22:16:01515 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:15516 menu->Init();
517 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE);
518 RenderViewHostTester::TestOnMessageReceived(
519 rvh(),
520 ChromeViewHostMsg_PageTranslated(
521 1, 0, "en", "en", TranslateErrors::IDENTICAL_LANGUAGES));
522 infobar = GetTranslateInfoBar();
523 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:27524 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
525 infobar->infobar_type());
526 EXPECT_EQ(TranslateErrors::IDENTICAL_LANGUAGES, infobar->error_type());
[email protected]2253b3b2012-06-03 22:39:15527
528 // Let's run the same steps again but this time the server fails to detect the
529 // page's language (it returns an empty string).
530 SimulateNavigation(GURL("http://www.google.com"), "und", true);
[email protected]921441c2012-10-19 22:16:01531 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:15532 menu->Init();
533 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE);
534 RenderViewHostTester::TestOnMessageReceived(
535 rvh(),
536 ChromeViewHostMsg_PageTranslated(
537 2, 0, "", "en", TranslateErrors::UNKNOWN_LANGUAGE));
538 infobar = GetTranslateInfoBar();
539 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:27540 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
541 infobar->infobar_type());
542 EXPECT_EQ(TranslateErrors::UNKNOWN_LANGUAGE, infobar->error_type());
[email protected]2253b3b2012-06-03 22:39:15543}
544
545// Tests that we show/don't show an info-bar for all languages the CLD can
546// report.
547TEST_F(TranslateManagerTest, TestAllLanguages) {
548 // The index in kExpectation are the Language enum (see languages.pb.h).
549 // true if we expect a translate infobar for that language.
550 // Note the supported languages are in translation_manager.cc, see
551 // kSupportedLanguages.
552 bool kExpectations[] = {
553 // 0-9
554 false, true, true, true, true, true, true, true, true, true,
555 // 10-19
556 true, true, true, true, true, true, true, true, true, true,
557 // 20-29
558 true, true, true, true, true, false, false, true, true, true,
559 // 30-39
560 true, true, true, true, true, true, true, false, true, false,
561 // 40-49
562 true, false, true, false, false, true, false, true, false, false,
563 // 50-59
564 true, false, false, true, true, true, false, true, false, false,
565 // 60-69
566 false, false, true, true, false, true, true, false, true, true,
567 // 70-79
568 false, false, false, false, true, true, false, true, false, false,
569 // 80-89
570 false, true, true, false, false, false, false, false, false, false,
571 // 90-99
572 false, true, false, false, false, false, false, true, false, false,
573 // 100-109
574 false, true, false, false, false, false, false, false, false, false,
575 // 110-119
576 false, false, false, false, false, false, false, false, false, false,
577 // 120-129
578 false, false, false, false, false, false, false, false, false, false,
579 // 130-139
580 false, false, false, false, false, false, false, false, false, true,
581 // 140-149
582 false, false, false, false, false, false, false, false, false, false,
583 // 150-159
584 false, false, false, false, false, false, false, false, false, false,
585 // 160
586 true
587 };
588
589 GURL url("http://www.google.com");
590 for (size_t i = 0; i < arraysize(kExpectations); ++i) {
591 ASSERT_LT(i, static_cast<size_t>(NUM_LANGUAGES));
592
593 std::string lang = LanguageCodeWithDialects(static_cast<Language>(i));
594 SCOPED_TRACE(::testing::Message() << "Iteration " << i <<
595 " language=" << lang);
596
597 // We should not have a translate infobar.
598 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
599 ASSERT_TRUE(infobar == NULL);
600
601 // Simulate navigating to a page.
602 NavigateAndCommit(url);
603 SimulateOnTranslateLanguageDetermined(lang, true);
604
605 // Verify we have/don't have an info-bar as expected.
606 infobar = GetTranslateInfoBar();
607 EXPECT_EQ(kExpectations[i], infobar != NULL);
608
609 // Close the info-bar if applicable.
610 if (infobar != NULL)
611 EXPECT_TRUE(CloseTranslateInfoBar());
612 }
613}
614
615// Test the fetching of languages from the translate server
616TEST_F(TranslateManagerTest, FetchLanguagesFromTranslateServer) {
617 std::vector<std::string> server_languages;
618 // A list of languages to fake being returned by the translate server.
619 server_languages.push_back("aa");
620 server_languages.push_back("bb");
621 server_languages.push_back("ab");
622 server_languages.push_back("en-CA");
623 server_languages.push_back("zz");
624 server_languages.push_back("yy");
625 server_languages.push_back("fr-FR");
626
627 // First, get the default languages list:
628 std::vector<std::string> default_supported_languages;
629 TranslateManager::GetSupportedLanguages(&default_supported_languages);
630 // To make sure we got the defaults and don't confuse them with the mocks.
631 ASSERT_NE(default_supported_languages.size(), server_languages.size());
632
633 Profile* profile =
[email protected]921441c2012-10-19 22:16:01634 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]2253b3b2012-06-03 22:39:15635 PrefService* prefs = profile->GetPrefs();
636 TranslateManager::GetInstance()->FetchLanguageListFromTranslateServer(prefs);
637
638 // Check that we still get the defaults until the URLFetch has completed.
639 std::vector<std::string> current_supported_languages;
640 TranslateManager::GetSupportedLanguages(&current_supported_languages);
641 EXPECT_EQ(default_supported_languages, current_supported_languages);
642
643 // Also check that it didn't change if we failed the URL fetch.
644 SimulateSupportedLanguagesURLFetch(false, std::vector<std::string>());
645 current_supported_languages.clear();
646 TranslateManager::GetSupportedLanguages(&current_supported_languages);
647 EXPECT_EQ(default_supported_languages, current_supported_languages);
648
649 // Now check that we got the appropriate set of languages from the server.
650 TranslateManager::GetInstance()->FetchLanguageListFromTranslateServer(prefs);
651 SimulateSupportedLanguagesURLFetch(true, server_languages);
652 current_supported_languages.clear();
653 TranslateManager::GetSupportedLanguages(&current_supported_languages);
654 // Not sure we need to guarantee the order of languages, so we find them.
655 EXPECT_EQ(server_languages.size(), current_supported_languages.size());
656 for (size_t i = 0; i < server_languages.size(); ++i) {
657 EXPECT_NE(current_supported_languages.end(),
658 std::find(current_supported_languages.begin(),
659 current_supported_languages.end(),
660 server_languages[i]));
661 }
662
663 // Reset to original state.
664 TranslateManager::GetInstance()->FetchLanguageListFromTranslateServer(prefs);
665 SimulateSupportedLanguagesURLFetch(true, default_supported_languages);
666}
667
668std::string GetLanguageListString(
669 const std::vector<std::string>& language_list) {
670 // The translate manager is expecting a JSON string like:
671 // sl({'sl': {'XX': 'LanguageName', ...}, 'tl': {'XX': 'LanguageName', ...}})
672 // We only need to set the tl (target languages) dictionary.
673 scoped_ptr<DictionaryValue> target_languages_dict(new DictionaryValue);
674 for (size_t i = 0; i < language_list.size(); ++i) {
675 // The value is ignored, we only use the key.
676 target_languages_dict->Set(language_list[i], Value::CreateNullValue());
677 }
678
679 DictionaryValue language_list_dict;
680 language_list_dict.Set("tl", target_languages_dict.release());
681 std::string language_list_json_str;
682 base::JSONWriter::Write(&language_list_dict, &language_list_json_str);
683 std::string language_list_str("sl(");
684 language_list_str += language_list_json_str;
685 language_list_str += ")";
686 return language_list_str;
687}
688
689// Test Language Code synonyms.
690TEST_F(TranslateManagerTest, LanguageCodeSynonyms) {
691 // The current set of synonyms are {"nb", "no"}, {"he", "iw"}, {"jw", "jv"}.
692
693 std::vector<std::string> language_list;
694 // Add some values around ht potential synonyms.
695 language_list.push_back("fr");
696 language_list.push_back("nb");
697 language_list.push_back("en");
698 TranslateManager::SetSupportedLanguages(GetLanguageListString(language_list));
699
700 EXPECT_TRUE(TranslateManager::IsSupportedLanguage("no"));
701 EXPECT_TRUE(TranslateManager::IsSupportedLanguage("nb"));
702
703 EXPECT_FALSE(TranslateManager::IsSupportedLanguage("he"));
704 EXPECT_FALSE(TranslateManager::IsSupportedLanguage("iw"));
705 EXPECT_FALSE(TranslateManager::IsSupportedLanguage("jw"));
706 EXPECT_FALSE(TranslateManager::IsSupportedLanguage("jv"));
707
708 language_list.push_back("iw");
709 TranslateManager::SetSupportedLanguages(GetLanguageListString(language_list));
710 EXPECT_TRUE(TranslateManager::IsSupportedLanguage("he"));
711 EXPECT_TRUE(TranslateManager::IsSupportedLanguage("iw"));
712
713 language_list.clear();
714 language_list.push_back("jw");
715 TranslateManager::SetSupportedLanguages(GetLanguageListString(language_list));
716 EXPECT_TRUE(TranslateManager::IsSupportedLanguage("jw"));
717 EXPECT_TRUE(TranslateManager::IsSupportedLanguage("jv"));
718
719 EXPECT_FALSE(TranslateManager::IsSupportedLanguage("no"));
720 EXPECT_FALSE(TranslateManager::IsSupportedLanguage("nb"));
721 EXPECT_FALSE(TranslateManager::IsSupportedLanguage("he"));
722 EXPECT_FALSE(TranslateManager::IsSupportedLanguage("iw"));
723}
724
725// Tests auto-translate on page.
726TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) {
727 // Simulate navigating to a page and getting its language.
728 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
729
730 // Simulate the user translating.
731 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
732 ASSERT_TRUE(infobar != NULL);
733 infobar->Translate();
734 // Simulate the translate script being retrieved.
735 SimulateTranslateScriptURLFetch(true);
736
737 RenderViewHostTester::TestOnMessageReceived(
738 rvh(),
739 ChromeViewHostMsg_PageTranslated(
740 0, 0, "fr", "en", TranslateErrors::NONE));
741
742 // Now navigate to a new page in the same language.
743 process()->sink().ClearMessages();
744 SimulateNavigation(GURL("http://news.google.fr"), "fr", true);
745
746 // This should have automatically triggered a translation.
747 int page_id = 0;
748 std::string original_lang, target_lang;
749 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
750 EXPECT_EQ(1, page_id);
751 EXPECT_EQ("fr", original_lang);
752 EXPECT_EQ("en", target_lang);
753
754 // Now navigate to a page in a different language.
755 process()->sink().ClearMessages();
756 SimulateNavigation(GURL("http://news.google.es"), "es", true);
757
758 // This should not have triggered a translate.
759 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
760}
761
762// Tests that multiple OnPageContents do not cause multiple infobars.
763TEST_F(TranslateManagerTest, MultipleOnPageContents) {
764 // Simulate navigating to a page and getting its language.
765 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
766
767 // Simulate clicking 'Nope' (don't translate).
768 EXPECT_TRUE(DenyTranslation());
[email protected]4f822f022012-12-20 19:11:42769 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
[email protected]2253b3b2012-06-03 22:39:15770
771 // Send a new PageContents, we should not show an infobar.
772 SimulateOnTranslateLanguageDetermined("fr", true);
[email protected]4f822f022012-12-20 19:11:42773 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
[email protected]2253b3b2012-06-03 22:39:15774
775 // Do the same steps but simulate closing the infobar this time.
776 SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true);
777 EXPECT_TRUE(CloseTranslateInfoBar());
[email protected]4f822f022012-12-20 19:11:42778 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
[email protected]2253b3b2012-06-03 22:39:15779 SimulateOnTranslateLanguageDetermined("fr", true);
[email protected]4f822f022012-12-20 19:11:42780 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
[email protected]2253b3b2012-06-03 22:39:15781}
782
783// Test that reloading the page brings back the infobar.
784TEST_F(TranslateManagerTest, Reload) {
785 // Simulate navigating to a page and getting its language.
786 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
787
788 // Close the infobar.
789 EXPECT_TRUE(CloseTranslateInfoBar());
790
791 // Reload should bring back the infobar.
[email protected]f8a2e132012-08-31 18:16:20792 ReloadAndWait();
[email protected]2253b3b2012-06-03 22:39:15793 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
794}
795
796// Test that reloading the page by way of typing again the URL in the
797// location bar brings back the infobar.
798TEST_F(TranslateManagerTest, ReloadFromLocationBar) {
799 GURL url("http://www.google.fr");
800
801 // Simulate navigating to a page and getting its language.
802 SimulateNavigation(url, "fr", true);
803
804 // Close the infobar.
805 EXPECT_TRUE(CloseTranslateInfoBar());
806
807 // Create a pending navigation and simulate a page load. That should be the
808 // equivalent of typing the URL again in the location bar.
[email protected]921441c2012-10-19 22:16:01809 NavEntryCommittedObserver nav_observer(web_contents());
810 web_contents()->GetController().LoadURL(url, content::Referrer(),
[email protected]2253b3b2012-06-03 22:39:15811 content::PAGE_TRANSITION_TYPED,
812 std::string());
813 rvh_tester()->SendNavigate(0, url);
814
815 // Test that we are really getting a same page navigation, the test would be
816 // useless if it was not the case.
817 const content::LoadCommittedDetails& nav_details =
818 nav_observer.get_load_commited_details();
819 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation.
820 EXPECT_EQ(content::NAVIGATION_TYPE_SAME_PAGE, nav_details.type);
821
822 // The TranslateManager class processes the navigation entry committed
823 // notification in a posted task; process that task.
[email protected]b8f50ce2012-11-17 12:37:57824 MessageLoop::current()->RunUntilIdle();
[email protected]2253b3b2012-06-03 22:39:15825 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
826}
827
828// Tests that a closed translate infobar does not reappear when navigating
829// in-page.
830TEST_F(TranslateManagerTest, CloseInfoBarInPageNavigation) {
831 // Simulate navigating to a page and getting its language.
832 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
833
834 // Close the infobar.
835 EXPECT_TRUE(CloseTranslateInfoBar());
836
837 // Navigate in page, no infobar should be shown.
838 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr",
839 true);
840 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
841
842 // Navigate out of page, a new infobar should show.
843 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true);
844 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
845}
846
847// Tests that a closed translate infobar does not reappear when navigating
848// in a subframe. (http://crbug.com/48215)
849TEST_F(TranslateManagerTest, CloseInfoBarInSubframeNavigation) {
850 // Simulate navigating to a page and getting its language.
851 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
852
853 // Close the infobar.
854 EXPECT_TRUE(CloseTranslateInfoBar());
855
856 // Simulate a sub-frame auto-navigating.
857 rvh_tester()->SendNavigateWithTransition(
858 1, GURL("http://pub.com"), content::PAGE_TRANSITION_AUTO_SUBFRAME);
859 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
860
861 // Simulate the user navigating in a sub-frame.
862 rvh_tester()->SendNavigateWithTransition(
863 2, GURL("http://pub.com"), content::PAGE_TRANSITION_MANUAL_SUBFRAME);
864 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
865
866 // Navigate out of page, a new infobar should show.
867 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true);
868 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
869}
870
[email protected]2253b3b2012-06-03 22:39:15871// Tests that denying translation is sticky when navigating in page.
872TEST_F(TranslateManagerTest, DenyTranslateInPageNavigation) {
873 // Simulate navigating to a page and getting its language.
874 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
875
876 // Simulate clicking 'Nope' (don't translate).
877 EXPECT_TRUE(DenyTranslation());
878
879 // Navigate in page, no infobar should be shown.
880 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true);
881 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
882
883 // Navigate out of page, a new infobar should show.
884 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true);
885 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
886}
887
888// Tests that after translating and closing the infobar, the infobar does not
889// return when navigating in page.
890TEST_F(TranslateManagerTest, TranslateCloseInfoBarInPageNavigation) {
891 // Simulate navigating to a page and getting its language.
892 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
893
894 // Simulate the user translating.
895 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
896 ASSERT_TRUE(infobar != NULL);
897 infobar->Translate();
898 // Simulate the translate script being retrieved.
899 SimulateTranslateScriptURLFetch(true);
900 RenderViewHostTester::TestOnMessageReceived(
901 rvh(),
902 ChromeViewHostMsg_PageTranslated(
903 0, 0, "fr", "en", TranslateErrors::NONE));
904
905 // Close the infobar.
906 EXPECT_TRUE(CloseTranslateInfoBar());
907
908 // Navigate in page, no infobar should be shown.
909 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true);
910 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
911
912 // Navigate out of page, a new infobar should show.
913 // Note that we navigate to a page in a different language so we don't trigger
914 // the auto-translate feature (it would translate the page automatically and
915 // the before translate inforbar would not be shown).
916 SimulateNavigation(GURL("http://www.google.de"), "de", true);
917 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
918}
919
920// Tests that the after translate the infobar still shows when navigating
921// in-page.
922TEST_F(TranslateManagerTest, TranslateInPageNavigation) {
923 // Simulate navigating to a page and getting its language.
924 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
925
926 // Simulate the user translating.
927 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
928 ASSERT_TRUE(infobar != NULL);
929 infobar->Translate();
930 // Simulate the translate script being retrieved.
931 SimulateTranslateScriptURLFetch(true);
932 RenderViewHostTester::TestOnMessageReceived(
933 rvh(),
934 ChromeViewHostMsg_PageTranslated(
935 0, 0, "fr", "en", TranslateErrors::NONE));
936 // The after translate infobar is showing.
937 infobar = GetTranslateInfoBar();
938 ASSERT_TRUE(infobar != NULL);
939
940 // Navigate out of page, a new infobar should show.
941 // See note in TranslateCloseInfoBarInPageNavigation test on why it is
942 // important to navigate to a page in a different language for this test.
943 SimulateNavigation(GURL("http://www.google.de"), "de", true);
944 // The old infobar is gone.
945 EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar));
946 // And there is a new one.
947 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
948}
949
950// Tests that no translate infobar is shown when navigating to a page in an
951// unsupported language.
952TEST_F(TranslateManagerTest, CLDReportsUnsupportedPageLanguage) {
953 // Simulate navigating to a page and getting an unsupported language.
954 SimulateNavigation(GURL("http://www.google.com"), "qbz", true);
955
956 // No info-bar should be shown.
957 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
958}
959
960// Tests that we deal correctly with unsupported languages returned by the
961// server.
962// The translation server might return a language we don't support.
963TEST_F(TranslateManagerTest, ServerReportsUnsupportedLanguage) {
964 // Simulate navigating to a page and translating it.
965 SimulateNavigation(GURL("http://mail.google.fr"), "fr", true);
966 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
967 ASSERT_TRUE(infobar != NULL);
968 process()->sink().ClearMessages();
969 infobar->Translate();
970 SimulateTranslateScriptURLFetch(true);
971 // Simulate the render notifying the translation has been done, but it
972 // reports a language we don't support.
973 RenderViewHostTester::TestOnMessageReceived(
974 rvh(),
975 ChromeViewHostMsg_PageTranslated(
976 0, 0, "qbz", "en", TranslateErrors::NONE));
977
978 // An error infobar should be showing to report that we don't support this
979 // language.
980 infobar = GetTranslateInfoBar();
981 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:27982 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
983 infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:15984
985 // This infobar should have a button (so the string should not be empty).
986 ASSERT_FALSE(infobar->GetMessageInfoBarButtonText().empty());
987
988 // Pressing the button on that infobar should revert to the original language.
989 process()->sink().ClearMessages();
990 infobar->MessageInfoBarButtonPressed();
991 const IPC::Message* message =
992 process()->sink().GetFirstMessageMatching(
993 ChromeViewMsg_RevertTranslation::ID);
994 EXPECT_TRUE(message != NULL);
995 // And it should have removed the infobar.
996 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
997}
998
999// Tests that no translate infobar is shown and context menu is disabled, when
1000// Chrome is in a language that the translate server does not support.
1001TEST_F(TranslateManagerTest, UnsupportedUILanguage) {
1002 std::string original_lang = g_browser_process->GetApplicationLocale();
1003 g_browser_process->SetApplicationLocale("qbz");
1004
1005 // Make sure that the accept language list only contains unsupported languages
1006 Profile* profile =
[email protected]921441c2012-10-19 22:16:011007 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]2253b3b2012-06-03 22:39:151008 PrefService* prefs = profile->GetPrefs();
1009 prefs->SetString(prefs::kAcceptLanguages, "qbz");
1010
1011 // Simulate navigating to a page in a language supported by the translate
1012 // server.
1013 SimulateNavigation(GURL("http://www.google.com"), "en", true);
1014
1015 // No info-bar should be shown.
1016 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
1017
1018 // And the context menu option should be disabled too.
1019 scoped_ptr<TestRenderViewContextMenu> menu(
[email protected]921441c2012-10-19 22:16:011020 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:151021 menu->Init();
1022 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1023 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1024
1025 g_browser_process->SetApplicationLocale(original_lang);
1026}
1027
1028// Tests that the first supported accept language is selected
1029TEST_F(TranslateManagerTest, TranslateAcceptLanguage) {
1030 // Set locate to non-existant language
1031 std::string original_lang = g_browser_process->GetApplicationLocale();
1032 g_browser_process->SetApplicationLocale("qbz");
1033
1034 // Set Qbz and French as the only accepted languages
1035 Profile* profile =
[email protected]921441c2012-10-19 22:16:011036 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]2253b3b2012-06-03 22:39:151037 PrefService* prefs = profile->GetPrefs();
1038 prefs->SetString(prefs::kAcceptLanguages, "qbz,fr");
1039
1040 // Go to a German page
1041 SimulateNavigation(GURL("http://google.de"), "de", true);
1042
1043 // Expect the infobar to pop up
1044 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1045
1046 // Set Qbz and English-US as the only accepted languages to test the country
1047 // code removal code which was causing a crash as filed in Issue 90106,
1048 // a crash caused by a language with a country code that wasn't recognized.
1049 prefs->SetString(prefs::kAcceptLanguages, "qbz,en-us");
1050
1051 // Go to a German page
1052 SimulateNavigation(GURL("http://google.de"), "de", true);
1053
1054 // Expect the infobar to pop up
1055 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1056}
1057
1058// Tests that the translate enabled preference is honored.
1059TEST_F(TranslateManagerTest, TranslateEnabledPref) {
1060 // Make sure the pref allows translate.
1061 Profile* profile =
[email protected]921441c2012-10-19 22:16:011062 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]2253b3b2012-06-03 22:39:151063 PrefService* prefs = profile->GetPrefs();
1064 prefs->SetBoolean(prefs::kEnableTranslate, true);
1065
1066 // Simulate navigating to a page and getting its language.
1067 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1068
1069 // An infobar should be shown.
1070 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
1071 EXPECT_TRUE(infobar != NULL);
1072
1073 // Disable translate.
1074 prefs->SetBoolean(prefs::kEnableTranslate, false);
1075
1076 // Navigate to a new page, that should close the previous infobar.
1077 GURL url("http://www.youtube.fr");
1078 NavigateAndCommit(url);
1079 infobar = GetTranslateInfoBar();
1080 EXPECT_TRUE(infobar == NULL);
1081
1082 // Simulate getting the page contents and language, that should not trigger
1083 // a translate infobar.
1084 SimulateOnTranslateLanguageDetermined("fr", true);
1085 infobar = GetTranslateInfoBar();
1086 EXPECT_TRUE(infobar == NULL);
1087}
1088
1089// Tests the "Never translate <language>" pref.
1090TEST_F(TranslateManagerTest, NeverTranslateLanguagePref) {
1091 // Simulate navigating to a page and getting its language.
1092 GURL url("http://www.google.fr");
1093 SimulateNavigation(url, "fr", true);
1094
1095 // An infobar should be shown.
1096 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1097
1098 // Select never translate this language.
1099 Profile* profile =
[email protected]921441c2012-10-19 22:16:011100 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]2253b3b2012-06-03 22:39:151101 PrefService* prefs = profile->GetPrefs();
1102 PrefChangeRegistrar registrar;
1103 registrar.Init(prefs);
[email protected]116129e02012-11-21 17:26:271104 registrar.Add(TranslatePrefs::kPrefTranslateLanguageBlacklist,
1105 pref_callback_);
[email protected]2253b3b2012-06-03 22:39:151106 TranslatePrefs translate_prefs(prefs);
1107 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr"));
1108 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url));
1109 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateLanguageBlacklist);
1110 translate_prefs.BlacklistLanguage("fr");
1111 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("fr"));
1112 EXPECT_FALSE(translate_prefs.CanTranslate(prefs, "fr", url));
1113
1114 // Close the infobar.
1115 EXPECT_TRUE(CloseTranslateInfoBar());
1116
1117 // Navigate to a new page also in French.
1118 SimulateNavigation(GURL("http://wwww.youtube.fr"), "fr", true);
1119
1120 // There should not be a translate infobar.
1121 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
1122
1123 // Remove the language from the blacklist.
1124 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateLanguageBlacklist);
1125 translate_prefs.RemoveLanguageFromBlacklist("fr");
1126 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr"));
1127 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url));
1128
1129 // Navigate to a page in French.
1130 SimulateNavigation(url, "fr", true);
1131
1132 // There should be a translate infobar.
1133 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1134}
1135
1136// Tests the "Never translate this site" pref.
1137TEST_F(TranslateManagerTest, NeverTranslateSitePref) {
1138 // Simulate navigating to a page and getting its language.
1139 GURL url("http://www.google.fr");
1140 std::string host(url.host());
1141 SimulateNavigation(url, "fr", true);
1142
1143 // An infobar should be shown.
1144 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1145
1146 // Select never translate this site.
1147 Profile* profile =
[email protected]921441c2012-10-19 22:16:011148 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]2253b3b2012-06-03 22:39:151149 PrefService* prefs = profile->GetPrefs();
1150 PrefChangeRegistrar registrar;
1151 registrar.Init(prefs);
[email protected]116129e02012-11-21 17:26:271152 registrar.Add(TranslatePrefs::kPrefTranslateSiteBlacklist, pref_callback_);
[email protected]2253b3b2012-06-03 22:39:151153 TranslatePrefs translate_prefs(prefs);
1154 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(host));
1155 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url));
1156 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist);
1157 translate_prefs.BlacklistSite(host);
1158 EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(host));
1159 EXPECT_FALSE(translate_prefs.CanTranslate(prefs, "fr", url));
1160
1161 // Close the infobar.
1162 EXPECT_TRUE(CloseTranslateInfoBar());
1163
1164 // Navigate to a new page also on the same site.
1165 SimulateNavigation(GURL("http://www.google.fr/hello"), "fr", true);
1166
1167 // There should not be a translate infobar.
1168 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
1169
1170 // Remove the site from the blacklist.
1171 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist);
1172 translate_prefs.RemoveSiteFromBlacklist(host);
1173 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(host));
1174 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url));
1175
1176 // Navigate to a page in French.
1177 SimulateNavigation(url, "fr", true);
1178
1179 // There should be a translate infobar.
1180 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1181}
1182
1183// Tests the "Always translate this language" pref.
1184TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) {
1185 // Select always translate French to English.
1186 Profile* profile =
[email protected]921441c2012-10-19 22:16:011187 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]2253b3b2012-06-03 22:39:151188 PrefService* prefs = profile->GetPrefs();
1189 PrefChangeRegistrar registrar;
1190 registrar.Init(prefs);
[email protected]116129e02012-11-21 17:26:271191 registrar.Add(TranslatePrefs::kPrefTranslateWhitelists, pref_callback_);
[email protected]2253b3b2012-06-03 22:39:151192 TranslatePrefs translate_prefs(prefs);
1193 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists);
1194 translate_prefs.WhitelistLanguagePair("fr", "en");
1195
1196 // Load a page in French.
1197 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1198
1199 // It should have triggered an automatic translation to English.
1200
1201 // The translating infobar should be showing.
1202 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
1203 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:271204 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:151205 // Simulate the translate script being retrieved.
1206 SimulateTranslateScriptURLFetch(true);
1207 int page_id = 0;
1208 std::string original_lang, target_lang;
1209 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1210 EXPECT_EQ("fr", original_lang);
1211 EXPECT_EQ("en", target_lang);
1212 process()->sink().ClearMessages();
1213
1214 // Try another language, it should not be autotranslated.
1215 SimulateNavigation(GURL("http://www.google.es"), "es", true);
1216 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1217 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1218 EXPECT_TRUE(CloseTranslateInfoBar());
1219
1220 // Let's switch to incognito mode, it should not be autotranslated in that
1221 // case either.
1222 TestingProfile* test_profile =
[email protected]921441c2012-10-19 22:16:011223 static_cast<TestingProfile*>(web_contents()->GetBrowserContext());
[email protected]2253b3b2012-06-03 22:39:151224 test_profile->set_incognito(true);
1225 SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true);
1226 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1227 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1228 EXPECT_TRUE(CloseTranslateInfoBar());
1229 test_profile->set_incognito(false); // Get back to non incognito.
1230
1231 // Now revert the always translate pref and make sure we go back to expected
1232 // behavior, which is show a "before translate" infobar.
1233 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists);
1234 translate_prefs.RemoveLanguagePairFromWhitelist("fr", "en");
1235 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1236 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1237 infobar = GetTranslateInfoBar();
1238 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:271239 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
1240 infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:151241}
1242
1243// Context menu.
1244TEST_F(TranslateManagerTest, ContextMenu) {
1245 // Blacklist www.google.fr and French for translation.
1246 GURL url("http://www.google.fr");
1247 Profile* profile =
[email protected]921441c2012-10-19 22:16:011248 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]2253b3b2012-06-03 22:39:151249 TranslatePrefs translate_prefs(profile->GetPrefs());
1250 translate_prefs.BlacklistLanguage("fr");
1251 translate_prefs.BlacklistSite(url.host());
1252 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("fr"));
1253 EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(url.host()));
1254
1255 // Simulate navigating to a page in French. The translate menu should show but
1256 // should only be enabled when the page language has been received.
1257 NavigateAndCommit(url);
1258 scoped_ptr<TestRenderViewContextMenu> menu(
[email protected]921441c2012-10-19 22:16:011259 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:151260 menu->Init();
1261 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1262 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1263
1264 // Simulate receiving the language.
1265 SimulateOnTranslateLanguageDetermined("fr", true);
[email protected]921441c2012-10-19 22:16:011266 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:151267 menu->Init();
1268 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1269 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1270
1271 // Use the menu to translate the page.
1272 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE);
1273
1274 // That should have triggered a translation.
1275 // The "translating..." infobar should be showing.
1276 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
1277 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:271278 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:151279 // Simulate the translate script being retrieved.
1280 SimulateTranslateScriptURLFetch(true);
1281 int page_id = 0;
1282 std::string original_lang, target_lang;
1283 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1284 EXPECT_EQ("fr", original_lang);
1285 EXPECT_EQ("en", target_lang);
1286 process()->sink().ClearMessages();
1287
1288 // This should also have reverted the blacklisting of this site and language.
1289 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr"));
1290 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(url.host()));
1291
1292 // Let's simulate the page being translated.
1293 RenderViewHostTester::TestOnMessageReceived(
1294 rvh(),
1295 ChromeViewHostMsg_PageTranslated(
1296 0, 0, "fr", "en", TranslateErrors::NONE));
1297
1298 // The translate menu should now be disabled.
[email protected]921441c2012-10-19 22:16:011299 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:151300 menu->Init();
1301 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1302 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1303
1304 // Test that selecting translate in the context menu WHILE the page is being
1305 // translated does nothing (this could happen if autotranslate kicks-in and
1306 // the user selects the menu while the translation is being performed).
1307 SimulateNavigation(GURL("http://www.google.es"), "es", true);
1308 infobar = GetTranslateInfoBar();
1309 ASSERT_TRUE(infobar != NULL);
1310 infobar->Translate();
1311 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1312 process()->sink().ClearMessages();
[email protected]921441c2012-10-19 22:16:011313 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:151314 menu->Init();
1315 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1316 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE);
1317 // No message expected since the translation should have been ignored.
1318 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1319
1320 // Now test that selecting translate in the context menu AFTER the page has
1321 // been translated does nothing.
1322 SimulateNavigation(GURL("http://www.google.de"), "de", true);
1323 infobar = GetTranslateInfoBar();
1324 ASSERT_TRUE(infobar != NULL);
1325 infobar->Translate();
1326 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1327 process()->sink().ClearMessages();
[email protected]921441c2012-10-19 22:16:011328 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:151329 menu->Init();
1330 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1331 RenderViewHostTester::TestOnMessageReceived(
1332 rvh(),
1333 ChromeViewHostMsg_PageTranslated(
1334 0, 0, "de", "en", TranslateErrors::NONE));
1335 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE);
1336 // No message expected since the translation should have been ignored.
1337 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1338
1339 // Test that the translate context menu is enabled when the page is in an
1340 // unknown language.
1341 SimulateNavigation(url, "und", true);
[email protected]921441c2012-10-19 22:16:011342 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:151343 menu->Init();
1344 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1345 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1346
1347 // Test that the translate context menu is disabled when the page is in an
1348 // unsupported language.
1349 SimulateNavigation(url, "qbz", true);
[email protected]921441c2012-10-19 22:16:011350 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:151351 menu->Init();
1352 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1353 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1354}
1355
1356// Tests that an extra always/never translate button is shown on the "before
1357// translate" infobar when the translation is accepted/declined 3 times,
1358// only when not in incognito mode.
1359TEST_F(TranslateManagerTest, BeforeTranslateExtraButtons) {
1360 Profile* profile =
[email protected]921441c2012-10-19 22:16:011361 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
[email protected]2253b3b2012-06-03 22:39:151362 TranslatePrefs translate_prefs(profile->GetPrefs());
1363 translate_prefs.ResetTranslationAcceptedCount("fr");
1364 translate_prefs.ResetTranslationDeniedCount("fr");
1365 translate_prefs.ResetTranslationAcceptedCount("de");
1366 translate_prefs.ResetTranslationDeniedCount("de");
1367
1368 // We'll do 4 times in incognito mode first to make sure the button is not
1369 // shown in that case, then 4 times in normal mode.
1370 TranslateInfoBarDelegate* infobar;
1371 TestingProfile* test_profile =
[email protected]921441c2012-10-19 22:16:011372 static_cast<TestingProfile*>(web_contents()->GetBrowserContext());
[email protected]bd306722012-07-11 20:43:591373 static_cast<extensions::TestExtensionSystem*>(
1374 extensions::ExtensionSystem::Get(test_profile))->
[email protected]2253b3b2012-06-03 22:39:151375 CreateExtensionProcessManager();
1376 test_profile->set_incognito(true);
1377 for (int i = 0; i < 8; ++i) {
1378 SCOPED_TRACE(::testing::Message() << "Iteration " << i <<
1379 " incognito mode=" << test_profile->IsOffTheRecord());
1380 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1381 infobar = GetTranslateInfoBar();
1382 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:271383 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
1384 infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:151385 if (i < 7) {
1386 EXPECT_FALSE(infobar->ShouldShowAlwaysTranslateButton());
1387 infobar->Translate();
1388 process()->sink().ClearMessages();
1389 } else {
1390 EXPECT_TRUE(infobar->ShouldShowAlwaysTranslateButton());
1391 }
1392 if (i == 3)
1393 test_profile->set_incognito(false);
1394 }
1395 // Simulate the user pressing "Always translate French".
1396 infobar->AlwaysTranslatePageLanguage();
1397 EXPECT_TRUE(translate_prefs.IsLanguagePairWhitelisted("fr", "en"));
1398 // Simulate the translate script being retrieved (it only needs to be done
1399 // once in the test as it is cached).
1400 SimulateTranslateScriptURLFetch(true);
1401 // That should have triggered a page translate.
1402 int page_id = 0;
1403 std::string original_lang, target_lang;
1404 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1405 process()->sink().ClearMessages();
1406
1407 // Now test that declining the translation causes a "never translate" button
1408 // to be shown (in non incognito mode only).
1409 test_profile->set_incognito(true);
1410 for (int i = 0; i < 8; ++i) {
1411 SCOPED_TRACE(::testing::Message() << "Iteration " << i <<
1412 " incognito mode=" << test_profile->IsOffTheRecord());
1413 SimulateNavigation(GURL("http://www.google.de"), "de", true);
1414 infobar = GetTranslateInfoBar();
1415 ASSERT_TRUE(infobar != NULL);
[email protected]2ebd22d2013-01-07 17:04:271416 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
1417 infobar->infobar_type());
[email protected]2253b3b2012-06-03 22:39:151418 if (i < 7) {
1419 EXPECT_FALSE(infobar->ShouldShowNeverTranslateButton());
1420 infobar->TranslationDeclined();
1421 } else {
1422 EXPECT_TRUE(infobar->ShouldShowNeverTranslateButton());
1423 }
1424 if (i == 3)
1425 test_profile->set_incognito(false);
1426 }
1427 // Simulate the user pressing "Never translate French".
1428 infobar->NeverTranslatePageLanguage();
1429 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("de"));
1430 // No translation should have occured and the infobar should be gone.
1431 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1432 process()->sink().ClearMessages();
1433 ASSERT_TRUE(GetTranslateInfoBar() == NULL);
1434}
1435
1436// Tests that we don't show a translate infobar when a page instructs that it
1437// should not be translated.
1438TEST_F(TranslateManagerTest, NonTranslatablePage) {
1439 // Simulate navigating to a page.
1440 SimulateNavigation(GURL("http://mail.google.fr"), "fr", false);
1441
1442 // We should not have an infobar.
1443 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
1444
1445 // The context menu should be disabled.
1446 scoped_ptr<TestRenderViewContextMenu> menu(
[email protected]921441c2012-10-19 22:16:011447 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
[email protected]2253b3b2012-06-03 22:39:151448 menu->Init();
1449 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1450 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1451}
1452
1453// Tests that the script is expired and refetched as expected.
1454TEST_F(TranslateManagerTest, ScriptExpires) {
1455 ExpireTranslateScriptImmediately();
1456
1457 // Simulate navigating to a page and translating it.
1458 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1459 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
1460 ASSERT_TRUE(infobar != NULL);
1461 process()->sink().ClearMessages();
1462 infobar->Translate();
1463 SimulateTranslateScriptURLFetch(true);
1464 RenderViewHostTester::TestOnMessageReceived(
1465 rvh(),
1466 ChromeViewHostMsg_PageTranslated(
1467 0, 0, "fr", "en", TranslateErrors::NONE));
1468
1469 // A task should have been posted to clear the script, run it.
[email protected]b8f50ce2012-11-17 12:37:571470 MessageLoop::current()->RunUntilIdle();
[email protected]2253b3b2012-06-03 22:39:151471
1472 // Do another navigation and translation.
1473 SimulateNavigation(GURL("http://www.google.es"), "es", true);
1474 infobar = GetTranslateInfoBar();
1475 ASSERT_TRUE(infobar != NULL);
1476 process()->sink().ClearMessages();
1477 infobar->Translate();
1478 // If we don't simulate the URL fetch, the TranslateManager should be waiting
1479 // for the script and no message should have been sent to the renderer.
1480 EXPECT_TRUE(
1481 process()->sink().GetFirstMessageMatching(
1482 ChromeViewMsg_TranslatePage::ID) ==
1483 NULL);
1484 // Now simulate the URL fetch.
1485 SimulateTranslateScriptURLFetch(true);
1486 // Now the message should have been sent.
1487 int page_id = 0;
1488 std::string original_lang, target_lang;
1489 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1490 EXPECT_EQ("es", original_lang);
1491 EXPECT_EQ("en", target_lang);
1492}
[email protected]f8a2e132012-08-31 18:16:201493
1494TEST_F(TranslateManagerTest, DownloadsAndHistoryNotTranslated) {
1495 ASSERT_FALSE(TranslateManager::IsTranslatableURL(
1496 GURL(chrome::kChromeUIDownloadsURL)));
1497 ASSERT_FALSE(TranslateManager::IsTranslatableURL(
1498 GURL(chrome::kChromeUIHistoryURL)));
1499}
1500
[email protected]373b4612012-12-15 23:26:411501// Test is flaky on Win http://crbug.com/166334
1502#if defined(OS_WIN)
1503#define MAYBE_PRE_TranslateSessionRestore DISABLED_PRE_TranslateSessionRestore
1504#else
1505#define MAYBE_PRE_TranslateSessionRestore PRE_TranslateSessionRestore
1506#endif
[email protected]f8a2e132012-08-31 18:16:201507// Test that session restore restores the translate infobar and other translate
1508// settings.
[email protected]373b4612012-12-15 23:26:411509IN_PROC_BROWSER_TEST_F(InProcessBrowserTest,
1510 MAYBE_PRE_TranslateSessionRestore) {
[email protected]f8a2e132012-08-31 18:16:201511 SessionStartupPref pref(SessionStartupPref::LAST);
1512 SessionStartupPref::SetStartupPref(browser()->profile(), pref);
1513
1514 WebContents* current_web_contents = chrome::GetActiveWebContents(browser());
[email protected]f0235f62012-09-28 16:50:571515 TranslateTabHelper* translate_tab_helper =
1516 TranslateTabHelper::FromWebContents(current_web_contents);
[email protected]f8a2e132012-08-31 18:16:201517 content::Source<WebContents> source(current_web_contents);
1518
1519 ui_test_utils::WindowedNotificationObserverWithDetails<std::string>
1520 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED,
1521 source);
1522
1523 GURL french_url = ui_test_utils::GetTestUrl(
1524 FilePath(), FilePath(FILE_PATH_LITERAL("french_page.html")));
1525 ui_test_utils::NavigateToURL(browser(), french_url);
1526 fr_language_detected_signal.Wait();
1527 std::string lang;
1528 EXPECT_TRUE(fr_language_detected_signal.GetDetailsFor(
1529 source.map_key(), &lang));
1530 EXPECT_EQ("fr", lang);
[email protected]f0235f62012-09-28 16:50:571531 EXPECT_EQ("fr", translate_tab_helper->language_state().original_language());
[email protected]f8a2e132012-08-31 18:16:201532}
1533
[email protected]373b4612012-12-15 23:26:411534#if defined (OS_WIN)
1535#define MAYBE_TranslateSessionRestore DISABLED_TranslateSessionRestore
1536#else
1537#define MAYBE_TranslateSessionRestore TranslateSessionRestore
1538#endif
1539IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, MAYBE_TranslateSessionRestore) {
[email protected]f8a2e132012-08-31 18:16:201540 WebContents* current_web_contents = chrome::GetActiveWebContents(browser());
1541 content::Source<WebContents> source(current_web_contents);
1542
1543 ui_test_utils::WindowedNotificationObserverWithDetails<std::string>
1544 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED,
1545 source);
1546 fr_language_detected_signal.Wait();
1547}