Fix build break
[chromium-blink-merge.git] / chrome / browser / translate / translate_manager_browsertest.cc
blob07403258de0c20e3802a00043696318d7a8ac561
1 // 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.
6 #include <algorithm>
7 #include <set>
8 #include <vector>
10 #include "base/json/json_writer.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/prefs/pref_change_registrar.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/stringprintf.h"
15 #include "base/utf_string_conversions.h"
16 #include "base/values.h"
17 #include "chrome/app/chrome_command_ids.h"
18 #include "chrome/browser/extensions/test_extension_system.h"
19 #include "chrome/browser/infobars/infobar.h"
20 #include "chrome/browser/infobars/infobar_service.h"
21 #include "chrome/browser/prefs/session_startup_pref.h"
22 #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"
26 #include "chrome/browser/translate/translate_tab_helper.h"
27 #include "chrome/browser/ui/browser.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
29 #include "chrome/common/chrome_notification_types.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/common/render_messages.h"
32 #include "chrome/common/url_constants.h"
33 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
34 #include "chrome/test/base/in_process_browser_test.h"
35 #include "chrome/test/base/testing_browser_process.h"
36 #include "chrome/test/base/testing_profile.h"
37 #include "chrome/test/base/ui_test_utils.h"
38 #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"
45 #include "content/public/test/render_view_test.h"
46 #include "content/public/test/test_browser_thread.h"
47 #include "content/public/test/test_renderer_host.h"
48 #include "grit/generated_resources.h"
49 #include "ipc/ipc_test_sink.h"
50 #include "net/url_request/test_url_fetcher_factory.h"
51 #include "testing/gmock/include/gmock/gmock.h"
52 #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
53 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
54 #include "third_party/cld/languages/public/languages.h"
56 using content::BrowserThread;
57 using content::NavigationController;
58 using content::RenderViewHostTester;
59 using content::WebContents;
60 using testing::_;
61 using testing::Pointee;
62 using testing::Property;
63 using WebKit::WebContextMenuData;
65 // An observer that keeps track of whether a navigation entry was committed.
66 class 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()));
74 virtual void Observe(int type,
75 const content::NotificationSource& source,
76 const content::NotificationDetails& details) OVERRIDE {
77 DCHECK(type == content::NOTIFICATION_NAV_ENTRY_COMMITTED);
78 details_ =
79 *(content::Details<content::LoadCommittedDetails>(details).ptr());
82 const content::LoadCommittedDetails&
83 get_load_commited_details() const {
84 return details_;
87 private:
88 content::LoadCommittedDetails details_;
89 content::NotificationRegistrar registrar_;
91 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver);
94 class TranslateManagerBrowserTest : public ChromeRenderViewHostTestHarness,
95 public content::NotificationObserver {
96 public:
97 TranslateManagerBrowserTest()
98 : pref_callback_(
99 base::Bind(&TranslateManagerBrowserTest::OnPreferenceChanged,
100 base::Unretained(this))),
101 ui_thread_(BrowserThread::UI, &message_loop_) {
104 // Simulates navigating to a page and getting the page contents and language
105 // for that navigation.
106 void SimulateNavigation(const GURL& url,
107 const std::string& lang,
108 bool page_translatable) {
109 NavigateAndCommit(url);
110 SimulateOnTranslateLanguageDetermined(lang, page_translatable);
113 void SimulateOnTranslateLanguageDetermined(const std::string& lang,
114 bool page_translatable) {
115 RenderViewHostTester::TestOnMessageReceived(
116 rvh(),
117 ChromeViewHostMsg_TranslateLanguageDetermined(
118 0, lang, page_translatable));
121 bool GetTranslateMessage(int* page_id,
122 std::string* original_lang,
123 std::string* target_lang) {
124 const IPC::Message* message =
125 process()->sink().GetFirstMessageMatching(
126 ChromeViewMsg_TranslatePage::ID);
127 if (!message)
128 return false;
129 Tuple4<int, std::string, std::string, std::string> translate_param;
130 ChromeViewMsg_TranslatePage::Read(message, &translate_param);
131 if (page_id)
132 *page_id = translate_param.a;
133 // Ignore translate_param.b which is the script injected in the page.
134 if (original_lang)
135 *original_lang = translate_param.c;
136 if (target_lang)
137 *target_lang = translate_param.d;
138 return true;
141 InfoBarService* infobar_service() {
142 return InfoBarService::FromWebContents(web_contents());
145 // Returns the translate infobar if there is 1 infobar and it is a translate
146 // infobar.
147 TranslateInfoBarDelegate* GetTranslateInfoBar() {
148 return (infobar_service()->GetInfoBarCount() == 1) ?
149 infobar_service()->GetInfoBarDelegateAt(0)->
150 AsTranslateInfoBarDelegate() : NULL;
153 // If there is 1 infobar and it is a translate infobar, closes it and returns
154 // true. Returns false otherwise.
155 bool CloseTranslateInfoBar() {
156 InfoBarDelegate* infobar = GetTranslateInfoBar();
157 if (!infobar)
158 return false;
159 infobar->InfoBarDismissed(); // Simulates closing the infobar.
160 infobar_service()->RemoveInfoBar(infobar);
161 return true;
164 // Checks whether |infobar| has been removed and clears the removed infobar
165 // list.
166 bool CheckInfoBarRemovedAndReset(InfoBarDelegate* delegate) {
167 bool found = removed_infobars_.count(delegate) != 0;
168 removed_infobars_.clear();
169 return found;
172 // Returns true if at least one infobar was closed.
173 bool InfoBarRemoved() {
174 return !removed_infobars_.empty();
177 // Clears the list of stored removed infobars.
178 void ClearRemovedInfoBars() {
179 removed_infobars_.clear();
182 void ExpireTranslateScriptImmediately() {
183 TranslateManager::GetInstance()->set_translate_script_expiration_delay(0);
186 // If there is 1 infobar and it is a translate infobar, deny translation and
187 // returns true. Returns false otherwise.
188 bool DenyTranslation() {
189 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
190 if (!infobar)
191 return false;
192 infobar->TranslationDeclined();
193 infobar_service()->RemoveInfoBar(infobar);
194 return true;
197 void ReloadAndWait(bool successful_reload) {
198 NavEntryCommittedObserver nav_observer(web_contents());
199 if (successful_reload)
200 Reload();
201 else
202 FailedReload();
204 // Ensures it is really handled a reload.
205 const content::LoadCommittedDetails& nav_details =
206 nav_observer.get_load_commited_details();
207 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation.
208 EXPECT_EQ(content::NAVIGATION_TYPE_EXISTING_PAGE, nav_details.type);
210 // The TranslateManager class processes the navigation entry committed
211 // notification in a posted task; process that task.
212 MessageLoop::current()->RunUntilIdle();
215 virtual void Observe(int type,
216 const content::NotificationSource& source,
217 const content::NotificationDetails& details) {
218 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
219 removed_infobars_.insert(
220 content::Details<InfoBarRemovedDetails>(details)->first);
223 MOCK_METHOD1(OnPreferenceChanged, void(const std::string&));
225 protected:
226 virtual void SetUp() {
227 WebKit::initialize(webkit_platform_support_.Get());
228 // Access the TranslateManager singleton so it is created before we call
229 // ChromeRenderViewHostTestHarness::SetUp() to match what's done in Chrome,
230 // where the TranslateManager is created before the WebContents. This
231 // matters as they both register for similar events and we want the
232 // notifications to happen in the same sequence (TranslateManager first,
233 // WebContents second). Also clears the translate script so it is fetched
234 // everytime and sets the expiration delay to a large value by default (in
235 // case it was zeroed in a previous test).
236 TranslateManager::GetInstance()->ClearTranslateScript();
237 TranslateManager::GetInstance()->
238 set_translate_script_expiration_delay(60 * 60 * 1000);
240 ChromeRenderViewHostTestHarness::SetUp();
241 InfoBarService::CreateForWebContents(web_contents());
242 TranslateTabHelper::CreateForWebContents(web_contents());
244 notification_registrar_.Add(this,
245 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
246 content::Source<InfoBarService>(infobar_service()));
249 virtual void TearDown() {
250 process()->sink().ClearMessages();
252 notification_registrar_.Remove(this,
253 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
254 content::Source<InfoBarService>(infobar_service()));
256 ChromeRenderViewHostTestHarness::TearDown();
257 WebKit::shutdown();
260 void SimulateTranslateScriptURLFetch(bool success) {
261 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
262 ASSERT_TRUE(fetcher);
263 net::URLRequestStatus status;
264 status.set_status(success ? net::URLRequestStatus::SUCCESS :
265 net::URLRequestStatus::FAILED);
266 fetcher->set_url(fetcher->GetOriginalURL());
267 fetcher->set_status(status);
268 fetcher->set_response_code(success ? 200 : 500);
269 fetcher->delegate()->OnURLFetchComplete(fetcher);
272 void SimulateSupportedLanguagesURLFetch(
273 bool success, const std::vector<std::string>& languages) {
274 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(1);
275 ASSERT_TRUE(fetcher);
276 net::URLRequestStatus status;
277 status.set_status(success ? net::URLRequestStatus::SUCCESS :
278 net::URLRequestStatus::FAILED);
280 std::string data;
281 if (success) {
282 data = base::StringPrintf("%s{\"sl\": {\"bla\": \"bla\"}, \"%s\": {",
283 TranslateManager::kLanguageListCallbackName,
284 TranslateManager::kTargetLanguagesKey);
285 const char* comma = "";
286 for (size_t i = 0; i < languages.size(); ++i) {
287 data += base::StringPrintf(
288 "%s\"%s\": \"UnusedFullName\"", comma, languages[i].c_str());
289 if (i == 0)
290 comma = ",";
292 data += "}})";
294 fetcher->set_url(fetcher->GetOriginalURL());
295 fetcher->set_status(status);
296 fetcher->set_response_code(success ? 200 : 500);
297 fetcher->SetResponseString(data);
298 fetcher->delegate()->OnURLFetchComplete(fetcher);
301 void SetPrefObserverExpectation(const char* path) {
302 EXPECT_CALL(*this, OnPreferenceChanged(std::string(path)));
305 PrefChangeRegistrar::NamedChangeCallback pref_callback_;
307 private:
308 content::NotificationRegistrar notification_registrar_;
309 net::TestURLFetcherFactory url_fetcher_factory_;
310 content::TestBrowserThread ui_thread_;
311 content::RenderViewTest::RendererWebKitPlatformSupportImplNoSandbox
312 webkit_platform_support_;
314 // The infobars that have been removed.
315 // WARNING: the pointers point to deleted objects, use only for comparison.
316 std::set<InfoBarDelegate*> removed_infobars_;
318 DISALLOW_COPY_AND_ASSIGN(TranslateManagerBrowserTest);
321 namespace {
323 class TestRenderViewContextMenu : public RenderViewContextMenu {
324 public:
325 static TestRenderViewContextMenu* CreateContextMenu(
326 WebContents* web_contents) {
327 content::ContextMenuParams params;
328 params.media_type = WebKit::WebContextMenuData::MediaTypeNone;
329 params.x = 0;
330 params.y = 0;
331 params.is_image_blocked = false;
332 params.media_flags = 0;
333 params.spellcheck_enabled = false;
334 params.is_editable = false;
335 params.page_url = web_contents->GetController().GetActiveEntry()->GetURL();
336 #if defined(OS_MACOSX)
337 params.writing_direction_default = 0;
338 params.writing_direction_left_to_right = 0;
339 params.writing_direction_right_to_left = 0;
340 #endif // OS_MACOSX
341 params.edit_flags = WebContextMenuData::CanTranslate;
342 return new TestRenderViewContextMenu(web_contents, params);
345 bool IsItemPresent(int id) {
346 return menu_model_.GetIndexOfCommandId(id) != -1;
349 virtual void PlatformInit() OVERRIDE { }
350 virtual void PlatformCancel() OVERRIDE { }
351 virtual bool GetAcceleratorForCommandId(
352 int command_id,
353 ui::Accelerator* accelerator) OVERRIDE { return false; }
355 private:
356 TestRenderViewContextMenu(WebContents* web_contents,
357 const content::ContextMenuParams& params)
358 : RenderViewContextMenu(web_contents, params) {
361 DISALLOW_COPY_AND_ASSIGN(TestRenderViewContextMenu);
364 } // namespace
366 TEST_F(TranslateManagerBrowserTest, NormalTranslate) {
367 // Simulate navigating to a page.
368 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
370 // We should have an infobar.
371 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
372 ASSERT_TRUE(infobar != NULL);
373 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
374 infobar->infobar_type());
376 // Simulate clicking translate.
377 process()->sink().ClearMessages();
378 infobar->Translate();
380 // The "Translating..." infobar should be showing.
381 infobar = GetTranslateInfoBar();
382 ASSERT_TRUE(infobar != NULL);
383 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->infobar_type());
385 // Simulate the translate script being retrieved (it only needs to be done
386 // once in the test as it is cached).
387 SimulateTranslateScriptURLFetch(true);
389 // Test that we sent the right message to the renderer.
390 int page_id = 0;
391 std::string original_lang, target_lang;
392 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
393 EXPECT_EQ("fr", original_lang);
394 EXPECT_EQ("en", target_lang);
396 // Simulate the render notifying the translation has been done.
397 RenderViewHostTester::TestOnMessageReceived(
398 rvh(),
399 ChromeViewHostMsg_PageTranslated(
400 0, 0, "fr", "en", TranslateErrors::NONE));
402 // The after translate infobar should be showing.
403 infobar = GetTranslateInfoBar();
404 ASSERT_TRUE(infobar != NULL);
405 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE, infobar->infobar_type());
407 // Simulate changing the original language and translating.
408 process()->sink().ClearMessages();
409 std::string new_original_lang = infobar->language_code_at(0);
410 infobar->set_original_language_index(0);
411 infobar->Translate();
412 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
413 EXPECT_EQ(new_original_lang, original_lang);
414 EXPECT_EQ("en", target_lang);
415 // Simulate the render notifying the translation has been done.
416 RenderViewHostTester::TestOnMessageReceived(
417 rvh(),
418 ChromeViewHostMsg_PageTranslated(
419 0, 0, new_original_lang, "en", TranslateErrors::NONE));
420 // infobar is now invalid.
421 TranslateInfoBarDelegate* new_infobar = GetTranslateInfoBar();
422 ASSERT_TRUE(new_infobar != NULL);
423 infobar = new_infobar;
425 // Simulate changing the target language and translating.
426 process()->sink().ClearMessages();
427 std::string new_target_lang = infobar->language_code_at(1);
428 infobar->set_target_language_index(1);
429 infobar->Translate();
430 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
431 EXPECT_EQ(new_original_lang, original_lang);
432 EXPECT_EQ(new_target_lang, target_lang);
433 // Simulate the render notifying the translation has been done.
434 RenderViewHostTester::TestOnMessageReceived(
435 rvh(),
436 ChromeViewHostMsg_PageTranslated(
437 0, 0, new_original_lang, new_target_lang, TranslateErrors::NONE));
438 // infobar is now invalid.
439 new_infobar = GetTranslateInfoBar();
440 ASSERT_TRUE(new_infobar != NULL);
442 // Verify reload keeps the same settings.
443 ReloadAndWait(true);
444 new_infobar = GetTranslateInfoBar();
445 ASSERT_TRUE(new_infobar != NULL);
446 ASSERT_EQ(new_target_lang, infobar->target_language_code());
449 TEST_F(TranslateManagerBrowserTest, TranslateScriptNotAvailable) {
450 // Simulate navigating to a page.
451 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
453 // We should have an infobar.
454 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
455 ASSERT_TRUE(infobar != NULL);
456 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
457 infobar->infobar_type());
459 // Simulate clicking translate.
460 process()->sink().ClearMessages();
461 infobar->Translate();
462 // Simulate a failure retrieving the translate script.
463 SimulateTranslateScriptURLFetch(false);
465 // We should not have sent any message to translate to the renderer.
466 EXPECT_FALSE(GetTranslateMessage(NULL, NULL, NULL));
468 // And we should have an error infobar showing.
469 infobar = GetTranslateInfoBar();
470 ASSERT_TRUE(infobar != NULL);
471 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
472 infobar->infobar_type());
475 // Ensures we deal correctly with pages for which the browser does not recognize
476 // the language (the translate server may or not detect the language).
477 TEST_F(TranslateManagerBrowserTest, TranslateUnknownLanguage) {
478 // Simulate navigating to a page ("und" is the string returned by the CLD for
479 // languages it does not recognize).
480 SimulateNavigation(GURL("http://www.google.mys"), "und", true);
482 // We should not have an infobar as we don't know the language.
483 ASSERT_TRUE(GetTranslateInfoBar() == NULL);
485 // Translate the page anyway throught the context menu.
486 scoped_ptr<TestRenderViewContextMenu> menu(
487 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
488 menu->Init();
489 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0);
491 // To test that bug #49018 if fixed, make sure we deal correctly with errors.
492 // Simulate a failure to fetch the translate script.
493 SimulateTranslateScriptURLFetch(false);
494 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
495 ASSERT_TRUE(infobar != NULL);
496 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
497 infobar->infobar_type());
498 EXPECT_TRUE(infobar->IsError());
499 infobar->MessageInfoBarButtonPressed();
500 SimulateTranslateScriptURLFetch(true); // This time succeed.
502 // Simulate the render notifying the translation has been done, the server
503 // having detected the page was in a known and supported language.
504 RenderViewHostTester::TestOnMessageReceived(
505 rvh(),
506 ChromeViewHostMsg_PageTranslated(
507 0, 0, "fr", "en", TranslateErrors::NONE));
509 // The after translate infobar should be showing.
510 infobar = GetTranslateInfoBar();
511 ASSERT_TRUE(infobar != NULL);
512 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE, infobar->infobar_type());
513 EXPECT_EQ("fr", infobar->original_language_code());
514 EXPECT_EQ("en", infobar->target_language_code());
516 // Let's run the same steps but this time the server detects the page is
517 // already in English.
518 SimulateNavigation(GURL("http://www.google.com"), "und", true);
519 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
520 menu->Init();
521 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0);
522 RenderViewHostTester::TestOnMessageReceived(
523 rvh(),
524 ChromeViewHostMsg_PageTranslated(
525 1, 0, "en", "en", TranslateErrors::IDENTICAL_LANGUAGES));
526 infobar = GetTranslateInfoBar();
527 ASSERT_TRUE(infobar != NULL);
528 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
529 infobar->infobar_type());
530 EXPECT_EQ(TranslateErrors::IDENTICAL_LANGUAGES, infobar->error_type());
532 // Let's run the same steps again but this time the server fails to detect the
533 // page's language (it returns an empty string).
534 SimulateNavigation(GURL("http://www.google.com"), "und", true);
535 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
536 menu->Init();
537 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0);
538 RenderViewHostTester::TestOnMessageReceived(
539 rvh(),
540 ChromeViewHostMsg_PageTranslated(
541 2, 0, std::string(), "en", TranslateErrors::UNKNOWN_LANGUAGE));
542 infobar = GetTranslateInfoBar();
543 ASSERT_TRUE(infobar != NULL);
544 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
545 infobar->infobar_type());
546 EXPECT_EQ(TranslateErrors::UNKNOWN_LANGUAGE, infobar->error_type());
549 // Tests that we show/don't show an info-bar for all languages the CLD can
550 // report.
551 TEST_F(TranslateManagerBrowserTest, TestAllLanguages) {
552 // The index in kExpectation are the Language enum (see languages.pb.h).
553 // true if we expect a translate infobar for that language.
554 // Note the supported languages are in translation_manager.cc, see
555 // kSupportedLanguages.
556 bool kExpectations[] = {
557 // 0-9
558 false, true, true, true, true, true, false, true, true, true,
559 // 10-19
560 false, true, true, true, true, true, true, true, true, true,
561 // 20-29
562 true, true, true, true, true, false, false, true, true, true,
563 // 30-39
564 true, true, false, true, true, true, true, false, true, false,
565 // 40-49
566 true, false, true, false, false, true, false, true, false, false,
567 // 50-59
568 false, false, false, true, true, true, true, false, false, false,
569 // 60-69
570 false, false, true, true, false, true, true, false, true, true,
571 // 70-79
572 false, false, false, false, false, false, false, true, false, false,
573 // 80-89
574 false, true, true, false, false, false, false, false, false, false,
575 // 90-99
576 false, true, false, false, false, false, false, false, false, false,
577 // 100-109
578 false, true, false, false, false, false, false, false, false, false,
579 // 110-119
580 false, false, false, false, false, false, false, false, false, false,
581 // 120-129
582 false, false, false, false, false, false, false, false, false, false,
583 // 130-139
584 false, false, false, false, false, false, false, false, false, true,
585 // 140-149
586 false, false, false, false, false, false, false, false, false, false,
587 // 150-159
588 false, false, false, false, false, false, false, false, false, false,
589 // 160
590 true
593 GURL url("http://www.google.com");
594 for (size_t i = 0; i < arraysize(kExpectations); ++i) {
595 ASSERT_LT(i, static_cast<size_t>(NUM_LANGUAGES));
597 std::string lang = LanguageCodeWithDialects(static_cast<Language>(i));
598 SCOPED_TRACE(::testing::Message() << "Iteration " << i <<
599 " language=" << lang);
601 // We should not have a translate infobar.
602 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
603 ASSERT_TRUE(infobar == NULL);
605 // Simulate navigating to a page.
606 NavigateAndCommit(url);
607 SimulateOnTranslateLanguageDetermined(lang, true);
609 // Verify we have/don't have an info-bar as expected.
610 infobar = GetTranslateInfoBar();
611 EXPECT_EQ(kExpectations[i], infobar != NULL);
613 // Close the info-bar if applicable.
614 if (infobar != NULL)
615 EXPECT_TRUE(CloseTranslateInfoBar());
619 // Test the fetching of languages from the translate server
620 TEST_F(TranslateManagerBrowserTest, FetchLanguagesFromTranslateServer) {
621 std::vector<std::string> server_languages;
622 // A list of languages to fake being returned by the translate server.
623 server_languages.push_back("aa");
624 server_languages.push_back("bb");
625 server_languages.push_back("ab");
626 server_languages.push_back("en-CA");
627 server_languages.push_back("zz");
628 server_languages.push_back("yy");
629 server_languages.push_back("fr-FR");
631 // First, get the default languages list:
632 std::vector<std::string> default_supported_languages;
633 TranslateManager::GetSupportedLanguages(&default_supported_languages);
634 // To make sure we got the defaults and don't confuse them with the mocks.
635 ASSERT_NE(default_supported_languages.size(), server_languages.size());
637 Profile* profile =
638 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
639 PrefService* prefs = profile->GetPrefs();
640 TranslateManager::GetInstance()->FetchLanguageListFromTranslateServer(prefs);
642 // Check that we still get the defaults until the URLFetch has completed.
643 std::vector<std::string> current_supported_languages;
644 TranslateManager::GetSupportedLanguages(&current_supported_languages);
645 EXPECT_EQ(default_supported_languages, current_supported_languages);
647 // Also check that it didn't change if we failed the URL fetch.
648 SimulateSupportedLanguagesURLFetch(false, std::vector<std::string>());
649 current_supported_languages.clear();
650 TranslateManager::GetSupportedLanguages(&current_supported_languages);
651 EXPECT_EQ(default_supported_languages, current_supported_languages);
653 // Now check that we got the appropriate set of languages from the server.
654 TranslateManager::GetInstance()->FetchLanguageListFromTranslateServer(prefs);
655 SimulateSupportedLanguagesURLFetch(true, server_languages);
656 current_supported_languages.clear();
657 TranslateManager::GetSupportedLanguages(&current_supported_languages);
658 // Not sure we need to guarantee the order of languages, so we find them.
659 EXPECT_EQ(server_languages.size(), current_supported_languages.size());
660 for (size_t i = 0; i < server_languages.size(); ++i) {
661 EXPECT_NE(current_supported_languages.end(),
662 std::find(current_supported_languages.begin(),
663 current_supported_languages.end(),
664 server_languages[i]));
667 // Reset to original state.
668 TranslateManager::GetInstance()->FetchLanguageListFromTranslateServer(prefs);
669 SimulateSupportedLanguagesURLFetch(true, default_supported_languages);
672 std::string GetLanguageListString(
673 const std::vector<std::string>& language_list) {
674 // The translate manager is expecting a JSON string like:
675 // sl({'sl': {'XX': 'LanguageName', ...}, 'tl': {'XX': 'LanguageName', ...}})
676 // We only need to set the tl (target languages) dictionary.
677 scoped_ptr<DictionaryValue> target_languages_dict(new DictionaryValue);
678 for (size_t i = 0; i < language_list.size(); ++i) {
679 // The value is ignored, we only use the key.
680 target_languages_dict->Set(language_list[i], Value::CreateNullValue());
683 DictionaryValue language_list_dict;
684 language_list_dict.Set("tl", target_languages_dict.release());
685 std::string language_list_json_str;
686 base::JSONWriter::Write(&language_list_dict, &language_list_json_str);
687 std::string language_list_str("sl(");
688 language_list_str += language_list_json_str;
689 language_list_str += ")";
690 return language_list_str;
693 // Tests auto-translate on page.
694 TEST_F(TranslateManagerBrowserTest, AutoTranslateOnNavigate) {
695 // Simulate navigating to a page and getting its language.
696 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
698 // Simulate the user translating.
699 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
700 ASSERT_TRUE(infobar != NULL);
701 infobar->Translate();
702 // Simulate the translate script being retrieved.
703 SimulateTranslateScriptURLFetch(true);
705 RenderViewHostTester::TestOnMessageReceived(
706 rvh(),
707 ChromeViewHostMsg_PageTranslated(
708 0, 0, "fr", "en", TranslateErrors::NONE));
710 // Now navigate to a new page in the same language.
711 process()->sink().ClearMessages();
712 SimulateNavigation(GURL("http://news.google.fr"), "fr", true);
714 // This should have automatically triggered a translation.
715 int page_id = 0;
716 std::string original_lang, target_lang;
717 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
718 EXPECT_EQ(1, page_id);
719 EXPECT_EQ("fr", original_lang);
720 EXPECT_EQ("en", target_lang);
722 // Now navigate to a page in a different language.
723 process()->sink().ClearMessages();
724 SimulateNavigation(GURL("http://news.google.es"), "es", true);
726 // This should not have triggered a translate.
727 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
730 // Tests that multiple OnPageContents do not cause multiple infobars.
731 TEST_F(TranslateManagerBrowserTest, MultipleOnPageContents) {
732 // Simulate navigating to a page and getting its language.
733 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
735 // Simulate clicking 'Nope' (don't translate).
736 EXPECT_TRUE(DenyTranslation());
737 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
739 // Send a new PageContents, we should not show an infobar.
740 SimulateOnTranslateLanguageDetermined("fr", true);
741 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
743 // Do the same steps but simulate closing the infobar this time.
744 SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true);
745 EXPECT_TRUE(CloseTranslateInfoBar());
746 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
747 SimulateOnTranslateLanguageDetermined("fr", true);
748 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
751 // Test that reloading the page brings back the infobar if the
752 // reload succeeded and does not bring it back the reload fails.
753 TEST_F(TranslateManagerBrowserTest, Reload) {
754 // Simulate navigating to a page and getting its language.
755 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
757 // Close the infobar.
758 EXPECT_TRUE(CloseTranslateInfoBar());
760 // Reload should bring back the infobar if the page succeds
761 ReloadAndWait(true);
762 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
764 // Close the infobar.
765 EXPECT_TRUE(CloseTranslateInfoBar());
767 // And not show it if the reload fails
768 ReloadAndWait(false);
769 EXPECT_EQ(NULL, GetTranslateInfoBar());
772 // Test that reloading the page by way of typing again the URL in the
773 // location bar brings back the infobar.
774 TEST_F(TranslateManagerBrowserTest, ReloadFromLocationBar) {
775 GURL url("http://www.google.fr");
777 // Simulate navigating to a page and getting its language.
778 SimulateNavigation(url, "fr", true);
780 // Close the infobar.
781 EXPECT_TRUE(CloseTranslateInfoBar());
783 // Create a pending navigation and simulate a page load. That should be the
784 // equivalent of typing the URL again in the location bar.
785 NavEntryCommittedObserver nav_observer(web_contents());
786 web_contents()->GetController().LoadURL(url, content::Referrer(),
787 content::PAGE_TRANSITION_TYPED,
788 std::string());
789 rvh_tester()->SendNavigate(0, url);
791 // Test that we are really getting a same page navigation, the test would be
792 // useless if it was not the case.
793 const content::LoadCommittedDetails& nav_details =
794 nav_observer.get_load_commited_details();
795 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation.
796 EXPECT_EQ(content::NAVIGATION_TYPE_SAME_PAGE, nav_details.type);
798 // The TranslateManager class processes the navigation entry committed
799 // notification in a posted task; process that task.
800 MessageLoop::current()->RunUntilIdle();
801 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
804 // Tests that a closed translate infobar does not reappear when navigating
805 // in-page.
806 TEST_F(TranslateManagerBrowserTest, CloseInfoBarInPageNavigation) {
807 // Simulate navigating to a page and getting its language.
808 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
810 // Close the infobar.
811 EXPECT_TRUE(CloseTranslateInfoBar());
813 // Navigate in page, no infobar should be shown.
814 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr",
815 true);
816 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
818 // Navigate out of page, a new infobar should show.
819 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true);
820 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
823 // Tests that a closed translate infobar does not reappear when navigating
824 // in a subframe. (http://crbug.com/48215)
825 TEST_F(TranslateManagerBrowserTest, CloseInfoBarInSubframeNavigation) {
826 // Simulate navigating to a page and getting its language.
827 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
829 // Close the infobar.
830 EXPECT_TRUE(CloseTranslateInfoBar());
832 // Simulate a sub-frame auto-navigating.
833 rvh_tester()->SendNavigateWithTransition(
834 1, GURL("http://pub.com"), content::PAGE_TRANSITION_AUTO_SUBFRAME);
835 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
837 // Simulate the user navigating in a sub-frame.
838 rvh_tester()->SendNavigateWithTransition(
839 2, GURL("http://pub.com"), content::PAGE_TRANSITION_MANUAL_SUBFRAME);
840 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
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);
847 // Tests that denying translation is sticky when navigating in page.
848 TEST_F(TranslateManagerBrowserTest, DenyTranslateInPageNavigation) {
849 // Simulate navigating to a page and getting its language.
850 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
852 // Simulate clicking 'Nope' (don't translate).
853 EXPECT_TRUE(DenyTranslation());
855 // Navigate in page, no infobar should be shown.
856 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true);
857 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
859 // Navigate out of page, a new infobar should show.
860 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true);
861 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
864 // Tests that after translating and closing the infobar, the infobar does not
865 // return when navigating in page.
866 TEST_F(TranslateManagerBrowserTest, TranslateCloseInfoBarInPageNavigation) {
867 // Simulate navigating to a page and getting its language.
868 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
870 // Simulate the user translating.
871 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
872 ASSERT_TRUE(infobar != NULL);
873 infobar->Translate();
874 // Simulate the translate script being retrieved.
875 SimulateTranslateScriptURLFetch(true);
876 RenderViewHostTester::TestOnMessageReceived(
877 rvh(),
878 ChromeViewHostMsg_PageTranslated(
879 0, 0, "fr", "en", TranslateErrors::NONE));
881 // Close the infobar.
882 EXPECT_TRUE(CloseTranslateInfoBar());
884 // Navigate in page, no infobar should be shown.
885 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true);
886 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
888 // Navigate out of page, a new infobar should show.
889 // Note that we navigate to a page in a different language so we don't trigger
890 // the auto-translate feature (it would translate the page automatically and
891 // the before translate inforbar would not be shown).
892 SimulateNavigation(GURL("http://www.google.de"), "de", true);
893 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
896 // Tests that the after translate the infobar still shows when navigating
897 // in-page.
898 TEST_F(TranslateManagerBrowserTest, TranslateInPageNavigation) {
899 // Simulate navigating to a page and getting its language.
900 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
902 // Simulate the user translating.
903 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
904 ASSERT_TRUE(infobar != NULL);
905 infobar->Translate();
906 // Simulate the translate script being retrieved.
907 SimulateTranslateScriptURLFetch(true);
908 RenderViewHostTester::TestOnMessageReceived(
909 rvh(),
910 ChromeViewHostMsg_PageTranslated(
911 0, 0, "fr", "en", TranslateErrors::NONE));
912 // The after translate infobar is showing.
913 infobar = GetTranslateInfoBar();
914 ASSERT_TRUE(infobar != NULL);
916 // Navigate out of page, a new infobar should show.
917 // See note in TranslateCloseInfoBarInPageNavigation test on why it is
918 // important to navigate to a page in a different language for this test.
919 SimulateNavigation(GURL("http://www.google.de"), "de", true);
920 // The old infobar is gone.
921 EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar));
922 // And there is a new one.
923 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
926 // Tests that no translate infobar is shown when navigating to a page in an
927 // unsupported language.
928 TEST_F(TranslateManagerBrowserTest, CLDReportsUnsupportedPageLanguage) {
929 // Simulate navigating to a page and getting an unsupported language.
930 SimulateNavigation(GURL("http://www.google.com"), "qbz", true);
932 // No info-bar should be shown.
933 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
936 // Tests that we deal correctly with unsupported languages returned by the
937 // server.
938 // The translation server might return a language we don't support.
939 TEST_F(TranslateManagerBrowserTest, ServerReportsUnsupportedLanguage) {
940 // Simulate navigating to a page and translating it.
941 SimulateNavigation(GURL("http://mail.google.fr"), "fr", true);
942 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
943 ASSERT_TRUE(infobar != NULL);
944 process()->sink().ClearMessages();
945 infobar->Translate();
946 SimulateTranslateScriptURLFetch(true);
947 // Simulate the render notifying the translation has been done, but it
948 // reports a language we don't support.
949 RenderViewHostTester::TestOnMessageReceived(
950 rvh(),
951 ChromeViewHostMsg_PageTranslated(
952 0, 0, "qbz", "en", TranslateErrors::NONE));
954 // An error infobar should be showing to report that we don't support this
955 // language.
956 infobar = GetTranslateInfoBar();
957 ASSERT_TRUE(infobar != NULL);
958 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
959 infobar->infobar_type());
961 // This infobar should have a button (so the string should not be empty).
962 ASSERT_FALSE(infobar->GetMessageInfoBarButtonText().empty());
964 // Pressing the button on that infobar should revert to the original language.
965 process()->sink().ClearMessages();
966 infobar->MessageInfoBarButtonPressed();
967 const IPC::Message* message =
968 process()->sink().GetFirstMessageMatching(
969 ChromeViewMsg_RevertTranslation::ID);
970 EXPECT_TRUE(message != NULL);
971 // And it should have removed the infobar.
972 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
975 // Tests that no translate infobar is shown and context menu is disabled, when
976 // Chrome is in a language that the translate server does not support.
977 TEST_F(TranslateManagerBrowserTest, UnsupportedUILanguage) {
978 std::string original_lang = g_browser_process->GetApplicationLocale();
979 g_browser_process->SetApplicationLocale("qbz");
981 // Make sure that the accept language list only contains unsupported languages
982 Profile* profile =
983 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
984 PrefService* prefs = profile->GetPrefs();
985 prefs->SetString(prefs::kAcceptLanguages, "qbz");
987 // Simulate navigating to a page in a language supported by the translate
988 // server.
989 SimulateNavigation(GURL("http://www.google.com"), "en", true);
991 // No info-bar should be shown.
992 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
994 // And the context menu option should be disabled too.
995 scoped_ptr<TestRenderViewContextMenu> menu(
996 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
997 menu->Init();
998 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
999 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1001 g_browser_process->SetApplicationLocale(original_lang);
1004 // Tests that the first supported accept language is selected
1005 TEST_F(TranslateManagerBrowserTest, TranslateAcceptLanguage) {
1006 // Set locate to non-existant language
1007 std::string original_lang = g_browser_process->GetApplicationLocale();
1008 g_browser_process->SetApplicationLocale("qbz");
1010 // Set Qbz and French as the only accepted languages
1011 Profile* profile =
1012 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1013 PrefService* prefs = profile->GetPrefs();
1014 prefs->SetString(prefs::kAcceptLanguages, "qbz,fr");
1016 // Go to a German page
1017 SimulateNavigation(GURL("http://google.de"), "de", true);
1019 // Expect the infobar to pop up
1020 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1022 // Set Qbz and English-US as the only accepted languages to test the country
1023 // code removal code which was causing a crash as filed in Issue 90106,
1024 // a crash caused by a language with a country code that wasn't recognized.
1025 prefs->SetString(prefs::kAcceptLanguages, "qbz,en-us");
1027 // Go to a German page
1028 SimulateNavigation(GURL("http://google.de"), "de", true);
1030 // Expect the infobar to pop up
1031 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1034 // Tests that the translate enabled preference is honored.
1035 TEST_F(TranslateManagerBrowserTest, TranslateEnabledPref) {
1036 // Make sure the pref allows translate.
1037 Profile* profile =
1038 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1039 PrefService* prefs = profile->GetPrefs();
1040 prefs->SetBoolean(prefs::kEnableTranslate, true);
1042 // Simulate navigating to a page and getting its language.
1043 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1045 // An infobar should be shown.
1046 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
1047 EXPECT_TRUE(infobar != NULL);
1049 // Disable translate.
1050 prefs->SetBoolean(prefs::kEnableTranslate, false);
1052 // Navigate to a new page, that should close the previous infobar.
1053 GURL url("http://www.youtube.fr");
1054 NavigateAndCommit(url);
1055 infobar = GetTranslateInfoBar();
1056 EXPECT_TRUE(infobar == NULL);
1058 // Simulate getting the page contents and language, that should not trigger
1059 // a translate infobar.
1060 SimulateOnTranslateLanguageDetermined("fr", true);
1061 infobar = GetTranslateInfoBar();
1062 EXPECT_TRUE(infobar == NULL);
1065 // Tests the "Never translate <language>" pref.
1066 TEST_F(TranslateManagerBrowserTest, NeverTranslateLanguagePref) {
1067 // Simulate navigating to a page and getting its language.
1068 GURL url("http://www.google.fr");
1069 SimulateNavigation(url, "fr", true);
1071 // An infobar should be shown.
1072 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1074 // Select never translate this language.
1075 Profile* profile =
1076 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1077 PrefService* prefs = profile->GetPrefs();
1078 PrefChangeRegistrar registrar;
1079 registrar.Init(prefs);
1080 registrar.Add(TranslatePrefs::kPrefTranslateLanguageBlacklist,
1081 pref_callback_);
1082 TranslatePrefs translate_prefs(prefs);
1083 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr"));
1084 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url));
1085 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateLanguageBlacklist);
1086 translate_prefs.BlacklistLanguage("fr");
1087 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("fr"));
1088 EXPECT_FALSE(translate_prefs.CanTranslate(prefs, "fr", url));
1090 // Close the infobar.
1091 EXPECT_TRUE(CloseTranslateInfoBar());
1093 // Navigate to a new page also in French.
1094 SimulateNavigation(GURL("http://wwww.youtube.fr"), "fr", true);
1096 // There should not be a translate infobar.
1097 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
1099 // Remove the language from the blacklist.
1100 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateLanguageBlacklist);
1101 translate_prefs.RemoveLanguageFromBlacklist("fr");
1102 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr"));
1103 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url));
1105 // Navigate to a page in French.
1106 SimulateNavigation(url, "fr", true);
1108 // There should be a translate infobar.
1109 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1112 // Tests the "Never translate this site" pref.
1113 TEST_F(TranslateManagerBrowserTest, NeverTranslateSitePref) {
1114 // Simulate navigating to a page and getting its language.
1115 GURL url("http://www.google.fr");
1116 std::string host(url.host());
1117 SimulateNavigation(url, "fr", true);
1119 // An infobar should be shown.
1120 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1122 // Select never translate this site.
1123 Profile* profile =
1124 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1125 PrefService* prefs = profile->GetPrefs();
1126 PrefChangeRegistrar registrar;
1127 registrar.Init(prefs);
1128 registrar.Add(TranslatePrefs::kPrefTranslateSiteBlacklist, pref_callback_);
1129 TranslatePrefs translate_prefs(prefs);
1130 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(host));
1131 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url));
1132 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist);
1133 translate_prefs.BlacklistSite(host);
1134 EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(host));
1135 EXPECT_FALSE(translate_prefs.CanTranslate(prefs, "fr", url));
1137 // Close the infobar.
1138 EXPECT_TRUE(CloseTranslateInfoBar());
1140 // Navigate to a new page also on the same site.
1141 SimulateNavigation(GURL("http://www.google.fr/hello"), "fr", true);
1143 // There should not be a translate infobar.
1144 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
1146 // Remove the site from the blacklist.
1147 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist);
1148 translate_prefs.RemoveSiteFromBlacklist(host);
1149 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(host));
1150 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url));
1152 // Navigate to a page in French.
1153 SimulateNavigation(url, "fr", true);
1155 // There should be a translate infobar.
1156 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1159 // Tests the "Always translate this language" pref.
1160 TEST_F(TranslateManagerBrowserTest, AlwaysTranslateLanguagePref) {
1161 // Select always translate French to English.
1162 Profile* profile =
1163 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1164 PrefService* prefs = profile->GetPrefs();
1165 PrefChangeRegistrar registrar;
1166 registrar.Init(prefs);
1167 registrar.Add(TranslatePrefs::kPrefTranslateWhitelists, pref_callback_);
1168 TranslatePrefs translate_prefs(prefs);
1169 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists);
1170 translate_prefs.WhitelistLanguagePair("fr", "en");
1172 // Load a page in French.
1173 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1175 // It should have triggered an automatic translation to English.
1177 // The translating infobar should be showing.
1178 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
1179 ASSERT_TRUE(infobar != NULL);
1180 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->infobar_type());
1181 // Simulate the translate script being retrieved.
1182 SimulateTranslateScriptURLFetch(true);
1183 int page_id = 0;
1184 std::string original_lang, target_lang;
1185 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1186 EXPECT_EQ("fr", original_lang);
1187 EXPECT_EQ("en", target_lang);
1188 process()->sink().ClearMessages();
1190 // Try another language, it should not be autotranslated.
1191 SimulateNavigation(GURL("http://www.google.es"), "es", true);
1192 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1193 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1194 EXPECT_TRUE(CloseTranslateInfoBar());
1196 // Let's switch to incognito mode, it should not be autotranslated in that
1197 // case either.
1198 TestingProfile* test_profile =
1199 static_cast<TestingProfile*>(web_contents()->GetBrowserContext());
1200 test_profile->set_incognito(true);
1201 SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true);
1202 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1203 EXPECT_TRUE(GetTranslateInfoBar() != NULL);
1204 EXPECT_TRUE(CloseTranslateInfoBar());
1205 test_profile->set_incognito(false); // Get back to non incognito.
1207 // Now revert the always translate pref and make sure we go back to expected
1208 // behavior, which is show a "before translate" infobar.
1209 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists);
1210 translate_prefs.RemoveLanguagePairFromWhitelist("fr", "en");
1211 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1212 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1213 infobar = GetTranslateInfoBar();
1214 ASSERT_TRUE(infobar != NULL);
1215 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
1216 infobar->infobar_type());
1219 // Context menu.
1220 TEST_F(TranslateManagerBrowserTest, ContextMenu) {
1221 // Blacklist www.google.fr and French for translation.
1222 GURL url("http://www.google.fr");
1223 Profile* profile =
1224 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1225 TranslatePrefs translate_prefs(profile->GetPrefs());
1226 translate_prefs.BlacklistLanguage("fr");
1227 translate_prefs.BlacklistSite(url.host());
1228 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("fr"));
1229 EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(url.host()));
1231 // Simulate navigating to a page in French. The translate menu should show but
1232 // should only be enabled when the page language has been received.
1233 NavigateAndCommit(url);
1234 scoped_ptr<TestRenderViewContextMenu> menu(
1235 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1236 menu->Init();
1237 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1238 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1240 // Simulate receiving the language.
1241 SimulateOnTranslateLanguageDetermined("fr", true);
1242 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1243 menu->Init();
1244 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1245 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1247 // Use the menu to translate the page.
1248 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0);
1250 // That should have triggered a translation.
1251 // The "translating..." infobar should be showing.
1252 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
1253 ASSERT_TRUE(infobar != NULL);
1254 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->infobar_type());
1255 // Simulate the translate script being retrieved.
1256 SimulateTranslateScriptURLFetch(true);
1257 int page_id = 0;
1258 std::string original_lang, target_lang;
1259 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1260 EXPECT_EQ("fr", original_lang);
1261 EXPECT_EQ("en", target_lang);
1262 process()->sink().ClearMessages();
1264 // This should also have reverted the blacklisting of this site and language.
1265 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr"));
1266 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(url.host()));
1268 // Let's simulate the page being translated.
1269 RenderViewHostTester::TestOnMessageReceived(
1270 rvh(),
1271 ChromeViewHostMsg_PageTranslated(
1272 0, 0, "fr", "en", TranslateErrors::NONE));
1274 // The translate menu should now be disabled.
1275 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1276 menu->Init();
1277 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1278 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1280 // Test that selecting translate in the context menu WHILE the page is being
1281 // translated does nothing (this could happen if autotranslate kicks-in and
1282 // the user selects the menu while the translation is being performed).
1283 SimulateNavigation(GURL("http://www.google.es"), "es", true);
1284 infobar = GetTranslateInfoBar();
1285 ASSERT_TRUE(infobar != NULL);
1286 infobar->Translate();
1287 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1288 process()->sink().ClearMessages();
1289 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1290 menu->Init();
1291 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1292 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0);
1293 // No message expected since the translation should have been ignored.
1294 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1296 // Now test that selecting translate in the context menu AFTER the page has
1297 // been translated does nothing.
1298 SimulateNavigation(GURL("http://www.google.de"), "de", true);
1299 infobar = GetTranslateInfoBar();
1300 ASSERT_TRUE(infobar != NULL);
1301 infobar->Translate();
1302 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1303 process()->sink().ClearMessages();
1304 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1305 menu->Init();
1306 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1307 RenderViewHostTester::TestOnMessageReceived(
1308 rvh(),
1309 ChromeViewHostMsg_PageTranslated(
1310 0, 0, "de", "en", TranslateErrors::NONE));
1311 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0);
1312 // No message expected since the translation should have been ignored.
1313 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1315 // Test that the translate context menu is enabled when the page is in an
1316 // unknown language.
1317 SimulateNavigation(url, "und", true);
1318 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1319 menu->Init();
1320 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1321 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1323 // Test that the translate context menu is disabled when the page is in an
1324 // unsupported language.
1325 SimulateNavigation(url, "qbz", true);
1326 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1327 menu->Init();
1328 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1329 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1332 // Tests that an extra always/never translate button is shown on the "before
1333 // translate" infobar when the translation is accepted/declined 3 times,
1334 // only when not in incognito mode.
1335 TEST_F(TranslateManagerBrowserTest, BeforeTranslateExtraButtons) {
1336 Profile* profile =
1337 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1338 TranslatePrefs translate_prefs(profile->GetPrefs());
1339 translate_prefs.ResetTranslationAcceptedCount("fr");
1340 translate_prefs.ResetTranslationDeniedCount("fr");
1341 translate_prefs.ResetTranslationAcceptedCount("de");
1342 translate_prefs.ResetTranslationDeniedCount("de");
1344 // We'll do 4 times in incognito mode first to make sure the button is not
1345 // shown in that case, then 4 times in normal mode.
1346 TranslateInfoBarDelegate* infobar;
1347 TestingProfile* test_profile =
1348 static_cast<TestingProfile*>(web_contents()->GetBrowserContext());
1349 static_cast<extensions::TestExtensionSystem*>(
1350 extensions::ExtensionSystem::Get(test_profile))->
1351 CreateExtensionProcessManager();
1352 test_profile->set_incognito(true);
1353 for (int i = 0; i < 8; ++i) {
1354 SCOPED_TRACE(::testing::Message() << "Iteration " << i <<
1355 " incognito mode=" << test_profile->IsOffTheRecord());
1356 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1357 infobar = GetTranslateInfoBar();
1358 ASSERT_TRUE(infobar != NULL);
1359 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
1360 infobar->infobar_type());
1361 if (i < 7) {
1362 EXPECT_FALSE(infobar->ShouldShowAlwaysTranslateButton());
1363 infobar->Translate();
1364 process()->sink().ClearMessages();
1365 } else {
1366 EXPECT_TRUE(infobar->ShouldShowAlwaysTranslateButton());
1368 if (i == 3)
1369 test_profile->set_incognito(false);
1371 // Simulate the user pressing "Always translate French".
1372 infobar->AlwaysTranslatePageLanguage();
1373 EXPECT_TRUE(translate_prefs.IsLanguagePairWhitelisted("fr", "en"));
1374 // Simulate the translate script being retrieved (it only needs to be done
1375 // once in the test as it is cached).
1376 SimulateTranslateScriptURLFetch(true);
1377 // That should have triggered a page translate.
1378 int page_id = 0;
1379 std::string original_lang, target_lang;
1380 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1381 process()->sink().ClearMessages();
1383 // Now test that declining the translation causes a "never translate" button
1384 // to be shown (in non incognito mode only).
1385 test_profile->set_incognito(true);
1386 for (int i = 0; i < 8; ++i) {
1387 SCOPED_TRACE(::testing::Message() << "Iteration " << i <<
1388 " incognito mode=" << test_profile->IsOffTheRecord());
1389 SimulateNavigation(GURL("http://www.google.de"), "de", true);
1390 infobar = GetTranslateInfoBar();
1391 ASSERT_TRUE(infobar != NULL);
1392 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
1393 infobar->infobar_type());
1394 if (i < 7) {
1395 EXPECT_FALSE(infobar->ShouldShowNeverTranslateButton());
1396 infobar->TranslationDeclined();
1397 } else {
1398 EXPECT_TRUE(infobar->ShouldShowNeverTranslateButton());
1400 if (i == 3)
1401 test_profile->set_incognito(false);
1403 // Simulate the user pressing "Never translate French".
1404 infobar->NeverTranslatePageLanguage();
1405 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("de"));
1406 // No translation should have occured and the infobar should be gone.
1407 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1408 process()->sink().ClearMessages();
1409 ASSERT_TRUE(GetTranslateInfoBar() == NULL);
1412 // Tests that we don't show a translate infobar when a page instructs that it
1413 // should not be translated.
1414 TEST_F(TranslateManagerBrowserTest, NonTranslatablePage) {
1415 // Simulate navigating to a page.
1416 SimulateNavigation(GURL("http://mail.google.fr"), "fr", false);
1418 // We should not have an infobar.
1419 EXPECT_TRUE(GetTranslateInfoBar() == NULL);
1421 // The context menu should be disabled.
1422 scoped_ptr<TestRenderViewContextMenu> menu(
1423 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1424 menu->Init();
1425 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
1426 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
1429 // Tests that the script is expired and refetched as expected.
1430 TEST_F(TranslateManagerBrowserTest, ScriptExpires) {
1431 ExpireTranslateScriptImmediately();
1433 // Simulate navigating to a page and translating it.
1434 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1435 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
1436 ASSERT_TRUE(infobar != NULL);
1437 process()->sink().ClearMessages();
1438 infobar->Translate();
1439 SimulateTranslateScriptURLFetch(true);
1440 RenderViewHostTester::TestOnMessageReceived(
1441 rvh(),
1442 ChromeViewHostMsg_PageTranslated(
1443 0, 0, "fr", "en", TranslateErrors::NONE));
1445 // A task should have been posted to clear the script, run it.
1446 MessageLoop::current()->RunUntilIdle();
1448 // Do another navigation and translation.
1449 SimulateNavigation(GURL("http://www.google.es"), "es", true);
1450 infobar = GetTranslateInfoBar();
1451 ASSERT_TRUE(infobar != NULL);
1452 process()->sink().ClearMessages();
1453 infobar->Translate();
1454 // If we don't simulate the URL fetch, the TranslateManager should be waiting
1455 // for the script and no message should have been sent to the renderer.
1456 EXPECT_TRUE(
1457 process()->sink().GetFirstMessageMatching(
1458 ChromeViewMsg_TranslatePage::ID) ==
1459 NULL);
1460 // Now simulate the URL fetch.
1461 SimulateTranslateScriptURLFetch(true);
1462 // Now the message should have been sent.
1463 int page_id = 0;
1464 std::string original_lang, target_lang;
1465 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
1466 EXPECT_EQ("es", original_lang);
1467 EXPECT_EQ("en", target_lang);
1470 TEST_F(TranslateManagerBrowserTest, DownloadsAndHistoryNotTranslated) {
1471 ASSERT_FALSE(TranslateManager::IsTranslatableURL(
1472 GURL(chrome::kChromeUIDownloadsURL)));
1473 ASSERT_FALSE(TranslateManager::IsTranslatableURL(
1474 GURL(chrome::kChromeUIHistoryURL)));
1477 // Test is flaky on Win http://crbug.com/166334
1478 #if defined(OS_WIN)
1479 #define MAYBE_PRE_TranslateSessionRestore DISABLED_PRE_TranslateSessionRestore
1480 #else
1481 #define MAYBE_PRE_TranslateSessionRestore PRE_TranslateSessionRestore
1482 #endif
1483 // Test that session restore restores the translate infobar and other translate
1484 // settings.
1485 IN_PROC_BROWSER_TEST_F(InProcessBrowserTest,
1486 MAYBE_PRE_TranslateSessionRestore) {
1487 SessionStartupPref pref(SessionStartupPref::LAST);
1488 SessionStartupPref::SetStartupPref(browser()->profile(), pref);
1490 WebContents* current_web_contents =
1491 browser()->tab_strip_model()->GetActiveWebContents();
1492 TranslateTabHelper* translate_tab_helper =
1493 TranslateTabHelper::FromWebContents(current_web_contents);
1494 content::Source<WebContents> source(current_web_contents);
1496 ui_test_utils::WindowedNotificationObserverWithDetails<std::string>
1497 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED,
1498 source);
1500 GURL french_url = ui_test_utils::GetTestUrl(
1501 base::FilePath(), base::FilePath(FILE_PATH_LITERAL("french_page.html")));
1502 ui_test_utils::NavigateToURL(browser(), french_url);
1503 fr_language_detected_signal.Wait();
1504 std::string lang;
1505 EXPECT_TRUE(fr_language_detected_signal.GetDetailsFor(
1506 source.map_key(), &lang));
1507 EXPECT_EQ("fr", lang);
1508 EXPECT_EQ("fr", translate_tab_helper->language_state().original_language());
1511 #if defined (OS_WIN)
1512 #define MAYBE_TranslateSessionRestore DISABLED_TranslateSessionRestore
1513 #else
1514 #define MAYBE_TranslateSessionRestore TranslateSessionRestore
1515 #endif
1516 IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, MAYBE_TranslateSessionRestore) {
1517 WebContents* current_web_contents =
1518 browser()->tab_strip_model()->GetActiveWebContents();
1519 content::Source<WebContents> source(current_web_contents);
1521 ui_test_utils::WindowedNotificationObserverWithDetails<std::string>
1522 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED,
1523 source);
1524 fr_language_detected_signal.Wait();