1 // Copyright 2014 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 #include <algorithm> 6 #include <set> 7 #include <vector> 8 9 #include "base/macros.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/prefs/pref_change_registrar.h" 12 #include "base/prefs/pref_service.h" 13 #include "base/strings/stringprintf.h" 14 #include "chrome/app/chrome_command_ids.h" 15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/extensions/test_extension_system.h" 17 #include "chrome/browser/infobars/infobar_service.h" 18 #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" 19 #include "chrome/browser/translate/chrome_translate_client.h" 20 #include "chrome/browser/translate/translate_service.h" 21 #include "chrome/browser/ui/translate/translate_bubble_factory.h" 22 #include "chrome/browser/ui/translate/translate_bubble_model.h" 23 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h" 24 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/pref_names.h" 26 #include "chrome/common/url_constants.h" 27 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 28 #include "chrome/test/base/testing_browser_process.h" 29 #include "chrome/test/base/testing_profile.h" 30 #include "components/infobars/core/infobar.h" 31 #include "components/translate/content/browser/content_translate_driver.h" 32 #include "components/translate/content/common/translate_messages.h" 33 #include "components/translate/core/browser/translate_accept_languages.h" 34 #include "components/translate/core/browser/translate_download_manager.h" 35 #include "components/translate/core/browser/translate_infobar_delegate.h" 36 #include "components/translate/core/browser/translate_language_list.h" 37 #include "components/translate/core/browser/translate_manager.h" 38 #include "components/translate/core/browser/translate_prefs.h" 39 #include "components/translate/core/browser/translate_script.h" 40 #include "components/translate/core/common/language_detection_details.h" 41 #include "components/translate/core/common/translate_pref_names.h" 42 #include "content/public/browser/navigation_details.h" 43 #include "content/public/browser/navigation_entry.h" 44 #include "content/public/browser/notification_details.h" 45 #include "content/public/browser/notification_registrar.h" 46 #include "content/public/browser/web_contents.h" 47 #include "content/public/common/url_constants.h" 48 #include "content/public/test/mock_render_process_host.h" 49 #include "content/public/test/test_renderer_host.h" 50 #include "net/url_request/test_url_fetcher_factory.h" 51 #include "net/url_request/url_fetcher_delegate.h" 52 #include "testing/gmock/include/gmock/gmock.h" 53 #include "third_party/WebKit/public/web/WebContextMenuData.h" 54 #include "url/gurl.h" 55 56 // An observer that keeps track of whether a navigation entry was committed. 57 class NavEntryCommittedObserver : public content::NotificationObserver { 58 public: 59 explicit NavEntryCommittedObserver(content::WebContents* web_contents) { 60 registrar_.Add(this, 61 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 62 content::Source<content::NavigationController>( 63 &web_contents->GetController())); 64 } 65 66 virtual void Observe(int type, 67 const content::NotificationSource& source, 68 const content::NotificationDetails& details) OVERRIDE { 69 DCHECK(type == content::NOTIFICATION_NAV_ENTRY_COMMITTED); 70 details_ = 71 *(content::Details<content::LoadCommittedDetails>(details).ptr()); 72 } 73 74 const content::LoadCommittedDetails& load_committed_details() const { 75 return details_; 76 } 77 78 private: 79 content::LoadCommittedDetails details_; 80 content::NotificationRegistrar registrar_; 81 82 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver); 83 }; 84 85 class TranslateManagerRenderViewHostTest 86 : public ChromeRenderViewHostTestHarness, 87 public content::NotificationObserver { 88 public: 89 TranslateManagerRenderViewHostTest() 90 : pref_callback_( 91 base::Bind(&TranslateManagerRenderViewHostTest::OnPreferenceChanged, 92 base::Unretained(this))) {} 93 94 // Simulates navigating to a page and getting the page contents and language 95 // for that navigation. 96 void SimulateNavigation(const GURL& url, 97 const std::string& lang, 98 bool page_translatable) { 99 if (rvh()->GetMainFrame()->GetLastCommittedURL() == url) 100 Reload(); 101 else 102 NavigateAndCommit(url); 103 SimulateOnTranslateLanguageDetermined(lang, page_translatable); 104 } 105 106 void SimulateOnTranslateLanguageDetermined(const std::string& lang, 107 bool page_translatable) { 108 translate::LanguageDetectionDetails details; 109 details.adopted_language = lang; 110 content::RenderViewHostTester::TestOnMessageReceived( 111 rvh(), 112 ChromeViewHostMsg_TranslateLanguageDetermined( 113 0, details, page_translatable)); 114 } 115 116 void SimulateOnPageTranslated(int routing_id, 117 const std::string& source_lang, 118 const std::string& target_lang, 119 translate::TranslateErrors::Type error) { 120 content::RenderViewHostTester::TestOnMessageReceived( 121 rvh(), 122 ChromeViewHostMsg_PageTranslated( 123 routing_id, source_lang, target_lang, error)); 124 } 125 126 void SimulateOnPageTranslated(const std::string& source_lang, 127 const std::string& target_lang) { 128 SimulateOnPageTranslated( 129 0, source_lang, target_lang, translate::TranslateErrors::NONE); 130 } 131 132 bool GetTranslateMessage(std::string* original_lang, 133 std::string* target_lang) { 134 const IPC::Message* message = process()->sink().GetFirstMessageMatching( 135 ChromeViewMsg_TranslatePage::ID); 136 if (!message) 137 return false; 138 Tuple4<int, std::string, std::string, std::string> translate_param; 139 ChromeViewMsg_TranslatePage::Read(message, &translate_param); 140 // Ignore translate_param.a which is the page seq no. 141 // Ignore translate_param.b which is the script injected in the page. 142 if (original_lang) 143 *original_lang = translate_param.c; 144 if (target_lang) 145 *target_lang = translate_param.d; 146 return true; 147 } 148 149 InfoBarService* infobar_service() { 150 return InfoBarService::FromWebContents(web_contents()); 151 } 152 153 // Returns the translate infobar if there is 1 infobar and it is a translate 154 // infobar. 155 translate::TranslateInfoBarDelegate* GetTranslateInfoBar() { 156 return (infobar_service()->infobar_count() == 1) ? 157 infobar_service()->infobar_at(0)->delegate()-> 158 AsTranslateInfoBarDelegate() : 159 NULL; 160 } 161 162 // If there is 1 infobar and it is a translate infobar, closes it and returns 163 // true. Returns false otherwise. 164 bool CloseTranslateInfoBar() { 165 infobars::InfoBarDelegate* infobar = GetTranslateInfoBar(); 166 if (!infobar) 167 return false; 168 infobar->InfoBarDismissed(); // Simulates closing the infobar. 169 infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0)); 170 return true; 171 } 172 173 // Checks whether |infobar| has been removed and clears the removed infobar 174 // list. 175 bool CheckInfoBarRemovedAndReset(infobars::InfoBarDelegate* delegate) { 176 bool found = removed_infobars_.count(delegate) != 0; 177 removed_infobars_.clear(); 178 return found; 179 } 180 181 void ExpireTranslateScriptImmediately() { 182 translate::TranslateDownloadManager::GetInstance() 183 ->SetTranslateScriptExpirationDelay(0); 184 } 185 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 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 190 if (!infobar) 191 return false; 192 infobar->TranslationDeclined(); 193 infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0)); 194 return true; 195 } 196 197 void ReloadAndWait(bool successful_reload) { 198 NavEntryCommittedObserver nav_observer(web_contents()); 199 if (successful_reload) 200 Reload(); 201 else 202 FailedReload(); 203 204 // Ensures it is really handled a reload. 205 const content::LoadCommittedDetails& nav_details = 206 nav_observer.load_committed_details(); 207 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation. 208 EXPECT_EQ(content::NAVIGATION_TYPE_EXISTING_PAGE, nav_details.type); 209 210 // The TranslateManager class processes the navigation entry committed 211 // notification in a posted task; process that task. 212 base::MessageLoop::current()->RunUntilIdle(); 213 } 214 215 TestRenderViewContextMenu* CreateContextMenu() { 216 content::ContextMenuParams params; 217 params.media_type = blink::WebContextMenuData::MediaTypeNone; 218 params.x = 0; 219 params.y = 0; 220 params.has_image_contents = true; 221 params.media_flags = 0; 222 params.spellcheck_enabled = false; 223 params.is_editable = false; 224 params.page_url = 225 web_contents()->GetController().GetActiveEntry()->GetURL(); 226 #if defined(OS_MACOSX) 227 params.writing_direction_default = 0; 228 params.writing_direction_left_to_right = 0; 229 params.writing_direction_right_to_left = 0; 230 #endif // OS_MACOSX 231 params.edit_flags = blink::WebContextMenuData::CanTranslate; 232 return new TestRenderViewContextMenu(web_contents()->GetMainFrame(), 233 params); 234 } 235 236 virtual void Observe(int type, 237 const content::NotificationSource& source, 238 const content::NotificationDetails& details) { 239 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); 240 removed_infobars_.insert( 241 content::Details<infobars::InfoBar::RemovedDetails>( 242 details)->first->delegate()); 243 } 244 245 MOCK_METHOD1(OnPreferenceChanged, void(const std::string&)); 246 247 protected: 248 virtual void SetUp() { 249 TranslateService::InitializeForTesting(); 250 251 // Clears the translate script so it is fetched everytime and sets the 252 // expiration delay to a large value by default (in case it was zeroed in a 253 // previous test). 254 translate::TranslateDownloadManager* download_manager = 255 translate::TranslateDownloadManager::GetInstance(); 256 download_manager->ClearTranslateScriptForTesting(); 257 download_manager->SetTranslateScriptExpirationDelay(60 * 60 * 1000); 258 259 ChromeRenderViewHostTestHarness::SetUp(); 260 InfoBarService::CreateForWebContents(web_contents()); 261 ChromeTranslateClient::CreateForWebContents(web_contents()); 262 ChromeTranslateClient::FromWebContents(web_contents()) 263 ->translate_driver() 264 .set_translate_max_reload_attempts(0); 265 266 notification_registrar_.Add( 267 this, 268 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 269 content::Source<InfoBarService>(infobar_service())); 270 } 271 272 virtual void TearDown() { 273 process()->sink().ClearMessages(); 274 275 notification_registrar_.Remove( 276 this, 277 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 278 content::Source<InfoBarService>(infobar_service())); 279 280 ChromeRenderViewHostTestHarness::TearDown(); 281 TranslateService::ShutdownForTesting(); 282 } 283 284 void SetApplicationLocale(const std::string& locale) { 285 g_browser_process->SetApplicationLocale(locale); 286 translate::TranslateDownloadManager::GetInstance()->set_application_locale( 287 g_browser_process->GetApplicationLocale()); 288 } 289 290 void SimulateTranslateScriptURLFetch(bool success) { 291 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID( 292 translate::TranslateScript::kFetcherId); 293 ASSERT_TRUE(fetcher); 294 net::URLRequestStatus status; 295 status.set_status(success ? net::URLRequestStatus::SUCCESS 296 : net::URLRequestStatus::FAILED); 297 fetcher->set_url(fetcher->GetOriginalURL()); 298 fetcher->set_status(status); 299 fetcher->set_response_code(success ? 200 : 500); 300 fetcher->delegate()->OnURLFetchComplete(fetcher); 301 } 302 303 void SimulateSupportedLanguagesURLFetch( 304 bool success, 305 const std::vector<std::string>& languages, 306 bool use_alpha_languages, 307 const std::vector<std::string>& alpha_languages) { 308 net::URLRequestStatus status; 309 status.set_status(success ? net::URLRequestStatus::SUCCESS 310 : net::URLRequestStatus::FAILED); 311 312 std::string data; 313 if (success) { 314 data = base::StringPrintf( 315 "%s{\"sl\": {\"bla\": \"bla\"}, \"%s\": {", 316 translate::TranslateLanguageList::kLanguageListCallbackName, 317 translate::TranslateLanguageList::kTargetLanguagesKey); 318 const char* comma = ""; 319 for (size_t i = 0; i < languages.size(); ++i) { 320 data += base::StringPrintf( 321 "%s\"%s\": \"UnusedFullName\"", comma, languages[i].c_str()); 322 if (i == 0) 323 comma = ","; 324 } 325 326 if (use_alpha_languages) { 327 data += base::StringPrintf( 328 "},\"%s\": {", 329 translate::TranslateLanguageList::kAlphaLanguagesKey); 330 comma = ""; 331 for (size_t i = 0; i < alpha_languages.size(); ++i) { 332 data += base::StringPrintf( 333 "%s\"%s\": 1", comma, alpha_languages[i].c_str()); 334 if (i == 0) 335 comma = ","; 336 } 337 } 338 339 data += "}})"; 340 } 341 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID( 342 translate::TranslateLanguageList::kFetcherId); 343 ASSERT_TRUE(fetcher != NULL); 344 fetcher->set_url(fetcher->GetOriginalURL()); 345 fetcher->set_status(status); 346 fetcher->set_response_code(success ? 200 : 500); 347 fetcher->SetResponseString(data); 348 fetcher->delegate()->OnURLFetchComplete(fetcher); 349 } 350 351 void SetPrefObserverExpectation(const char* path) { 352 EXPECT_CALL(*this, OnPreferenceChanged(std::string(path))); 353 } 354 355 PrefChangeRegistrar::NamedChangeCallback pref_callback_; 356 357 private: 358 content::NotificationRegistrar notification_registrar_; 359 net::TestURLFetcherFactory url_fetcher_factory_; 360 361 // The infobars that have been removed. 362 // WARNING: the pointers point to deleted objects, use only for comparison. 363 std::set<infobars::InfoBarDelegate*> removed_infobars_; 364 365 DISALLOW_COPY_AND_ASSIGN(TranslateManagerRenderViewHostTest); 366 }; 367 368 class MockTranslateBubbleFactory : public TranslateBubbleFactory { 369 public: 370 MockTranslateBubbleFactory() {} 371 372 virtual void ShowImplementation( 373 BrowserWindow* window, 374 content::WebContents* web_contents, 375 translate::TranslateStep step, 376 translate::TranslateErrors::Type error_type) OVERRIDE { 377 if (model_) { 378 model_->SetViewState( 379 TranslateBubbleModelImpl::TranslateStepToViewState(step)); 380 return; 381 } 382 383 ChromeTranslateClient* chrome_translate_client = 384 ChromeTranslateClient::FromWebContents(web_contents); 385 std::string source_language = 386 chrome_translate_client->GetLanguageState().original_language(); 387 std::string target_language = 388 translate::TranslateDownloadManager::GetLanguageCode( 389 g_browser_process->GetApplicationLocale()); 390 391 scoped_ptr<translate::TranslateUIDelegate> ui_delegate( 392 new translate::TranslateUIDelegate( 393 chrome_translate_client->GetTranslateManager()->GetWeakPtr(), 394 source_language, 395 target_language)); 396 model_.reset(new TranslateBubbleModelImpl(step, ui_delegate.Pass())); 397 } 398 399 TranslateBubbleModel* model() { return model_.get(); } 400 401 private: 402 scoped_ptr<TranslateBubbleModel> model_; 403 404 DISALLOW_COPY_AND_ASSIGN(MockTranslateBubbleFactory); 405 }; 406 407 408 TEST_F(TranslateManagerRenderViewHostTest, NormalTranslate) { 409 // See BubbleNormalTranslate for corresponding bubble UX testing. 410 if (TranslateService::IsTranslateBubbleEnabled()) 411 return; 412 413 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 414 415 // We should have an infobar. 416 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 417 ASSERT_TRUE(infobar != NULL); 418 EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, 419 infobar->translate_step()); 420 421 // Simulate clicking translate. 422 process()->sink().ClearMessages(); 423 infobar->Translate(); 424 425 // The "Translating..." infobar should be showing. 426 infobar = GetTranslateInfoBar(); 427 ASSERT_TRUE(infobar != NULL); 428 EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATING, infobar->translate_step()); 429 430 // Simulate the translate script being retrieved (it only needs to be done 431 // once in the test as it is cached). 432 SimulateTranslateScriptURLFetch(true); 433 434 // Test that we sent the right message to the renderer. 435 std::string original_lang, target_lang; 436 EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); 437 EXPECT_EQ("fr", original_lang); 438 EXPECT_EQ("en", target_lang); 439 440 // Simulate the render notifying the translation has been done. 441 SimulateOnPageTranslated("fr", "en"); 442 443 // The after translate infobar should be showing. 444 infobar = GetTranslateInfoBar(); 445 ASSERT_TRUE(infobar != NULL); 446 EXPECT_EQ(translate::TRANSLATE_STEP_AFTER_TRANSLATE, 447 infobar->translate_step()); 448 449 // Simulate changing the original language and translating. 450 process()->sink().ClearMessages(); 451 std::string new_original_lang = infobar->language_code_at(0); 452 infobar->UpdateOriginalLanguageIndex(0); 453 infobar->Translate(); 454 EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); 455 EXPECT_EQ(new_original_lang, original_lang); 456 EXPECT_EQ("en", target_lang); 457 // Simulate the render notifying the translation has been done. 458 SimulateOnPageTranslated(new_original_lang, "en"); 459 infobar = GetTranslateInfoBar(); 460 ASSERT_TRUE(infobar != NULL); 461 462 // Simulate changing the target language and translating. 463 process()->sink().ClearMessages(); 464 std::string new_target_lang = infobar->language_code_at(1); 465 infobar->UpdateTargetLanguageIndex(1); 466 infobar->Translate(); 467 EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); 468 EXPECT_EQ(new_original_lang, original_lang); 469 EXPECT_EQ(new_target_lang, target_lang); 470 // Simulate the render notifying the translation has been done. 471 SimulateOnPageTranslated(new_original_lang, new_target_lang); 472 infobar = GetTranslateInfoBar(); 473 ASSERT_TRUE(infobar != NULL); 474 EXPECT_EQ(new_target_lang, infobar->target_language_code()); 475 476 // Reloading should trigger translation iff Always Translate is on. 477 ReloadAndWait(true); 478 infobar = GetTranslateInfoBar(); 479 ASSERT_TRUE(infobar != NULL); 480 EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, 481 infobar->translate_step()); 482 infobar->UpdateTargetLanguageIndex(1); 483 infobar->ToggleAlwaysTranslate(); 484 ReloadAndWait(true); 485 infobar = GetTranslateInfoBar(); 486 ASSERT_TRUE(infobar != NULL); 487 EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATING, infobar->translate_step()); 488 EXPECT_EQ(new_target_lang, infobar->target_language_code()); 489 } 490 491 TEST_F(TranslateManagerRenderViewHostTest, TranslateScriptNotAvailable) { 492 // See BubbleTranslateScriptNotAvailable for corresponding bubble UX testing. 493 if (TranslateService::IsTranslateBubbleEnabled()) 494 return; 495 496 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 497 498 // We should have an infobar. 499 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 500 ASSERT_TRUE(infobar != NULL); 501 EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, 502 infobar->translate_step()); 503 504 // Simulate clicking translate. 505 process()->sink().ClearMessages(); 506 infobar->Translate(); 507 SimulateTranslateScriptURLFetch(false); 508 509 // We should not have sent any message to translate to the renderer. 510 EXPECT_FALSE(GetTranslateMessage(NULL, NULL)); 511 512 // And we should have an error infobar showing. 513 infobar = GetTranslateInfoBar(); 514 ASSERT_TRUE(infobar != NULL); 515 EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATE_ERROR, 516 infobar->translate_step()); 517 } 518 519 // Ensures we deal correctly with pages for which the browser does not recognize 520 // the language (the translate server may or not detect the language). 521 TEST_F(TranslateManagerRenderViewHostTest, TranslateUnknownLanguage) { 522 // See BubbleUnknownLanguage for corresponding bubble UX testing. 523 if (TranslateService::IsTranslateBubbleEnabled()) 524 return; 525 526 // Simulate navigating to a page ("und" is the string returned by the CLD for 527 // languages it does not recognize). 528 SimulateNavigation(GURL("http://www.google.mys"), "und", true); 529 530 // We should not have an infobar as we don't know the language. 531 ASSERT_TRUE(GetTranslateInfoBar() == NULL); 532 533 // Translate the page anyway throught the context menu. 534 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); 535 menu->Init(); 536 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 537 538 // To test that bug #49018 if fixed, make sure we deal correctly with errors. 539 // Simulate a failure to fetch the translate script. 540 SimulateTranslateScriptURLFetch(false); 541 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 542 ASSERT_TRUE(infobar != NULL); 543 EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATE_ERROR, 544 infobar->translate_step()); 545 EXPECT_TRUE(infobar->is_error()); 546 infobar->MessageInfoBarButtonPressed(); 547 SimulateTranslateScriptURLFetch(true); // This time succeed. 548 549 // Simulate the render notifying the translation has been done, the server 550 // having detected the page was in a known and supported language. 551 SimulateOnPageTranslated("fr", "en"); 552 553 // The after translate infobar should be showing. 554 infobar = GetTranslateInfoBar(); 555 ASSERT_TRUE(infobar != NULL); 556 EXPECT_EQ(translate::TRANSLATE_STEP_AFTER_TRANSLATE, 557 infobar->translate_step()); 558 EXPECT_EQ("fr", infobar->original_language_code()); 559 EXPECT_EQ("en", infobar->target_language_code()); 560 561 // Let's run the same steps but this time the server detects the page is 562 // already in English. 563 SimulateNavigation(GURL("http://www.google.com"), "und", true); 564 menu.reset(CreateContextMenu()); 565 menu->Init(); 566 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 567 SimulateOnPageTranslated( 568 1, "en", "en", translate::TranslateErrors::IDENTICAL_LANGUAGES); 569 infobar = GetTranslateInfoBar(); 570 ASSERT_TRUE(infobar != NULL); 571 EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATE_ERROR, 572 infobar->translate_step()); 573 EXPECT_EQ(translate::TranslateErrors::IDENTICAL_LANGUAGES, 574 infobar->error_type()); 575 576 // Let's run the same steps again but this time the server fails to detect the 577 // page's language (it returns an empty string). 578 SimulateNavigation(GURL("http://www.google.com"), "und", true); 579 menu.reset(CreateContextMenu()); 580 menu->Init(); 581 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 582 SimulateOnPageTranslated( 583 2, std::string(), "en", translate::TranslateErrors::UNKNOWN_LANGUAGE); 584 infobar = GetTranslateInfoBar(); 585 ASSERT_TRUE(infobar != NULL); 586 EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATE_ERROR, 587 infobar->translate_step()); 588 EXPECT_EQ(translate::TranslateErrors::UNKNOWN_LANGUAGE, 589 infobar->error_type()); 590 } 591 592 // Tests that we show/don't show an info-bar for the languages. 593 TEST_F(TranslateManagerRenderViewHostTest, TestLanguages) { 594 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 595 if (TranslateService::IsTranslateBubbleEnabled()) 596 return; 597 598 std::vector<std::string> languages; 599 languages.push_back("en"); 600 languages.push_back("ja"); 601 languages.push_back("fr"); 602 languages.push_back("ht"); 603 languages.push_back("xx"); 604 languages.push_back("zh"); 605 languages.push_back("zh-CN"); 606 languages.push_back("und"); 607 608 GURL url("http://www.google.com"); 609 for (size_t i = 0; i < languages.size(); ++i) { 610 std::string lang = languages[i]; 611 SCOPED_TRACE(::testing::Message() << "Iteration " << i 612 << " language=" << lang); 613 614 // We should not have a translate infobar. 615 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 616 ASSERT_TRUE(infobar == NULL); 617 618 SimulateNavigation(url, lang, true); 619 620 // Verify we have/don't have an info-bar as expected. 621 infobar = GetTranslateInfoBar(); 622 bool expected = 623 translate::TranslateDownloadManager::IsSupportedLanguage(lang) && 624 lang != "en"; 625 EXPECT_EQ(expected, infobar != NULL); 626 627 if (infobar != NULL) 628 EXPECT_TRUE(CloseTranslateInfoBar()); 629 } 630 } 631 632 // A list of languages to fake being returned by the translate server. 633 // Use only langauges for which Chrome's copy of ICU has 634 // display names in English locale. To save space, Chrome's copy of ICU 635 // does not have the display name for a language unless it's in the 636 // Accept-Language list. 637 static const char* server_language_list[] = 638 {"ach", "ak", "af", "en-CA", "zh", "yi", "fr-FR", "tl", "iw", "in", "xx"}; 639 static const char* alpha_language_list[] = {"ach", "yi"}; 640 641 // Test the fetching of languages from the translate server 642 TEST_F(TranslateManagerRenderViewHostTest, FetchLanguagesFromTranslateServer) { 643 std::vector<std::string> server_languages; 644 for (size_t i = 0; i < arraysize(server_language_list); ++i) 645 server_languages.push_back(server_language_list[i]); 646 647 std::vector<std::string> alpha_languages; 648 for (size_t i = 0; i < arraysize(alpha_language_list); ++i) 649 alpha_languages.push_back(alpha_language_list[i]); 650 651 // First, get the default languages list. Note that calling 652 // GetSupportedLanguages() invokes RequestLanguageList() internally. 653 std::vector<std::string> default_supported_languages; 654 translate::TranslateDownloadManager::GetSupportedLanguages( 655 &default_supported_languages); 656 // To make sure we got the defaults and don't confuse them with the mocks. 657 ASSERT_NE(default_supported_languages.size(), server_languages.size()); 658 659 // Check that we still get the defaults until the URLFetch has completed. 660 std::vector<std::string> current_supported_languages; 661 translate::TranslateDownloadManager::GetSupportedLanguages( 662 ¤t_supported_languages); 663 EXPECT_EQ(default_supported_languages, current_supported_languages); 664 665 // Also check that it didn't change if we failed the URL fetch. 666 SimulateSupportedLanguagesURLFetch( 667 false, std::vector<std::string>(), true, std::vector<std::string>()); 668 current_supported_languages.clear(); 669 translate::TranslateDownloadManager::GetSupportedLanguages( 670 ¤t_supported_languages); 671 EXPECT_EQ(default_supported_languages, current_supported_languages); 672 673 // Now check that we got the appropriate set of languages from the server. 674 SimulateSupportedLanguagesURLFetch( 675 true, server_languages, true, alpha_languages); 676 current_supported_languages.clear(); 677 translate::TranslateDownloadManager::GetSupportedLanguages( 678 ¤t_supported_languages); 679 // "xx" can't be displayed in the Translate infobar, so this is eliminated. 680 EXPECT_EQ(server_languages.size() - 1, current_supported_languages.size()); 681 // Not sure we need to guarantee the order of languages, so we find them. 682 for (size_t i = 0; i < server_languages.size(); ++i) { 683 const std::string& lang = server_languages[i]; 684 if (lang == "xx") 685 continue; 686 EXPECT_NE(current_supported_languages.end(), 687 std::find(current_supported_languages.begin(), 688 current_supported_languages.end(), 689 lang)) << "lang=" << lang; 690 bool is_alpha = 691 std::find(alpha_languages.begin(), alpha_languages.end(), lang) != 692 alpha_languages.end(); 693 EXPECT_EQ(translate::TranslateDownloadManager::IsAlphaLanguage(lang), 694 is_alpha) 695 << "lang=" << lang; 696 } 697 } 698 699 // Test the fetching of languages from the translate server without 'al' 700 // parameter. 701 TEST_F(TranslateManagerRenderViewHostTest, 702 FetchLanguagesFromTranslateServerWithoutAlpha) { 703 std::vector<std::string> server_languages; 704 for (size_t i = 0; i < arraysize(server_language_list); ++i) 705 server_languages.push_back(server_language_list[i]); 706 707 std::vector<std::string> alpha_languages; 708 for (size_t i = 0; i < arraysize(alpha_language_list); ++i) 709 alpha_languages.push_back(alpha_language_list[i]); 710 711 // call GetSupportedLanguages to call RequestLanguageList internally. 712 std::vector<std::string> default_supported_languages; 713 translate::TranslateDownloadManager::GetSupportedLanguages( 714 &default_supported_languages); 715 716 SimulateSupportedLanguagesURLFetch( 717 true, server_languages, false, alpha_languages); 718 719 std::vector<std::string> current_supported_languages; 720 translate::TranslateDownloadManager::GetSupportedLanguages( 721 ¤t_supported_languages); 722 723 // "xx" can't be displayed in the Translate infobar, so this is eliminated. 724 EXPECT_EQ(server_languages.size() - 1, current_supported_languages.size()); 725 726 for (size_t i = 0; i < server_languages.size(); ++i) { 727 const std::string& lang = server_languages[i]; 728 if (lang == "xx") 729 continue; 730 EXPECT_NE(current_supported_languages.end(), 731 std::find(current_supported_languages.begin(), 732 current_supported_languages.end(), 733 lang)) << "lang=" << lang; 734 EXPECT_FALSE(translate::TranslateDownloadManager::IsAlphaLanguage(lang)) 735 << "lang=" << lang; 736 } 737 } 738 739 // Tests auto-translate on page. 740 TEST_F(TranslateManagerRenderViewHostTest, AutoTranslateOnNavigate) { 741 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 742 if (TranslateService::IsTranslateBubbleEnabled()) 743 return; 744 745 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 746 747 // Simulate the user translating. 748 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 749 ASSERT_TRUE(infobar != NULL); 750 infobar->Translate(); 751 // Simulate the translate script being retrieved. 752 SimulateTranslateScriptURLFetch(true); 753 SimulateOnPageTranslated("fr", "en"); 754 755 // Now navigate to a new page in the same language. 756 process()->sink().ClearMessages(); 757 SimulateNavigation(GURL("http://news.google.fr"), "fr", true); 758 759 // This should have automatically triggered a translation. 760 std::string original_lang, target_lang; 761 EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); 762 EXPECT_EQ("fr", original_lang); 763 EXPECT_EQ("en", target_lang); 764 765 // Now navigate to a page in a different language. 766 process()->sink().ClearMessages(); 767 SimulateNavigation(GURL("http://news.google.es"), "es", true); 768 769 // This should not have triggered a translate. 770 EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); 771 } 772 773 // Tests that multiple OnPageContents do not cause multiple infobars. 774 TEST_F(TranslateManagerRenderViewHostTest, MultipleOnPageContents) { 775 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 776 if (TranslateService::IsTranslateBubbleEnabled()) 777 return; 778 779 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 780 781 // Simulate clicking 'Nope' (don't translate). 782 EXPECT_TRUE(DenyTranslation()); 783 EXPECT_EQ(0U, infobar_service()->infobar_count()); 784 785 // Send a new PageContents, we should not show an infobar. 786 SimulateOnTranslateLanguageDetermined("fr", true); 787 EXPECT_EQ(0U, infobar_service()->infobar_count()); 788 789 // Do the same steps but simulate closing the infobar this time. 790 SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true); 791 EXPECT_TRUE(CloseTranslateInfoBar()); 792 EXPECT_EQ(0U, infobar_service()->infobar_count()); 793 SimulateOnTranslateLanguageDetermined("fr", true); 794 EXPECT_EQ(0U, infobar_service()->infobar_count()); 795 } 796 797 // Test that reloading the page brings back the infobar if the 798 // reload succeeded and does not bring it back the reload fails. 799 TEST_F(TranslateManagerRenderViewHostTest, Reload) { 800 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 801 if (TranslateService::IsTranslateBubbleEnabled()) 802 return; 803 804 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 805 806 EXPECT_TRUE(CloseTranslateInfoBar()); 807 808 // Reload should bring back the infobar if the reload succeeds. 809 ReloadAndWait(true); 810 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 811 EXPECT_TRUE(CloseTranslateInfoBar()); 812 813 // ...But not show it if the reload fails. 814 ReloadAndWait(false); 815 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 816 817 // If we set reload attempts to a high value, we will not see the infobar 818 // immediately. 819 ChromeTranslateClient::FromWebContents(web_contents()) 820 ->translate_driver() 821 .set_translate_max_reload_attempts(100); 822 ReloadAndWait(true); 823 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 824 } 825 826 // Test that reloading the page by way of typing again the URL in the 827 // location bar brings back the infobar. 828 TEST_F(TranslateManagerRenderViewHostTest, ReloadFromLocationBar) { 829 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 830 if (TranslateService::IsTranslateBubbleEnabled()) 831 return; 832 833 GURL url("http://www.google.fr"); 834 SimulateNavigation(url, "fr", true); 835 836 EXPECT_TRUE(CloseTranslateInfoBar()); 837 838 // Create a pending navigation and simulate a page load. That should be the 839 // equivalent of typing the URL again in the location bar. 840 NavEntryCommittedObserver nav_observer(web_contents()); 841 web_contents()->GetController().LoadURL( 842 url, content::Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); 843 rvh_tester()->SendNavigateWithTransition( 844 0, url, ui::PAGE_TRANSITION_TYPED); 845 846 // Test that we are really getting a same page navigation, the test would be 847 // useless if it was not the case. 848 const content::LoadCommittedDetails& nav_details = 849 nav_observer.load_committed_details(); 850 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation. 851 EXPECT_EQ(content::NAVIGATION_TYPE_SAME_PAGE, nav_details.type); 852 853 // The TranslateManager class processes the navigation entry committed 854 // notification in a posted task; process that task. 855 base::MessageLoop::current()->RunUntilIdle(); 856 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 857 } 858 859 // Tests that a closed translate infobar does not reappear when navigating 860 // in-page. 861 TEST_F(TranslateManagerRenderViewHostTest, CloseInfoBarInPageNavigation) { 862 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 863 if (TranslateService::IsTranslateBubbleEnabled()) 864 return; 865 866 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 867 868 EXPECT_TRUE(CloseTranslateInfoBar()); 869 870 // Navigate in page, no infobar should be shown. 871 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); 872 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 873 874 // Navigate out of page, a new infobar should show. 875 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); 876 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 877 } 878 879 // Tests that a closed translate infobar does not reappear when navigating 880 // in a subframe. (http://crbug.com/48215) 881 TEST_F(TranslateManagerRenderViewHostTest, CloseInfoBarInSubframeNavigation) { 882 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 883 if (TranslateService::IsTranslateBubbleEnabled()) 884 return; 885 886 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 887 888 EXPECT_TRUE(CloseTranslateInfoBar()); 889 890 content::RenderFrameHostTester* subframe_tester = 891 content::RenderFrameHostTester::For( 892 content::RenderFrameHostTester::For(main_rfh()) 893 ->AppendChild("subframe")); 894 895 // Simulate a sub-frame auto-navigating. 896 subframe_tester->SendNavigateWithTransition( 897 1, GURL("http://pub.com"), ui::PAGE_TRANSITION_AUTO_SUBFRAME); 898 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 899 900 // Simulate the user navigating in a sub-frame. 901 subframe_tester->SendNavigateWithTransition( 902 2, GURL("http://pub.com"), ui::PAGE_TRANSITION_MANUAL_SUBFRAME); 903 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 904 905 // Navigate out of page, a new infobar should show. 906 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); 907 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 908 } 909 910 // Tests that denying translation is sticky when navigating in page. 911 TEST_F(TranslateManagerRenderViewHostTest, DenyTranslateInPageNavigation) { 912 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 913 if (TranslateService::IsTranslateBubbleEnabled()) 914 return; 915 916 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 917 918 // Simulate clicking 'Nope' (don't translate). 919 EXPECT_TRUE(DenyTranslation()); 920 921 // Navigate in page, no infobar should be shown. 922 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); 923 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 924 925 // Navigate out of page, a new infobar should show. 926 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); 927 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 928 } 929 930 // Tests that after translating and closing the infobar, the infobar does not 931 // return when navigating in page. 932 TEST_F(TranslateManagerRenderViewHostTest, 933 TranslateCloseInfoBarInPageNavigation) { 934 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 935 if (TranslateService::IsTranslateBubbleEnabled()) 936 return; 937 938 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 939 940 // Simulate the user translating. 941 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 942 ASSERT_TRUE(infobar != NULL); 943 infobar->Translate(); 944 // Simulate the translate script being retrieved. 945 SimulateTranslateScriptURLFetch(true); 946 SimulateOnPageTranslated("fr", "en"); 947 948 EXPECT_TRUE(CloseTranslateInfoBar()); 949 950 // Navigate in page, no infobar should be shown. 951 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); 952 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 953 954 // Navigate out of page, a new infobar should show. 955 // Note that we navigate to a page in a different language so we don't trigger 956 // the auto-translate feature (it would translate the page automatically and 957 // the before translate infobar would not be shown). 958 SimulateNavigation(GURL("http://www.google.de"), "de", true); 959 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 960 } 961 962 // Tests that the after translate the infobar still shows when navigating 963 // in-page. 964 TEST_F(TranslateManagerRenderViewHostTest, TranslateInPageNavigation) { 965 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 966 if (TranslateService::IsTranslateBubbleEnabled()) 967 return; 968 969 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 970 971 // Simulate the user translating. 972 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 973 ASSERT_TRUE(infobar != NULL); 974 infobar->Translate(); 975 SimulateTranslateScriptURLFetch(true); 976 SimulateOnPageTranslated("fr", "en"); 977 // The after translate infobar is showing. 978 infobar = GetTranslateInfoBar(); 979 ASSERT_TRUE(infobar != NULL); 980 981 // Navigate out of page, a new infobar should show. 982 // See note in TranslateCloseInfoBarInPageNavigation test on why it is 983 // important to navigate to a page in a different language for this test. 984 SimulateNavigation(GURL("http://www.google.de"), "de", true); 985 // The old infobar is gone. 986 EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar)); 987 // And there is a new one. 988 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 989 } 990 991 // Tests that no translate infobar is shown when navigating to a page in an 992 // unsupported language. 993 TEST_F(TranslateManagerRenderViewHostTest, CLDReportsUnsupportedPageLanguage) { 994 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 995 if (TranslateService::IsTranslateBubbleEnabled()) 996 return; 997 998 // Simulate navigating to a page and getting an unsupported language. 999 SimulateNavigation(GURL("http://www.google.com"), "qbz", true); 1000 1001 // No info-bar should be shown. 1002 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 1003 } 1004 1005 // Tests that we deal correctly with unsupported languages returned by the 1006 // server. 1007 // The translation server might return a language we don't support. 1008 TEST_F(TranslateManagerRenderViewHostTest, ServerReportsUnsupportedLanguage) { 1009 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1010 if (TranslateService::IsTranslateBubbleEnabled()) 1011 return; 1012 1013 SimulateNavigation(GURL("http://mail.google.fr"), "fr", true); 1014 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1015 ASSERT_TRUE(infobar != NULL); 1016 process()->sink().ClearMessages(); 1017 infobar->Translate(); 1018 SimulateTranslateScriptURLFetch(true); 1019 // Simulate the render notifying the translation has been done, but it 1020 // reports a language we don't support. 1021 SimulateOnPageTranslated("qbz", "en"); 1022 1023 // An error infobar should be showing to report that we don't support this 1024 // language. 1025 infobar = GetTranslateInfoBar(); 1026 ASSERT_TRUE(infobar != NULL); 1027 EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATE_ERROR, 1028 infobar->translate_step()); 1029 1030 // This infobar should have a button (so the string should not be empty). 1031 ASSERT_FALSE(infobar->GetMessageInfoBarButtonText().empty()); 1032 1033 // Pressing the button on that infobar should revert to the original language. 1034 process()->sink().ClearMessages(); 1035 infobar->MessageInfoBarButtonPressed(); 1036 const IPC::Message* message = process()->sink().GetFirstMessageMatching( 1037 ChromeViewMsg_RevertTranslation::ID); 1038 EXPECT_TRUE(message != NULL); 1039 // And it should have removed the infobar. 1040 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 1041 } 1042 1043 // Tests that no translate infobar is shown and context menu is disabled, when 1044 // Chrome is in a language that the translate server does not support. 1045 TEST_F(TranslateManagerRenderViewHostTest, UnsupportedUILanguage) { 1046 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1047 if (TranslateService::IsTranslateBubbleEnabled()) 1048 return; 1049 1050 std::string original_lang = g_browser_process->GetApplicationLocale(); 1051 SetApplicationLocale("qbz"); 1052 1053 // Make sure that the accept language list only contains unsupported languages 1054 Profile* profile = 1055 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1056 PrefService* prefs = profile->GetPrefs(); 1057 prefs->SetString(prefs::kAcceptLanguages, "qbz"); 1058 1059 // Simulate navigating to a page in a language supported by the translate 1060 // server. 1061 SimulateNavigation(GURL("http://www.google.com"), "en", true); 1062 1063 // No info-bar should be shown. 1064 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 1065 1066 // And the context menu option should be disabled too. 1067 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); 1068 menu->Init(); 1069 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1070 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1071 1072 SetApplicationLocale(original_lang); 1073 } 1074 1075 // Tests that the first supported accept language is selected 1076 TEST_F(TranslateManagerRenderViewHostTest, TranslateAcceptLanguage) { 1077 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1078 if (TranslateService::IsTranslateBubbleEnabled()) 1079 return; 1080 1081 // Set locate to non-existant language 1082 std::string original_lang = g_browser_process->GetApplicationLocale(); 1083 SetApplicationLocale("qbz"); 1084 1085 // Set Qbz and French as the only accepted languages 1086 Profile* profile = 1087 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1088 PrefService* prefs = profile->GetPrefs(); 1089 prefs->SetString(prefs::kAcceptLanguages, "qbz,fr"); 1090 1091 // Go to a German page 1092 SimulateNavigation(GURL("http://google.de"), "de", true); 1093 1094 // Expect the infobar to pop up 1095 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1096 1097 // Set Qbz and English-US as the only accepted languages to test the country 1098 // code removal code which was causing a crash as filed in Issue 90106, 1099 // a crash caused by a language with a country code that wasn't recognized. 1100 prefs->SetString(prefs::kAcceptLanguages, "qbz,en-us"); 1101 1102 // Go to a German page 1103 SimulateNavigation(GURL("http://google.de"), "de", true); 1104 1105 // Expect the infobar to pop up 1106 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1107 } 1108 1109 // Tests that the translate enabled preference is honored. 1110 TEST_F(TranslateManagerRenderViewHostTest, TranslateEnabledPref) { 1111 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1112 if (TranslateService::IsTranslateBubbleEnabled()) 1113 return; 1114 1115 // Make sure the pref allows translate. 1116 Profile* profile = 1117 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1118 PrefService* prefs = profile->GetPrefs(); 1119 prefs->SetBoolean(prefs::kEnableTranslate, true); 1120 1121 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1122 1123 // An infobar should be shown. 1124 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1125 EXPECT_TRUE(infobar != NULL); 1126 1127 // Disable translate. 1128 prefs->SetBoolean(prefs::kEnableTranslate, false); 1129 1130 // Navigate to a new page, that should close the previous infobar. 1131 GURL url("http://www.youtube.fr"); 1132 NavigateAndCommit(url); 1133 infobar = GetTranslateInfoBar(); 1134 EXPECT_TRUE(infobar == NULL); 1135 1136 // Simulate getting the page contents and language, that should not trigger 1137 // a translate infobar. 1138 SimulateOnTranslateLanguageDetermined("fr", true); 1139 infobar = GetTranslateInfoBar(); 1140 EXPECT_TRUE(infobar == NULL); 1141 } 1142 1143 // Tests the "Never translate <language>" pref. 1144 TEST_F(TranslateManagerRenderViewHostTest, NeverTranslateLanguagePref) { 1145 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1146 if (TranslateService::IsTranslateBubbleEnabled()) 1147 return; 1148 1149 GURL url("http://www.google.fr"); 1150 SimulateNavigation(url, "fr", true); 1151 1152 // An infobar should be shown. 1153 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1154 1155 // Select never translate this language. 1156 Profile* profile = 1157 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1158 PrefService* prefs = profile->GetPrefs(); 1159 PrefChangeRegistrar registrar; 1160 registrar.Init(prefs); 1161 registrar.Add(translate::TranslatePrefs::kPrefTranslateBlockedLanguages, 1162 pref_callback_); 1163 scoped_ptr<translate::TranslatePrefs> translate_prefs( 1164 ChromeTranslateClient::CreateTranslatePrefs(prefs)); 1165 EXPECT_FALSE(translate_prefs->IsBlockedLanguage("fr")); 1166 translate::TranslateAcceptLanguages* accept_languages = 1167 ChromeTranslateClient::GetTranslateAcceptLanguages(profile); 1168 EXPECT_TRUE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); 1169 SetPrefObserverExpectation( 1170 translate::TranslatePrefs::kPrefTranslateBlockedLanguages); 1171 translate_prefs->BlockLanguage("fr"); 1172 EXPECT_TRUE(translate_prefs->IsBlockedLanguage("fr")); 1173 EXPECT_FALSE(translate_prefs->IsSiteBlacklisted(url.host())); 1174 EXPECT_FALSE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); 1175 1176 EXPECT_TRUE(CloseTranslateInfoBar()); 1177 1178 // Navigate to a new page also in French. 1179 SimulateNavigation(GURL("http://wwww.youtube.fr"), "fr", true); 1180 1181 // There should not be a translate infobar. 1182 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 1183 1184 // Remove the language from the blacklist. 1185 SetPrefObserverExpectation( 1186 translate::TranslatePrefs::kPrefTranslateBlockedLanguages); 1187 translate_prefs->UnblockLanguage("fr"); 1188 EXPECT_FALSE(translate_prefs->IsBlockedLanguage("fr")); 1189 EXPECT_FALSE(translate_prefs->IsSiteBlacklisted(url.host())); 1190 EXPECT_TRUE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); 1191 1192 // Navigate to a page in French. 1193 SimulateNavigation(url, "fr", true); 1194 1195 // There should be a translate infobar. 1196 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1197 } 1198 1199 // Tests the "Never translate this site" pref. 1200 TEST_F(TranslateManagerRenderViewHostTest, NeverTranslateSitePref) { 1201 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1202 if (TranslateService::IsTranslateBubbleEnabled()) 1203 return; 1204 1205 GURL url("http://www.google.fr"); 1206 std::string host(url.host()); 1207 SimulateNavigation(url, "fr", true); 1208 1209 // An infobar should be shown. 1210 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1211 1212 // Select never translate this site. 1213 Profile* profile = 1214 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1215 PrefService* prefs = profile->GetPrefs(); 1216 PrefChangeRegistrar registrar; 1217 registrar.Init(prefs); 1218 registrar.Add(translate::TranslatePrefs::kPrefTranslateSiteBlacklist, 1219 pref_callback_); 1220 scoped_ptr<translate::TranslatePrefs> translate_prefs( 1221 ChromeTranslateClient::CreateTranslatePrefs(prefs)); 1222 EXPECT_FALSE(translate_prefs->IsSiteBlacklisted(host)); 1223 translate::TranslateAcceptLanguages* accept_languages = 1224 ChromeTranslateClient::GetTranslateAcceptLanguages(profile); 1225 EXPECT_TRUE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); 1226 SetPrefObserverExpectation( 1227 translate::TranslatePrefs::kPrefTranslateSiteBlacklist); 1228 translate_prefs->BlacklistSite(host); 1229 EXPECT_TRUE(translate_prefs->IsSiteBlacklisted(host)); 1230 EXPECT_TRUE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); 1231 1232 EXPECT_TRUE(CloseTranslateInfoBar()); 1233 1234 // Navigate to a new page also on the same site. 1235 SimulateNavigation(GURL("http://www.google.fr/hello"), "fr", true); 1236 1237 // There should not be a translate infobar. 1238 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 1239 1240 // Remove the site from the blacklist. 1241 SetPrefObserverExpectation( 1242 translate::TranslatePrefs::kPrefTranslateSiteBlacklist); 1243 translate_prefs->RemoveSiteFromBlacklist(host); 1244 EXPECT_FALSE(translate_prefs->IsSiteBlacklisted(host)); 1245 EXPECT_TRUE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); 1246 1247 // Navigate to a page in French. 1248 SimulateNavigation(url, "fr", true); 1249 1250 // There should be a translate infobar. 1251 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1252 } 1253 1254 // Tests the "Always translate this language" pref. 1255 TEST_F(TranslateManagerRenderViewHostTest, AlwaysTranslateLanguagePref) { 1256 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1257 if (TranslateService::IsTranslateBubbleEnabled()) 1258 return; 1259 1260 // Select always translate French to English. 1261 Profile* profile = 1262 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1263 PrefService* prefs = profile->GetPrefs(); 1264 PrefChangeRegistrar registrar; 1265 registrar.Init(prefs); 1266 registrar.Add(translate::TranslatePrefs::kPrefTranslateWhitelists, 1267 pref_callback_); 1268 scoped_ptr<translate::TranslatePrefs> translate_prefs( 1269 ChromeTranslateClient::CreateTranslatePrefs(prefs)); 1270 SetPrefObserverExpectation( 1271 translate::TranslatePrefs::kPrefTranslateWhitelists); 1272 translate_prefs->WhitelistLanguagePair("fr", "en"); 1273 1274 // Load a page in French. 1275 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1276 1277 // It should have triggered an automatic translation to English. 1278 1279 // The translating infobar should be showing. 1280 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1281 ASSERT_TRUE(infobar != NULL); 1282 EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATING, infobar->translate_step()); 1283 SimulateTranslateScriptURLFetch(true); 1284 std::string original_lang, target_lang; 1285 EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); 1286 EXPECT_EQ("fr", original_lang); 1287 EXPECT_EQ("en", target_lang); 1288 process()->sink().ClearMessages(); 1289 1290 // Try another language, it should not be autotranslated. 1291 SimulateNavigation(GURL("http://www.google.es"), "es", true); 1292 EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); 1293 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1294 EXPECT_TRUE(CloseTranslateInfoBar()); 1295 1296 // Let's switch to incognito mode, it should not be autotranslated in that 1297 // case either. 1298 TestingProfile* test_profile = 1299 static_cast<TestingProfile*>(web_contents()->GetBrowserContext()); 1300 test_profile->ForceIncognito(true); 1301 SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true); 1302 EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); 1303 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1304 EXPECT_TRUE(CloseTranslateInfoBar()); 1305 test_profile->ForceIncognito(false); // Get back to non incognito. 1306 1307 // Now revert the always translate pref and make sure we go back to expected 1308 // behavior, which is show a "before translate" infobar. 1309 SetPrefObserverExpectation( 1310 translate::TranslatePrefs::kPrefTranslateWhitelists); 1311 translate_prefs->RemoveLanguagePairFromWhitelist("fr", "en"); 1312 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1313 EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); 1314 infobar = GetTranslateInfoBar(); 1315 ASSERT_TRUE(infobar != NULL); 1316 EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, 1317 infobar->translate_step()); 1318 } 1319 1320 // Context menu. 1321 TEST_F(TranslateManagerRenderViewHostTest, ContextMenu) { 1322 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1323 if (TranslateService::IsTranslateBubbleEnabled()) 1324 return; 1325 1326 // Blacklist www.google.fr and French for translation. 1327 GURL url("http://www.google.fr"); 1328 Profile* profile = 1329 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1330 scoped_ptr<translate::TranslatePrefs> translate_prefs( 1331 ChromeTranslateClient::CreateTranslatePrefs(profile->GetPrefs())); 1332 translate_prefs->BlockLanguage("fr"); 1333 translate_prefs->BlacklistSite(url.host()); 1334 EXPECT_TRUE(translate_prefs->IsBlockedLanguage("fr")); 1335 EXPECT_TRUE(translate_prefs->IsSiteBlacklisted(url.host())); 1336 1337 // Simulate navigating to a page in French. The translate menu should show but 1338 // should only be enabled when the page language has been received. 1339 NavigateAndCommit(url); 1340 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); 1341 menu->Init(); 1342 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1343 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1344 1345 // Simulate receiving the language. 1346 SimulateOnTranslateLanguageDetermined("fr", true); 1347 menu.reset(CreateContextMenu()); 1348 menu->Init(); 1349 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1350 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1351 1352 // Use the menu to translate the page. 1353 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 1354 1355 // That should have triggered a translation. 1356 // The "translating..." infobar should be showing. 1357 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1358 ASSERT_TRUE(infobar != NULL); 1359 EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATING, infobar->translate_step()); 1360 SimulateTranslateScriptURLFetch(true); 1361 std::string original_lang, target_lang; 1362 EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); 1363 EXPECT_EQ("fr", original_lang); 1364 EXPECT_EQ("en", target_lang); 1365 process()->sink().ClearMessages(); 1366 1367 // This should also have reverted the blacklisting of this site and language. 1368 EXPECT_FALSE(translate_prefs->IsBlockedLanguage("fr")); 1369 EXPECT_FALSE(translate_prefs->IsSiteBlacklisted(url.host())); 1370 1371 // Let's simulate the page being translated. 1372 SimulateOnPageTranslated("fr", "en"); 1373 1374 // The translate menu should now be disabled. 1375 menu.reset(CreateContextMenu()); 1376 menu->Init(); 1377 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1378 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1379 1380 // Test that selecting translate in the context menu WHILE the page is being 1381 // translated does nothing (this could happen if autotranslate kicks-in and 1382 // the user selects the menu while the translation is being performed). 1383 SimulateNavigation(GURL("http://www.google.es"), "es", true); 1384 infobar = GetTranslateInfoBar(); 1385 ASSERT_TRUE(infobar != NULL); 1386 infobar->Translate(); 1387 EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); 1388 process()->sink().ClearMessages(); 1389 menu.reset(CreateContextMenu()); 1390 menu->Init(); 1391 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1392 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 1393 // No message expected since the translation should have been ignored. 1394 EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); 1395 1396 // Now test that selecting translate in the context menu AFTER the page has 1397 // been translated does nothing. 1398 SimulateNavigation(GURL("http://www.google.de"), "de", true); 1399 infobar = GetTranslateInfoBar(); 1400 ASSERT_TRUE(infobar != NULL); 1401 infobar->Translate(); 1402 EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); 1403 process()->sink().ClearMessages(); 1404 menu.reset(CreateContextMenu()); 1405 menu->Init(); 1406 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1407 SimulateOnPageTranslated("de", "en"); 1408 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 1409 // No message expected since the translation should have been ignored. 1410 EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); 1411 1412 // Test that the translate context menu is enabled when the page is in an 1413 // unknown language. 1414 SimulateNavigation(url, "und", true); 1415 menu.reset(CreateContextMenu()); 1416 menu->Init(); 1417 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1418 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1419 1420 // Test that the translate context menu is enabled even if the page is in an 1421 // unsupported language. 1422 SimulateNavigation(url, "qbz", true); 1423 menu.reset(CreateContextMenu()); 1424 menu->Init(); 1425 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1426 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1427 } 1428 1429 // Tests that an extra always/never translate button is shown on the "before 1430 // translate" infobar when the translation is accepted/declined 3 times, 1431 // only when not in incognito mode. 1432 TEST_F(TranslateManagerRenderViewHostTest, BeforeTranslateExtraButtons) { 1433 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1434 if (TranslateService::IsTranslateBubbleEnabled()) 1435 return; 1436 1437 Profile* profile = 1438 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1439 scoped_ptr<translate::TranslatePrefs> translate_prefs( 1440 ChromeTranslateClient::CreateTranslatePrefs(profile->GetPrefs())); 1441 translate_prefs->ResetTranslationAcceptedCount("fr"); 1442 translate_prefs->ResetTranslationDeniedCount("fr"); 1443 translate_prefs->ResetTranslationAcceptedCount("de"); 1444 translate_prefs->ResetTranslationDeniedCount("de"); 1445 1446 // We'll do 4 times in incognito mode first to make sure the button is not 1447 // shown in that case, then 4 times in normal mode. 1448 translate::TranslateInfoBarDelegate* infobar; 1449 TestingProfile* test_profile = 1450 static_cast<TestingProfile*>(web_contents()->GetBrowserContext()); 1451 static_cast<extensions::TestExtensionSystem*>( 1452 extensions::ExtensionSystem::Get(test_profile))->CreateProcessManager(); 1453 test_profile->ForceIncognito(true); 1454 for (int i = 0; i < 8; ++i) { 1455 SCOPED_TRACE(::testing::Message() << "Iteration " << i << " incognito mode=" 1456 << test_profile->IsOffTheRecord()); 1457 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1458 infobar = GetTranslateInfoBar(); 1459 ASSERT_TRUE(infobar != NULL); 1460 EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, 1461 infobar->translate_step()); 1462 if (i < 7) { 1463 EXPECT_FALSE(infobar->ShouldShowAlwaysTranslateShortcut()); 1464 infobar->Translate(); 1465 process()->sink().ClearMessages(); 1466 } else { 1467 EXPECT_TRUE(infobar->ShouldShowAlwaysTranslateShortcut()); 1468 } 1469 if (i == 3) 1470 test_profile->ForceIncognito(false); 1471 } 1472 // Simulate the user pressing "Always translate French". 1473 infobar->AlwaysTranslatePageLanguage(); 1474 EXPECT_TRUE(translate_prefs->IsLanguagePairWhitelisted("fr", "en")); 1475 // Simulate the translate script being retrieved (it only needs to be done 1476 // once in the test as it is cached). 1477 SimulateTranslateScriptURLFetch(true); 1478 // That should have triggered a page translate. 1479 std::string original_lang, target_lang; 1480 EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); 1481 process()->sink().ClearMessages(); 1482 1483 // Now test that declining the translation causes a "never translate" button 1484 // to be shown (in non incognito mode only). 1485 test_profile->ForceIncognito(true); 1486 for (int i = 0; i < 8; ++i) { 1487 SCOPED_TRACE(::testing::Message() << "Iteration " << i << " incognito mode=" 1488 << test_profile->IsOffTheRecord()); 1489 SimulateNavigation(GURL("http://www.google.de"), "de", true); 1490 infobar = GetTranslateInfoBar(); 1491 ASSERT_TRUE(infobar != NULL); 1492 EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, 1493 infobar->translate_step()); 1494 if (i < 7) { 1495 EXPECT_FALSE(infobar->ShouldShowNeverTranslateShortcut()); 1496 infobar->TranslationDeclined(); 1497 } else { 1498 EXPECT_TRUE(infobar->ShouldShowNeverTranslateShortcut()); 1499 } 1500 if (i == 3) 1501 test_profile->ForceIncognito(false); 1502 } 1503 // Simulate the user pressing "Never translate French". 1504 infobar->NeverTranslatePageLanguage(); 1505 EXPECT_TRUE(translate_prefs->IsBlockedLanguage("de")); 1506 // No translation should have occured and the infobar should be gone. 1507 EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); 1508 process()->sink().ClearMessages(); 1509 ASSERT_TRUE(GetTranslateInfoBar() == NULL); 1510 } 1511 1512 // Tests that we don't show a translate infobar when a page instructs that it 1513 // should not be translated. 1514 TEST_F(TranslateManagerRenderViewHostTest, NonTranslatablePage) { 1515 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1516 if (TranslateService::IsTranslateBubbleEnabled()) 1517 return; 1518 1519 SimulateNavigation(GURL("http://mail.google.fr"), "fr", false); 1520 1521 // We should not have an infobar. 1522 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 1523 1524 // The context menu is enabled to allow users to force translation. 1525 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); 1526 menu->Init(); 1527 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1528 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1529 } 1530 1531 // Tests that the script is expired and refetched as expected. 1532 TEST_F(TranslateManagerRenderViewHostTest, ScriptExpires) { 1533 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 1534 if (TranslateService::IsTranslateBubbleEnabled()) 1535 return; 1536 1537 ExpireTranslateScriptImmediately(); 1538 1539 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1540 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1541 ASSERT_TRUE(infobar != NULL); 1542 process()->sink().ClearMessages(); 1543 infobar->Translate(); 1544 SimulateTranslateScriptURLFetch(true); 1545 SimulateOnPageTranslated("fr", "en"); 1546 1547 // A task should have been posted to clear the script, run it. 1548 base::MessageLoop::current()->RunUntilIdle(); 1549 1550 // Do another navigation and translation. 1551 SimulateNavigation(GURL("http://www.google.es"), "es", true); 1552 infobar = GetTranslateInfoBar(); 1553 ASSERT_TRUE(infobar != NULL); 1554 process()->sink().ClearMessages(); 1555 infobar->Translate(); 1556 // If we don't simulate the URL fetch, the TranslateManager should be waiting 1557 // for the script and no message should have been sent to the renderer. 1558 EXPECT_TRUE(process()->sink().GetFirstMessageMatching( 1559 ChromeViewMsg_TranslatePage::ID) == NULL); 1560 // Now simulate the URL fetch. 1561 SimulateTranslateScriptURLFetch(true); 1562 // Now the message should have been sent. 1563 std::string original_lang, target_lang; 1564 EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); 1565 EXPECT_EQ("es", original_lang); 1566 EXPECT_EQ("en", target_lang); 1567 } 1568 1569 TEST_F(TranslateManagerRenderViewHostTest, DownloadsAndHistoryNotTranslated) { 1570 ASSERT_FALSE( 1571 TranslateService::IsTranslatableURL(GURL(chrome::kChromeUIDownloadsURL))); 1572 ASSERT_FALSE( 1573 TranslateService::IsTranslatableURL(GURL(chrome::kChromeUIHistoryURL))); 1574 } 1575 1576 TEST_F(TranslateManagerRenderViewHostTest, BubbleNormalTranslate) { 1577 // See NormalTranslate for corresponding infobar UX testing. 1578 if (!TranslateService::IsTranslateBubbleEnabled()) 1579 return; 1580 1581 MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; 1582 scoped_ptr<TranslateBubbleFactory> factory_ptr(factory); 1583 TranslateBubbleFactory::SetFactory(factory); 1584 1585 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1586 1587 // Check the bubble exists instead of the infobar. 1588 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1589 ASSERT_TRUE(infobar == NULL); 1590 TranslateBubbleModel* bubble = factory->model(); 1591 ASSERT_TRUE(bubble != NULL); 1592 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE, 1593 bubble->GetViewState()); 1594 1595 // Simulate clicking translate. 1596 process()->sink().ClearMessages(); 1597 bubble->Translate(); 1598 1599 // Check the bubble shows "Translating...". 1600 bubble = factory->model(); 1601 ASSERT_TRUE(bubble != NULL); 1602 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_TRANSLATING, 1603 bubble->GetViewState()); 1604 1605 // Simulate the translate script being retrieved (it only needs to be done 1606 // once in the test as it is cached). 1607 SimulateTranslateScriptURLFetch(true); 1608 1609 // Simulate the render notifying the translation has been done. 1610 SimulateOnPageTranslated("fr", "en"); 1611 1612 // Check the bubble shows "Translated." 1613 bubble = factory->model(); 1614 ASSERT_TRUE(bubble != NULL); 1615 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE, 1616 bubble->GetViewState()); 1617 } 1618 1619 TEST_F(TranslateManagerRenderViewHostTest, BubbleTranslateScriptNotAvailable) { 1620 // See TranslateScriptNotAvailable for corresponding infobar UX testing. 1621 if (!TranslateService::IsTranslateBubbleEnabled()) 1622 return; 1623 1624 MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; 1625 scoped_ptr<TranslateBubbleFactory> factory_ptr(factory); 1626 TranslateBubbleFactory::SetFactory(factory); 1627 1628 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1629 1630 // Check the bubble exists instead of the infobar. 1631 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1632 ASSERT_TRUE(infobar == NULL); 1633 TranslateBubbleModel* bubble = factory->model(); 1634 ASSERT_TRUE(bubble != NULL); 1635 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE, 1636 bubble->GetViewState()); 1637 1638 // Simulate clicking translate. 1639 process()->sink().ClearMessages(); 1640 bubble->Translate(); 1641 SimulateTranslateScriptURLFetch(false); 1642 1643 // We should not have sent any message to translate to the renderer. 1644 EXPECT_FALSE(GetTranslateMessage(NULL, NULL)); 1645 1646 // And we should have an error infobar showing. 1647 bubble = factory->model(); 1648 ASSERT_TRUE(bubble != NULL); 1649 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ERROR, bubble->GetViewState()); 1650 } 1651 1652 TEST_F(TranslateManagerRenderViewHostTest, BubbleUnknownLanguage) { 1653 // See TranslateUnknownLanguage for corresponding infobar UX testing. 1654 if (!TranslateService::IsTranslateBubbleEnabled()) 1655 return; 1656 1657 MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; 1658 scoped_ptr<TranslateBubbleFactory> factory_ptr(factory); 1659 TranslateBubbleFactory::SetFactory(factory); 1660 1661 // Simulate navigating to a page ("und" is the string returned by the CLD for 1662 // languages it does not recognize). 1663 SimulateNavigation(GURL("http://www.google.mys"), "und", true); 1664 1665 // We should not have a bubble as we don't know the language. 1666 ASSERT_TRUE(factory->model() == NULL); 1667 1668 // Translate the page anyway throught the context menu. 1669 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); 1670 menu->Init(); 1671 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 1672 1673 // Check the bubble exists instead of the infobar. 1674 translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1675 ASSERT_TRUE(infobar == NULL); 1676 TranslateBubbleModel* bubble = factory->model(); 1677 ASSERT_TRUE(bubble != NULL); 1678 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_TRANSLATING, 1679 bubble->GetViewState()); 1680 } 1681