| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 | |
| 6 #include <set> | |
| 7 | |
| 8 #include "base/utf_string_conversions.h" | |
| 9 #include "chrome/app/chrome_command_ids.h" | |
| 10 #include "chrome/browser/prefs/pref_service.h" | |
| 11 #include "chrome/browser/prefs/pref_change_registrar.h" | |
| 12 #include "chrome/browser/tab_contents/render_view_context_menu.h" | |
| 13 #include "chrome/browser/translate/translate_infobar_delegate.h" | |
| 14 #include "chrome/browser/translate/translate_manager.h" | |
| 15 #include "chrome/browser/translate/translate_prefs.h" | |
| 16 #include "chrome/common/notification_details.h" | |
| 17 #include "chrome/common/notification_observer_mock.h" | |
| 18 #include "chrome/common/notification_registrar.h" | |
| 19 #include "chrome/common/notification_type.h" | |
| 20 #include "chrome/common/pref_names.h" | |
| 21 #include "chrome/common/render_messages.h" | |
| 22 #include "chrome/common/net/test_url_fetcher_factory.h" | |
| 23 #include "chrome/test/testing_browser_process.h" | |
| 24 #include "chrome/test/testing_profile.h" | |
| 25 #include "content/browser/renderer_host/mock_render_process_host.h" | |
| 26 #include "content/browser/renderer_host/test_render_view_host.h" | |
| 27 #include "content/browser/tab_contents/navigation_controller.h" | |
| 28 #include "content/browser/tab_contents/test_tab_contents.h" | |
| 29 #include "grit/generated_resources.h" | |
| 30 #include "ipc/ipc_test_sink.h" | |
| 31 #include "testing/gmock/include/gmock/gmock.h" | |
| 32 #include "third_party/cld/languages/public/languages.h" | |
| 33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h" | |
| 34 | |
| 35 using testing::_; | |
| 36 using testing::Pointee; | |
| 37 using testing::Property; | |
| 38 using WebKit::WebContextMenuData; | |
| 39 | |
| 40 class TranslateManagerTest : public RenderViewHostTestHarness, | |
| 41 public NotificationObserver { | |
| 42 public: | |
| 43 TranslateManagerTest() {} | |
| 44 | |
| 45 // Simluates navigating to a page and getting the page contents and language | |
| 46 // for that navigation. | |
| 47 void SimulateNavigation(const GURL& url, | |
| 48 const std::string& contents, | |
| 49 const std::string& lang, | |
| 50 bool page_translatable) { | |
| 51 NavigateAndCommit(url); | |
| 52 int page_id = RenderViewHostTestHarness::contents()->controller(). | |
| 53 GetLastCommittedEntry()->page_id(); | |
| 54 SimulateOnPageContents(url, page_id, contents, lang, page_translatable); | |
| 55 } | |
| 56 | |
| 57 void SimulateOnPageContents(const GURL& url, int page_id, | |
| 58 const std::string& contents, | |
| 59 const std::string& lang, | |
| 60 bool page_translatable) { | |
| 61 rvh()->TestOnMessageReceived(ViewHostMsg_PageContents(0, url, page_id, | |
| 62 UTF8ToUTF16(contents), | |
| 63 lang, | |
| 64 page_translatable)); | |
| 65 } | |
| 66 | |
| 67 bool GetTranslateMessage(int* page_id, | |
| 68 std::string* original_lang, | |
| 69 std::string* target_lang) { | |
| 70 const IPC::Message* message = | |
| 71 process()->sink().GetFirstMessageMatching(ViewMsg_TranslatePage::ID); | |
| 72 if (!message) | |
| 73 return false; | |
| 74 Tuple4<int, std::string, std::string, std::string> translate_param; | |
| 75 ViewMsg_TranslatePage::Read(message, &translate_param); | |
| 76 if (page_id) | |
| 77 *page_id = translate_param.a; | |
| 78 // Ignore translate_param.b which is the script injected in the page. | |
| 79 if (original_lang) | |
| 80 *original_lang = translate_param.c; | |
| 81 if (target_lang) | |
| 82 *target_lang = translate_param.d; | |
| 83 return true; | |
| 84 } | |
| 85 | |
| 86 // Returns the translate infobar if there is 1 infobar and it is a translate | |
| 87 // infobar. | |
| 88 TranslateInfoBarDelegate* GetTranslateInfoBar() { | |
| 89 return (contents()->infobar_count() == 1) ? | |
| 90 contents()->GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate() : | |
| 91 NULL; | |
| 92 } | |
| 93 | |
| 94 // If there is 1 infobar and it is a translate infobar, closes it and returns | |
| 95 // true. Returns false otherwise. | |
| 96 bool CloseTranslateInfoBar() { | |
| 97 InfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 98 if (!infobar) | |
| 99 return false; | |
| 100 infobar->InfoBarDismissed(); // Simulates closing the infobar. | |
| 101 contents()->RemoveInfoBar(infobar); | |
| 102 return true; | |
| 103 } | |
| 104 | |
| 105 // Checks whether |infobar| has been removed and clears the removed infobar | |
| 106 // list. | |
| 107 bool CheckInfoBarRemovedAndReset(InfoBarDelegate* delegate) { | |
| 108 bool found = removed_infobars_.count(delegate) != 0; | |
| 109 removed_infobars_.clear(); | |
| 110 return found; | |
| 111 } | |
| 112 | |
| 113 // Returns true if at least one infobar was closed. | |
| 114 bool InfoBarRemoved() { | |
| 115 return !removed_infobars_.empty(); | |
| 116 } | |
| 117 | |
| 118 // Clears the list of stored removed infobars. | |
| 119 void ClearRemovedInfoBars() { | |
| 120 removed_infobars_.clear(); | |
| 121 } | |
| 122 | |
| 123 void ExpireTranslateScriptImmediately() { | |
| 124 TranslateManager::GetInstance()->set_translate_script_expiration_delay(0); | |
| 125 } | |
| 126 | |
| 127 // If there is 1 infobar and it is a translate infobar, deny translation and | |
| 128 // returns true. Returns false otherwise. | |
| 129 bool DenyTranslation() { | |
| 130 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 131 if (!infobar) | |
| 132 return false; | |
| 133 infobar->TranslationDeclined(); | |
| 134 contents()->RemoveInfoBar(infobar); | |
| 135 return true; | |
| 136 } | |
| 137 | |
| 138 virtual void Observe(NotificationType type, | |
| 139 const NotificationSource& source, | |
| 140 const NotificationDetails& details) { | |
| 141 DCHECK_EQ(NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, type.value); | |
| 142 removed_infobars_.insert(Details<InfoBarDelegate>(details).ptr()); | |
| 143 } | |
| 144 | |
| 145 protected: | |
| 146 virtual void SetUp() { | |
| 147 URLFetcher::set_factory(&url_fetcher_factory_); | |
| 148 | |
| 149 // Access the TranslateManager singleton so it is created before we call | |
| 150 // RenderViewHostTestHarness::SetUp() to match what's done in Chrome, where | |
| 151 // the TranslateManager is created before the TabContents. This matters as | |
| 152 // they both register for similar events and we want the notifications to | |
| 153 // happen in the same sequence (TranslateManager first, TabContents second). | |
| 154 // Also clears the translate script so it is fetched everytime and sets the | |
| 155 // expiration delay to a large value by default (in case it was zeroed in | |
| 156 // a previous test). | |
| 157 TranslateManager::GetInstance()->ClearTranslateScript(); | |
| 158 TranslateManager::GetInstance()-> | |
| 159 set_translate_script_expiration_delay(60 * 60 * 1000); | |
| 160 | |
| 161 RenderViewHostTestHarness::SetUp(); | |
| 162 | |
| 163 notification_registrar_.Add(this, | |
| 164 NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, | |
| 165 Source<TabContents>(contents())); | |
| 166 } | |
| 167 | |
| 168 virtual void TearDown() { | |
| 169 process()->sink().ClearMessages(); | |
| 170 | |
| 171 notification_registrar_.Remove(this, | |
| 172 NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, | |
| 173 Source<TabContents>(contents())); | |
| 174 | |
| 175 RenderViewHostTestHarness::TearDown(); | |
| 176 | |
| 177 URLFetcher::set_factory(NULL); | |
| 178 } | |
| 179 | |
| 180 void SimulateURLFetch(bool success) { | |
| 181 TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); | |
| 182 ASSERT_TRUE(fetcher); | |
| 183 net::URLRequestStatus status; | |
| 184 status.set_status(success ? net::URLRequestStatus::SUCCESS : | |
| 185 net::URLRequestStatus::FAILED); | |
| 186 fetcher->delegate()->OnURLFetchComplete(fetcher, fetcher->original_url(), | |
| 187 status, success ? 200 : 500, | |
| 188 ResponseCookies(), | |
| 189 std::string()); | |
| 190 } | |
| 191 | |
| 192 void SetPrefObserverExpectation(const char* path) { | |
| 193 EXPECT_CALL( | |
| 194 pref_observer_, | |
| 195 Observe(NotificationType(NotificationType::PREF_CHANGED), | |
| 196 _, | |
| 197 Property(&Details<std::string>::ptr, Pointee(path)))); | |
| 198 } | |
| 199 | |
| 200 NotificationObserverMock pref_observer_; | |
| 201 | |
| 202 private: | |
| 203 NotificationRegistrar notification_registrar_; | |
| 204 TestURLFetcherFactory url_fetcher_factory_; | |
| 205 | |
| 206 // The infobars that have been removed. | |
| 207 // WARNING: the pointers point to deleted objects, use only for comparison. | |
| 208 std::set<InfoBarDelegate*> removed_infobars_; | |
| 209 | |
| 210 DISALLOW_COPY_AND_ASSIGN(TranslateManagerTest); | |
| 211 }; | |
| 212 | |
| 213 // An observer that keeps track of whether a navigation entry was committed. | |
| 214 class NavEntryCommittedObserver : public NotificationObserver { | |
| 215 public: | |
| 216 explicit NavEntryCommittedObserver(TabContents* tab_contents) { | |
| 217 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, | |
| 218 Source<NavigationController>(&tab_contents->controller())); | |
| 219 } | |
| 220 | |
| 221 virtual void Observe(NotificationType type, | |
| 222 const NotificationSource& source, | |
| 223 const NotificationDetails& details) { | |
| 224 DCHECK(type == NotificationType::NAV_ENTRY_COMMITTED); | |
| 225 details_ = | |
| 226 *(Details<NavigationController::LoadCommittedDetails>(details).ptr()); | |
| 227 } | |
| 228 | |
| 229 const NavigationController::LoadCommittedDetails& | |
| 230 get_load_commited_details() const { | |
| 231 return details_; | |
| 232 } | |
| 233 | |
| 234 private: | |
| 235 NavigationController::LoadCommittedDetails details_; | |
| 236 NotificationRegistrar registrar_; | |
| 237 | |
| 238 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver); | |
| 239 }; | |
| 240 | |
| 241 class TestRenderViewContextMenu : public RenderViewContextMenu { | |
| 242 public: | |
| 243 static TestRenderViewContextMenu* CreateContextMenu( | |
| 244 TabContents* tab_contents) { | |
| 245 ContextMenuParams params; | |
| 246 params.media_type = WebKit::WebContextMenuData::MediaTypeNone; | |
| 247 params.x = 0; | |
| 248 params.y = 0; | |
| 249 params.is_image_blocked = false; | |
| 250 params.media_flags = 0; | |
| 251 params.spellcheck_enabled = false; | |
| 252 params.is_editable = false; | |
| 253 params.page_url = tab_contents->controller().GetActiveEntry()->url(); | |
| 254 #if defined(OS_MACOSX) | |
| 255 params.writing_direction_default = 0; | |
| 256 params.writing_direction_left_to_right = 0; | |
| 257 params.writing_direction_right_to_left = 0; | |
| 258 #endif // OS_MACOSX | |
| 259 params.edit_flags = WebContextMenuData::CanTranslate; | |
| 260 return new TestRenderViewContextMenu(tab_contents, params); | |
| 261 } | |
| 262 | |
| 263 bool IsItemPresent(int id) { | |
| 264 return menu_model_.GetIndexOfCommandId(id) != -1; | |
| 265 } | |
| 266 | |
| 267 virtual void PlatformInit() { } | |
| 268 virtual bool GetAcceleratorForCommandId( | |
| 269 int command_id, | |
| 270 ui::Accelerator* accelerator) { return false; } | |
| 271 | |
| 272 private: | |
| 273 TestRenderViewContextMenu(TabContents* tab_contents, | |
| 274 const ContextMenuParams& params) | |
| 275 : RenderViewContextMenu(tab_contents, params) { | |
| 276 } | |
| 277 | |
| 278 DISALLOW_COPY_AND_ASSIGN(TestRenderViewContextMenu); | |
| 279 }; | |
| 280 | |
| 281 TEST_F(TranslateManagerTest, NormalTranslate) { | |
| 282 // Simulate navigating to a page. | |
| 283 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 284 | |
| 285 // We should have an infobar. | |
| 286 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 287 ASSERT_TRUE(infobar != NULL); | |
| 288 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); | |
| 289 | |
| 290 // Simulate clicking translate. | |
| 291 process()->sink().ClearMessages(); | |
| 292 infobar->Translate(); | |
| 293 | |
| 294 // The "Translating..." infobar should be showing. | |
| 295 infobar = GetTranslateInfoBar(); | |
| 296 ASSERT_TRUE(infobar != NULL); | |
| 297 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->type()); | |
| 298 | |
| 299 // Simulate the translate script being retrieved (it only needs to be done | |
| 300 // once in the test as it is cached). | |
| 301 SimulateURLFetch(true); | |
| 302 | |
| 303 // Test that we sent the right message to the renderer. | |
| 304 int page_id = 0; | |
| 305 std::string original_lang, target_lang; | |
| 306 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 307 EXPECT_EQ("fr", original_lang); | |
| 308 EXPECT_EQ("en", target_lang); | |
| 309 | |
| 310 // Simulate the render notifying the translation has been done. | |
| 311 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
| 312 TranslateErrors::NONE)); | |
| 313 | |
| 314 // The after translate infobar should be showing. | |
| 315 infobar = GetTranslateInfoBar(); | |
| 316 ASSERT_TRUE(infobar != NULL); | |
| 317 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE, infobar->type()); | |
| 318 | |
| 319 // Simulate changing the original language, this should trigger a translation. | |
| 320 process()->sink().ClearMessages(); | |
| 321 std::string new_original_lang = infobar->GetLanguageCodeAt(0); | |
| 322 infobar->SetOriginalLanguage(0); | |
| 323 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 324 EXPECT_EQ(new_original_lang, original_lang); | |
| 325 EXPECT_EQ("en", target_lang); | |
| 326 // Simulate the render notifying the translation has been done. | |
| 327 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, | |
| 328 new_original_lang, "en", TranslateErrors::NONE)); | |
| 329 // infobar is now invalid. | |
| 330 TranslateInfoBarDelegate* new_infobar = GetTranslateInfoBar(); | |
| 331 ASSERT_TRUE(new_infobar != NULL); | |
| 332 infobar = new_infobar; | |
| 333 | |
| 334 // Simulate changing the target language, this should trigger a translation. | |
| 335 process()->sink().ClearMessages(); | |
| 336 std::string new_target_lang = infobar->GetLanguageCodeAt(1); | |
| 337 infobar->SetTargetLanguage(1); | |
| 338 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 339 EXPECT_EQ(new_original_lang, original_lang); | |
| 340 EXPECT_EQ(new_target_lang, target_lang); | |
| 341 // Simulate the render notifying the translation has been done. | |
| 342 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, | |
| 343 new_original_lang, new_target_lang, TranslateErrors::NONE)); | |
| 344 // infobar is now invalid. | |
| 345 new_infobar = GetTranslateInfoBar(); | |
| 346 ASSERT_TRUE(new_infobar != NULL); | |
| 347 } | |
| 348 | |
| 349 TEST_F(TranslateManagerTest, TranslateScriptNotAvailable) { | |
| 350 // Simulate navigating to a page. | |
| 351 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 352 | |
| 353 // We should have an infobar. | |
| 354 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 355 ASSERT_TRUE(infobar != NULL); | |
| 356 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); | |
| 357 | |
| 358 // Simulate clicking translate. | |
| 359 process()->sink().ClearMessages(); | |
| 360 infobar->Translate(); | |
| 361 // Simulate a failure retrieving the translate script. | |
| 362 SimulateURLFetch(false); | |
| 363 | |
| 364 // We should not have sent any message to translate to the renderer. | |
| 365 EXPECT_FALSE(GetTranslateMessage(NULL, NULL, NULL)); | |
| 366 | |
| 367 // And we should have an error infobar showing. | |
| 368 infobar = GetTranslateInfoBar(); | |
| 369 ASSERT_TRUE(infobar != NULL); | |
| 370 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, infobar->type()); | |
| 371 } | |
| 372 | |
| 373 // Ensures we deal correctly with pages for which the browser does not recognize | |
| 374 // the language (the translate server may or not detect the language). | |
| 375 TEST_F(TranslateManagerTest, TranslateUnknownLanguage) { | |
| 376 // Simulate navigating to a page ("und" is the string returned by the CLD for | |
| 377 // languages it does not recognize). | |
| 378 SimulateNavigation(GURL("http://www.google.mys"), "G00g1e", "und", true); | |
| 379 | |
| 380 // We should not have an infobar as we don't know the language. | |
| 381 ASSERT_TRUE(GetTranslateInfoBar() == NULL); | |
| 382 | |
| 383 // Translate the page anyway throught the context menu. | |
| 384 scoped_ptr<TestRenderViewContextMenu> menu( | |
| 385 TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 386 menu->Init(); | |
| 387 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
| 388 | |
| 389 // To test that bug #49018 if fixed, make sure we deal correctly with errors. | |
| 390 SimulateURLFetch(false); // Simulate a failure to fetch the translate script. | |
| 391 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 392 ASSERT_TRUE(infobar != NULL); | |
| 393 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, infobar->type()); | |
| 394 EXPECT_TRUE(infobar->IsError()); | |
| 395 infobar->MessageInfoBarButtonPressed(); | |
| 396 SimulateURLFetch(true); // This time succeed. | |
| 397 | |
| 398 // Simulate the render notifying the translation has been done, the server | |
| 399 // having detected the page was in a known and supported language. | |
| 400 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
| 401 TranslateErrors::NONE)); | |
| 402 | |
| 403 // The after translate infobar should be showing. | |
| 404 infobar = GetTranslateInfoBar(); | |
| 405 ASSERT_TRUE(infobar != NULL); | |
| 406 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE, infobar->type()); | |
| 407 EXPECT_EQ("fr", infobar->GetOriginalLanguageCode()); | |
| 408 EXPECT_EQ("en", infobar->GetTargetLanguageCode()); | |
| 409 | |
| 410 // Let's run the same steps but this time the server detects the page is | |
| 411 // already in English. | |
| 412 SimulateNavigation(GURL("http://www.google.com"), "The Google", "und", true); | |
| 413 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 414 menu->Init(); | |
| 415 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
| 416 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(1, 0, "en", "en", | |
| 417 TranslateErrors::IDENTICAL_LANGUAGES)); | |
| 418 infobar = GetTranslateInfoBar(); | |
| 419 ASSERT_TRUE(infobar != NULL); | |
| 420 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, infobar->type()); | |
| 421 EXPECT_EQ(TranslateErrors::IDENTICAL_LANGUAGES, infobar->error()); | |
| 422 | |
| 423 // Let's run the same steps again but this time the server fails to detect the | |
| 424 // page's language (it returns an empty string). | |
| 425 SimulateNavigation(GURL("http://www.google.com"), "The Google", "und", true); | |
| 426 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 427 menu->Init(); | |
| 428 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
| 429 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(2, 0, "", "en", | |
| 430 TranslateErrors::UNKNOWN_LANGUAGE)); | |
| 431 infobar = GetTranslateInfoBar(); | |
| 432 ASSERT_TRUE(infobar != NULL); | |
| 433 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, infobar->type()); | |
| 434 EXPECT_EQ(TranslateErrors::UNKNOWN_LANGUAGE, infobar->error()); | |
| 435 } | |
| 436 | |
| 437 // Tests that we show/don't show an info-bar for all languages the CLD can | |
| 438 // report. | |
| 439 TEST_F(TranslateManagerTest, TestAllLanguages) { | |
| 440 // The index in kExpectation are the Language enum (see languages.pb.h). | |
| 441 // true if we expect a translate infobar for that language. | |
| 442 // Note the supported languages are in translation_manager.cc, see | |
| 443 // kSupportedLanguages. | |
| 444 bool kExpectations[] = { | |
| 445 // 0-9 | |
| 446 false, true, true, true, true, true, true, true, true, true, | |
| 447 // 10-19 | |
| 448 true, true, true, true, true, true, true, true, true, true, | |
| 449 // 20-29 | |
| 450 true, true, true, true, true, false, false, true, true, true, | |
| 451 // 30-39 | |
| 452 true, true, true, true, true, true, true, false, true, false, | |
| 453 // 40-49 | |
| 454 true, false, true, false, false, true, false, true, false, false, | |
| 455 // 50-59 | |
| 456 true, false, false, true, true, true, false, true, false, false, | |
| 457 // 60-69 | |
| 458 false, false, true, true, false, true, true, false, true, true, | |
| 459 // 70-79 | |
| 460 false, false, false, false, true, true, false, true, false, false, | |
| 461 // 80-89 | |
| 462 false, false, false, false, false, false, false, false, false, false, | |
| 463 // 90-99 | |
| 464 false, true, false, false, false, false, false, true, false, false, | |
| 465 // 100-109 | |
| 466 false, true, false, false, false, false, false, false, false, false, | |
| 467 // 110-119 | |
| 468 false, false, false, false, false, false, false, false, false, false, | |
| 469 // 120-129 | |
| 470 false, false, false, false, false, false, false, false, false, false, | |
| 471 // 130-139 | |
| 472 false, false, false, false, false, false, false, false, false, true, | |
| 473 // 140-149 | |
| 474 false, false, false, false, false, false, false, false, false, false, | |
| 475 // 150-159 | |
| 476 false, false, false, false, false, false, false, false, false, false, | |
| 477 // 160 | |
| 478 false | |
| 479 }; | |
| 480 | |
| 481 GURL url("http://www.google.com"); | |
| 482 for (size_t i = 0; i < arraysize(kExpectations); ++i) { | |
| 483 ASSERT_LT(i, static_cast<size_t>(NUM_LANGUAGES)); | |
| 484 | |
| 485 std::string lang = LanguageCodeWithDialects(static_cast<Language>(i)); | |
| 486 SCOPED_TRACE(::testing::Message::Message() << "Iteration " << i << | |
| 487 " language=" << lang); | |
| 488 | |
| 489 // We should not have a translate infobar. | |
| 490 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 491 ASSERT_TRUE(infobar == NULL); | |
| 492 | |
| 493 // Simulate navigating to a page. | |
| 494 NavigateAndCommit(url); | |
| 495 SimulateOnPageContents(url, i, "", lang, true); | |
| 496 | |
| 497 // Verify we have/don't have an info-bar as expected. | |
| 498 infobar = GetTranslateInfoBar(); | |
| 499 EXPECT_EQ(kExpectations[i], infobar != NULL); | |
| 500 | |
| 501 // Close the info-bar if applicable. | |
| 502 if (infobar != NULL) | |
| 503 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 504 } | |
| 505 } | |
| 506 | |
| 507 // Tests auto-translate on page. | |
| 508 TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) { | |
| 509 // Simulate navigating to a page and getting its language. | |
| 510 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 511 | |
| 512 // Simulate the user translating. | |
| 513 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 514 ASSERT_TRUE(infobar != NULL); | |
| 515 infobar->Translate(); | |
| 516 SimulateURLFetch(true); // Simulate the translate script being retrieved. | |
| 517 | |
| 518 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
| 519 TranslateErrors::NONE)); | |
| 520 | |
| 521 // Now navigate to a new page in the same language. | |
| 522 process()->sink().ClearMessages(); | |
| 523 SimulateNavigation(GURL("http://news.google.fr"), "Les news", "fr", true); | |
| 524 | |
| 525 // This should have automatically triggered a translation. | |
| 526 int page_id = 0; | |
| 527 std::string original_lang, target_lang; | |
| 528 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 529 EXPECT_EQ(1, page_id); | |
| 530 EXPECT_EQ("fr", original_lang); | |
| 531 EXPECT_EQ("en", target_lang); | |
| 532 | |
| 533 // Now navigate to a page in a different language. | |
| 534 process()->sink().ClearMessages(); | |
| 535 SimulateNavigation(GURL("http://news.google.es"), "Las news", "es", true); | |
| 536 | |
| 537 // This should not have triggered a translate. | |
| 538 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 539 } | |
| 540 | |
| 541 // Tests that multiple OnPageContents do not cause multiple infobars. | |
| 542 TEST_F(TranslateManagerTest, MultipleOnPageContents) { | |
| 543 // Simulate navigating to a page and getting its language. | |
| 544 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 545 | |
| 546 // Simulate clicking 'Nope' (don't translate). | |
| 547 EXPECT_TRUE(DenyTranslation()); | |
| 548 EXPECT_EQ(0U, contents()->infobar_count()); | |
| 549 | |
| 550 // Send a new PageContents, we should not show an infobar. | |
| 551 SimulateOnPageContents(GURL("http://www.google.fr"), 0, "Le Google", "fr", | |
| 552 true); | |
| 553 EXPECT_EQ(0U, contents()->infobar_count()); | |
| 554 | |
| 555 // Do the same steps but simulate closing the infobar this time. | |
| 556 SimulateNavigation(GURL("http://www.youtube.fr"), "Le YouTube", "fr", | |
| 557 true); | |
| 558 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 559 EXPECT_EQ(0U, contents()->infobar_count()); | |
| 560 SimulateOnPageContents(GURL("http://www.youtube.fr"), 1, "Le YouTube", "fr", | |
| 561 true); | |
| 562 EXPECT_EQ(0U, contents()->infobar_count()); | |
| 563 } | |
| 564 | |
| 565 // Test that reloading the page brings back the infobar. | |
| 566 TEST_F(TranslateManagerTest, Reload) { | |
| 567 // Simulate navigating to a page and getting its language. | |
| 568 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 569 | |
| 570 // Close the infobar. | |
| 571 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 572 | |
| 573 // Reload should bring back the infobar. | |
| 574 NavEntryCommittedObserver nav_observer(contents()); | |
| 575 Reload(); | |
| 576 | |
| 577 // Ensures it is really handled a reload. | |
| 578 const NavigationController::LoadCommittedDetails& nav_details = | |
| 579 nav_observer.get_load_commited_details(); | |
| 580 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation. | |
| 581 EXPECT_EQ(NavigationType::EXISTING_PAGE, nav_details.type); | |
| 582 | |
| 583 // The TranslateManager class processes the navigation entry committed | |
| 584 // notification in a posted task; process that task. | |
| 585 MessageLoop::current()->RunAllPending(); | |
| 586 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 587 } | |
| 588 | |
| 589 // Test that reloading the page by way of typing again the URL in the | |
| 590 // location bar brings back the infobar. | |
| 591 TEST_F(TranslateManagerTest, ReloadFromLocationBar) { | |
| 592 GURL url("http://www.google.fr"); | |
| 593 | |
| 594 // Simulate navigating to a page and getting its language. | |
| 595 SimulateNavigation(url, "Le Google", "fr", true); | |
| 596 | |
| 597 // Close the infobar. | |
| 598 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 599 | |
| 600 // Create a pending navigation and simulate a page load. That should be the | |
| 601 // equivalent of typing the URL again in the location bar. | |
| 602 NavEntryCommittedObserver nav_observer(contents()); | |
| 603 contents()->controller().LoadURL(url, GURL(), PageTransition::TYPED); | |
| 604 rvh()->SendNavigate(0, url); | |
| 605 | |
| 606 // Test that we are really getting a same page navigation, the test would be | |
| 607 // useless if it was not the case. | |
| 608 const NavigationController::LoadCommittedDetails& nav_details = | |
| 609 nav_observer.get_load_commited_details(); | |
| 610 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation. | |
| 611 EXPECT_EQ(NavigationType::SAME_PAGE, nav_details.type); | |
| 612 | |
| 613 // The TranslateManager class processes the navigation entry committed | |
| 614 // notification in a posted task; process that task. | |
| 615 MessageLoop::current()->RunAllPending(); | |
| 616 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 617 } | |
| 618 | |
| 619 // Tests that a closed translate infobar does not reappear when navigating | |
| 620 // in-page. | |
| 621 TEST_F(TranslateManagerTest, CloseInfoBarInPageNavigation) { | |
| 622 // Simulate navigating to a page and getting its language. | |
| 623 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 624 | |
| 625 // Close the infobar. | |
| 626 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 627 | |
| 628 // Navigate in page, no infobar should be shown. | |
| 629 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", | |
| 630 true); | |
| 631 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 632 | |
| 633 // Navigate out of page, a new infobar should show. | |
| 634 SimulateNavigation(GURL("http://www.google.fr/foot"), "Le Google", "fr", | |
| 635 true); | |
| 636 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 637 } | |
| 638 | |
| 639 // Tests that a closed translate infobar does not reappear when navigating | |
| 640 // in a subframe. (http://crbug.com/48215) | |
| 641 TEST_F(TranslateManagerTest, CloseInfoBarInSubframeNavigation) { | |
| 642 // Simulate navigating to a page and getting its language. | |
| 643 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 644 | |
| 645 // Close the infobar. | |
| 646 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 647 | |
| 648 // Simulate a sub-frame auto-navigating. | |
| 649 rvh()->SendNavigateWithTransition(1, GURL("http://pub.com"), | |
| 650 PageTransition::AUTO_SUBFRAME); | |
| 651 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 652 | |
| 653 // Simulate the user navigating in a sub-frame. | |
| 654 rvh()->SendNavigateWithTransition(2, GURL("http://pub.com"), | |
| 655 PageTransition::MANUAL_SUBFRAME); | |
| 656 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 657 | |
| 658 // Navigate out of page, a new infobar should show. | |
| 659 SimulateNavigation(GURL("http://www.google.fr/foot"), "Le Google", "fr", | |
| 660 true); | |
| 661 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 662 } | |
| 663 | |
| 664 | |
| 665 | |
| 666 // Tests that denying translation is sticky when navigating in page. | |
| 667 TEST_F(TranslateManagerTest, DenyTranslateInPageNavigation) { | |
| 668 // Simulate navigating to a page and getting its language. | |
| 669 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 670 | |
| 671 // Simulate clicking 'Nope' (don't translate). | |
| 672 EXPECT_TRUE(DenyTranslation()); | |
| 673 | |
| 674 // Navigate in page, no infobar should be shown. | |
| 675 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", | |
| 676 true); | |
| 677 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 678 | |
| 679 // Navigate out of page, a new infobar should show. | |
| 680 SimulateNavigation(GURL("http://www.google.fr/foot"), "Le Google", "fr", | |
| 681 true); | |
| 682 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 683 } | |
| 684 | |
| 685 // Tests that after translating and closing the infobar, the infobar does not | |
| 686 // return when navigating in page. | |
| 687 TEST_F(TranslateManagerTest, TranslateCloseInfoBarInPageNavigation) { | |
| 688 // Simulate navigating to a page and getting its language. | |
| 689 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 690 | |
| 691 // Simulate the user translating. | |
| 692 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 693 ASSERT_TRUE(infobar != NULL); | |
| 694 infobar->Translate(); | |
| 695 SimulateURLFetch(true); // Simulate the translate script being retrieved. | |
| 696 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
| 697 TranslateErrors::NONE)); | |
| 698 | |
| 699 // Close the infobar. | |
| 700 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 701 | |
| 702 // Navigate in page, no infobar should be shown. | |
| 703 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", | |
| 704 true); | |
| 705 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 706 | |
| 707 // Navigate out of page, a new infobar should show. | |
| 708 // Note that we navigate to a page in a different language so we don't trigger | |
| 709 // the auto-translate feature (it would translate the page automatically and | |
| 710 // the before translate inforbar would not be shown). | |
| 711 SimulateNavigation(GURL("http://www.google.de"), "Das Google", "de", true); | |
| 712 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 713 } | |
| 714 | |
| 715 // Tests that the after translate the infobar still shows when navigating | |
| 716 // in-page. | |
| 717 TEST_F(TranslateManagerTest, TranslateInPageNavigation) { | |
| 718 // Simulate navigating to a page and getting its language. | |
| 719 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 720 | |
| 721 // Simulate the user translating. | |
| 722 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 723 ASSERT_TRUE(infobar != NULL); | |
| 724 infobar->Translate(); | |
| 725 SimulateURLFetch(true); // Simulate the translate script being retrieved. | |
| 726 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
| 727 TranslateErrors::NONE)); | |
| 728 // The after translate infobar is showing. | |
| 729 infobar = GetTranslateInfoBar(); | |
| 730 ASSERT_TRUE(infobar != NULL); | |
| 731 | |
| 732 // Navigate in page, the same infobar should still be shown. | |
| 733 ClearRemovedInfoBars(); | |
| 734 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", | |
| 735 true); | |
| 736 EXPECT_FALSE(InfoBarRemoved()); | |
| 737 EXPECT_EQ(infobar, GetTranslateInfoBar()); | |
| 738 | |
| 739 // Navigate out of page, a new infobar should show. | |
| 740 // See note in TranslateCloseInfoBarInPageNavigation test on why it is | |
| 741 // important to navigate to a page in a different language for this test. | |
| 742 SimulateNavigation(GURL("http://www.google.de"), "Das Google", "de", true); | |
| 743 // The old infobar is gone. | |
| 744 EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar)); | |
| 745 // And there is a new one. | |
| 746 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 747 } | |
| 748 | |
| 749 // Tests that no translate infobar is shown when navigating to a page in an | |
| 750 // unsupported language. | |
| 751 TEST_F(TranslateManagerTest, CLDReportsUnsupportedPageLanguage) { | |
| 752 // Simulate navigating to a page and getting an unsupported language. | |
| 753 SimulateNavigation(GURL("http://www.google.com"), "Google", "qbz", true); | |
| 754 | |
| 755 // No info-bar should be shown. | |
| 756 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 757 } | |
| 758 | |
| 759 // Tests that we deal correctly with unsupported languages returned by the | |
| 760 // server. | |
| 761 // The translation server might return a language we don't support. | |
| 762 TEST_F(TranslateManagerTest, ServerReportsUnsupportedLanguage) { | |
| 763 // Simulate navigating to a page and translating it. | |
| 764 SimulateNavigation(GURL("http://mail.google.fr"), "Le Google", "fr", true); | |
| 765 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 766 ASSERT_TRUE(infobar != NULL); | |
| 767 process()->sink().ClearMessages(); | |
| 768 infobar->Translate(); | |
| 769 SimulateURLFetch(true); | |
| 770 // Simulate the render notifying the translation has been done, but it | |
| 771 // reports a language we don't support. | |
| 772 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "qbz", "en", | |
| 773 TranslateErrors::NONE)); | |
| 774 | |
| 775 // An error infobar should be showing to report that we don't support this | |
| 776 // language. | |
| 777 infobar = GetTranslateInfoBar(); | |
| 778 ASSERT_TRUE(infobar != NULL); | |
| 779 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, infobar->type()); | |
| 780 | |
| 781 // This infobar should have a button (so the string should not be empty). | |
| 782 ASSERT_FALSE(infobar->GetMessageInfoBarButtonText().empty()); | |
| 783 | |
| 784 // Pressing the button on that infobar should revert to the original language. | |
| 785 process()->sink().ClearMessages(); | |
| 786 infobar->MessageInfoBarButtonPressed(); | |
| 787 const IPC::Message* message = | |
| 788 process()->sink().GetFirstMessageMatching(ViewMsg_RevertTranslation::ID); | |
| 789 EXPECT_TRUE(message != NULL); | |
| 790 // And it should have removed the infobar. | |
| 791 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 792 } | |
| 793 | |
| 794 // Tests that no translate infobar is shown when Chrome is in a language that | |
| 795 // the translate server does not support. | |
| 796 TEST_F(TranslateManagerTest, UnsupportedUILanguage) { | |
| 797 TestingBrowserProcess* browser_process = | |
| 798 static_cast<TestingBrowserProcess*>(g_browser_process); | |
| 799 std::string original_lang = browser_process->GetApplicationLocale(); | |
| 800 browser_process->SetApplicationLocale("qbz"); | |
| 801 | |
| 802 // Simulate navigating to a page in a language supported by the translate | |
| 803 // server. | |
| 804 SimulateNavigation(GURL("http://www.google.com"), "Google", "en", true); | |
| 805 | |
| 806 // No info-bar should be shown. | |
| 807 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 808 | |
| 809 browser_process->SetApplicationLocale(original_lang); | |
| 810 } | |
| 811 | |
| 812 // Tests that the translate enabled preference is honored. | |
| 813 TEST_F(TranslateManagerTest, TranslateEnabledPref) { | |
| 814 // Make sure the pref allows translate. | |
| 815 PrefService* prefs = contents()->profile()->GetPrefs(); | |
| 816 prefs->SetBoolean(prefs::kEnableTranslate, true); | |
| 817 | |
| 818 // Simulate navigating to a page and getting its language. | |
| 819 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 820 | |
| 821 // An infobar should be shown. | |
| 822 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 823 EXPECT_TRUE(infobar != NULL); | |
| 824 | |
| 825 // Disable translate. | |
| 826 prefs->SetBoolean(prefs::kEnableTranslate, false); | |
| 827 | |
| 828 // Navigate to a new page, that should close the previous infobar. | |
| 829 GURL url("http://www.youtube.fr"); | |
| 830 NavigateAndCommit(url); | |
| 831 infobar = GetTranslateInfoBar(); | |
| 832 EXPECT_TRUE(infobar == NULL); | |
| 833 | |
| 834 // Simulate getting the page contents and language, that should not trigger | |
| 835 // a translate infobar. | |
| 836 SimulateOnPageContents(url, 1, "Le YouTube", "fr", true); | |
| 837 infobar = GetTranslateInfoBar(); | |
| 838 EXPECT_TRUE(infobar == NULL); | |
| 839 } | |
| 840 | |
| 841 // Tests the "Never translate <language>" pref. | |
| 842 TEST_F(TranslateManagerTest, NeverTranslateLanguagePref) { | |
| 843 // Simulate navigating to a page and getting its language. | |
| 844 GURL url("http://www.google.fr"); | |
| 845 SimulateNavigation(url, "Le Google", "fr", true); | |
| 846 | |
| 847 // An infobar should be shown. | |
| 848 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 849 | |
| 850 // Select never translate this language. | |
| 851 PrefService* prefs = contents()->profile()->GetPrefs(); | |
| 852 PrefChangeRegistrar registrar; | |
| 853 registrar.Init(prefs); | |
| 854 registrar.Add(TranslatePrefs::kPrefTranslateLanguageBlacklist, | |
| 855 &pref_observer_); | |
| 856 TranslatePrefs translate_prefs(prefs); | |
| 857 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr")); | |
| 858 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
| 859 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateLanguageBlacklist); | |
| 860 translate_prefs.BlacklistLanguage("fr"); | |
| 861 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("fr")); | |
| 862 EXPECT_FALSE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
| 863 | |
| 864 // Close the infobar. | |
| 865 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 866 | |
| 867 // Navigate to a new page also in French. | |
| 868 SimulateNavigation(GURL("http://wwww.youtube.fr"), "Le YouTube", "fr", true); | |
| 869 | |
| 870 // There should not be a translate infobar. | |
| 871 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 872 | |
| 873 // Remove the language from the blacklist. | |
| 874 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateLanguageBlacklist); | |
| 875 translate_prefs.RemoveLanguageFromBlacklist("fr"); | |
| 876 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr")); | |
| 877 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
| 878 | |
| 879 // Navigate to a page in French. | |
| 880 SimulateNavigation(url, "Le Google", "fr", true); | |
| 881 | |
| 882 // There should be a translate infobar. | |
| 883 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 884 } | |
| 885 | |
| 886 // Tests the "Never translate this site" pref. | |
| 887 TEST_F(TranslateManagerTest, NeverTranslateSitePref) { | |
| 888 // Simulate navigating to a page and getting its language. | |
| 889 GURL url("http://www.google.fr"); | |
| 890 std::string host(url.host()); | |
| 891 SimulateNavigation(url, "Le Google", "fr", true); | |
| 892 | |
| 893 // An infobar should be shown. | |
| 894 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 895 | |
| 896 // Select never translate this site. | |
| 897 PrefService* prefs = contents()->profile()->GetPrefs(); | |
| 898 PrefChangeRegistrar registrar; | |
| 899 registrar.Init(prefs); | |
| 900 registrar.Add(TranslatePrefs::kPrefTranslateSiteBlacklist, | |
| 901 &pref_observer_); | |
| 902 TranslatePrefs translate_prefs(prefs); | |
| 903 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(host)); | |
| 904 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
| 905 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist); | |
| 906 translate_prefs.BlacklistSite(host); | |
| 907 EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(host)); | |
| 908 EXPECT_FALSE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
| 909 | |
| 910 // Close the infobar. | |
| 911 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 912 | |
| 913 // Navigate to a new page also on the same site. | |
| 914 SimulateNavigation(GURL("http://www.google.fr/hello"), "Bonjour", "fr", true); | |
| 915 | |
| 916 // There should not be a translate infobar. | |
| 917 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 918 | |
| 919 // Remove the site from the blacklist. | |
| 920 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist); | |
| 921 translate_prefs.RemoveSiteFromBlacklist(host); | |
| 922 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(host)); | |
| 923 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
| 924 | |
| 925 // Navigate to a page in French. | |
| 926 SimulateNavigation(url, "Le Google", "fr", true); | |
| 927 | |
| 928 // There should be a translate infobar. | |
| 929 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 930 } | |
| 931 | |
| 932 // Tests the "Always translate this language" pref. | |
| 933 TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) { | |
| 934 // Select always translate French to English. | |
| 935 PrefService* prefs = contents()->profile()->GetPrefs(); | |
| 936 PrefChangeRegistrar registrar; | |
| 937 registrar.Init(prefs); | |
| 938 registrar.Add(TranslatePrefs::kPrefTranslateWhitelists, | |
| 939 &pref_observer_); | |
| 940 TranslatePrefs translate_prefs(prefs); | |
| 941 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists); | |
| 942 translate_prefs.WhitelistLanguagePair("fr", "en"); | |
| 943 | |
| 944 // Load a page in French. | |
| 945 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 946 | |
| 947 // It should have triggered an automatic translation to English. | |
| 948 | |
| 949 // The translating infobar should be showing. | |
| 950 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 951 ASSERT_TRUE(infobar != NULL); | |
| 952 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->type()); | |
| 953 | |
| 954 SimulateURLFetch(true); // Simulate the translate script being retrieved. | |
| 955 int page_id = 0; | |
| 956 std::string original_lang, target_lang; | |
| 957 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 958 EXPECT_EQ("fr", original_lang); | |
| 959 EXPECT_EQ("en", target_lang); | |
| 960 process()->sink().ClearMessages(); | |
| 961 | |
| 962 // Try another language, it should not be autotranslated. | |
| 963 SimulateNavigation(GURL("http://www.google.es"), "El Google", "es", true); | |
| 964 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 965 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 966 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 967 | |
| 968 // Let's switch to incognito mode, it should not be autotranslated in that | |
| 969 // case either. | |
| 970 TestingProfile* test_profile = | |
| 971 static_cast<TestingProfile*>(contents()->profile()); | |
| 972 test_profile->set_off_the_record(true); | |
| 973 SimulateNavigation(GURL("http://www.youtube.fr"), "Le YouTube", "fr", true); | |
| 974 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 975 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
| 976 EXPECT_TRUE(CloseTranslateInfoBar()); | |
| 977 test_profile->set_off_the_record(false); // Get back to non incognito. | |
| 978 | |
| 979 // Now revert the always translate pref and make sure we go back to expected | |
| 980 // behavior, which is show a "before translate" infobar. | |
| 981 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists); | |
| 982 translate_prefs.RemoveLanguagePairFromWhitelist("fr", "en"); | |
| 983 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 984 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 985 infobar = GetTranslateInfoBar(); | |
| 986 ASSERT_TRUE(infobar != NULL); | |
| 987 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); | |
| 988 } | |
| 989 | |
| 990 // Context menu. | |
| 991 TEST_F(TranslateManagerTest, ContextMenu) { | |
| 992 // Blacklist www.google.fr and French for translation. | |
| 993 GURL url("http://www.google.fr"); | |
| 994 TranslatePrefs translate_prefs(contents()->profile()->GetPrefs()); | |
| 995 translate_prefs.BlacklistLanguage("fr"); | |
| 996 translate_prefs.BlacklistSite(url.host()); | |
| 997 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("fr")); | |
| 998 EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(url.host())); | |
| 999 | |
| 1000 // Simulate navigating to a page in French. The translate menu should show but | |
| 1001 // should only be enabled when the page language has been received. | |
| 1002 NavigateAndCommit(url); | |
| 1003 scoped_ptr<TestRenderViewContextMenu> menu( | |
| 1004 TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 1005 menu->Init(); | |
| 1006 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1007 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1008 | |
| 1009 // Simulate receiving the language. | |
| 1010 SimulateOnPageContents(url, 0, "Le Google", "fr", true); | |
| 1011 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 1012 menu->Init(); | |
| 1013 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1014 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1015 | |
| 1016 // Use the menu to translate the page. | |
| 1017 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
| 1018 | |
| 1019 // That should have triggered a translation. | |
| 1020 // The "translating..." infobar should be showing. | |
| 1021 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 1022 ASSERT_TRUE(infobar != NULL); | |
| 1023 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->type()); | |
| 1024 SimulateURLFetch(true); // Simulate the translate script being retrieved. | |
| 1025 int page_id = 0; | |
| 1026 std::string original_lang, target_lang; | |
| 1027 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 1028 EXPECT_EQ("fr", original_lang); | |
| 1029 EXPECT_EQ("en", target_lang); | |
| 1030 process()->sink().ClearMessages(); | |
| 1031 | |
| 1032 // This should also have reverted the blacklisting of this site and language. | |
| 1033 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr")); | |
| 1034 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(url.host())); | |
| 1035 | |
| 1036 // Let's simulate the page being translated. | |
| 1037 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
| 1038 TranslateErrors::NONE)); | |
| 1039 | |
| 1040 // The translate menu should now be disabled. | |
| 1041 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 1042 menu->Init(); | |
| 1043 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1044 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1045 | |
| 1046 // Test that selecting translate in the context menu WHILE the page is being | |
| 1047 // translated does nothing (this could happen if autotranslate kicks-in and | |
| 1048 // the user selects the menu while the translation is being performed). | |
| 1049 SimulateNavigation(GURL("http://www.google.es"), "El Google", "es", true); | |
| 1050 infobar = GetTranslateInfoBar(); | |
| 1051 ASSERT_TRUE(infobar != NULL); | |
| 1052 infobar->Translate(); | |
| 1053 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 1054 process()->sink().ClearMessages(); | |
| 1055 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 1056 menu->Init(); | |
| 1057 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1058 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
| 1059 // No message expected since the translation should have been ignored. | |
| 1060 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 1061 | |
| 1062 // Now test that selecting translate in the context menu AFTER the page has | |
| 1063 // been translated does nothing. | |
| 1064 SimulateNavigation(GURL("http://www.google.de"), "Das Google", "de", true); | |
| 1065 infobar = GetTranslateInfoBar(); | |
| 1066 ASSERT_TRUE(infobar != NULL); | |
| 1067 infobar->Translate(); | |
| 1068 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 1069 process()->sink().ClearMessages(); | |
| 1070 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 1071 menu->Init(); | |
| 1072 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1073 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "de", "en", | |
| 1074 TranslateErrors::NONE)); | |
| 1075 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
| 1076 // No message expected since the translation should have been ignored. | |
| 1077 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 1078 | |
| 1079 // Test that the translate context menu is disabled when the page is in the | |
| 1080 // same language as the UI. | |
| 1081 SimulateNavigation(url, "Google", "en", true); | |
| 1082 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 1083 menu->Init(); | |
| 1084 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1085 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1086 | |
| 1087 // Test that the translate context menu is enabled when the page is in an | |
| 1088 // unknown language. | |
| 1089 SimulateNavigation(url, "G00g1e", "und", true); | |
| 1090 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 1091 menu->Init(); | |
| 1092 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1093 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1094 | |
| 1095 // Test that the translate context menu is disabled when the page is in an | |
| 1096 // unsupported language. | |
| 1097 SimulateNavigation(url, "G00g1e", "qbz", true); | |
| 1098 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 1099 menu->Init(); | |
| 1100 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1101 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1102 } | |
| 1103 | |
| 1104 // Tests that an extra always/never translate button is shown on the "before | |
| 1105 // translate" infobar when the translation is accepted/declined 3 times, | |
| 1106 // only when not in incognito mode. | |
| 1107 TEST_F(TranslateManagerTest, BeforeTranslateExtraButtons) { | |
| 1108 TranslatePrefs translate_prefs(contents()->profile()->GetPrefs()); | |
| 1109 translate_prefs.ResetTranslationAcceptedCount("fr"); | |
| 1110 translate_prefs.ResetTranslationDeniedCount("fr"); | |
| 1111 translate_prefs.ResetTranslationAcceptedCount("de"); | |
| 1112 translate_prefs.ResetTranslationDeniedCount("de"); | |
| 1113 | |
| 1114 // We'll do 4 times in incognito mode first to make sure the button is not | |
| 1115 // shown in that case, then 4 times in normal mode. | |
| 1116 TranslateInfoBarDelegate* infobar; | |
| 1117 TestingProfile* test_profile = | |
| 1118 static_cast<TestingProfile*>(contents()->profile()); | |
| 1119 test_profile->set_off_the_record(true); | |
| 1120 for (int i = 0; i < 8; ++i) { | |
| 1121 SCOPED_TRACE(::testing::Message::Message() << "Iteration " << i << | |
| 1122 " incognito mode=" << test_profile->IsOffTheRecord()); | |
| 1123 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 1124 infobar = GetTranslateInfoBar(); | |
| 1125 ASSERT_TRUE(infobar != NULL); | |
| 1126 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); | |
| 1127 if (i < 7) { | |
| 1128 EXPECT_FALSE(infobar->ShouldShowAlwaysTranslateButton()); | |
| 1129 infobar->Translate(); | |
| 1130 process()->sink().ClearMessages(); | |
| 1131 } else { | |
| 1132 EXPECT_TRUE(infobar->ShouldShowAlwaysTranslateButton()); | |
| 1133 } | |
| 1134 if (i == 3) | |
| 1135 test_profile->set_off_the_record(false); | |
| 1136 } | |
| 1137 // Simulate the user pressing "Always translate French". | |
| 1138 infobar->AlwaysTranslatePageLanguage(); | |
| 1139 EXPECT_TRUE(translate_prefs.IsLanguagePairWhitelisted("fr", "en")); | |
| 1140 // Simulate the translate script being retrieved (it only needs to be done | |
| 1141 // once in the test as it is cached). | |
| 1142 SimulateURLFetch(true); | |
| 1143 // That should have triggered a page translate. | |
| 1144 int page_id = 0; | |
| 1145 std::string original_lang, target_lang; | |
| 1146 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 1147 process()->sink().ClearMessages(); | |
| 1148 | |
| 1149 // Now test that declining the translation causes a "never translate" button | |
| 1150 // to be shown (in non incognito mode only). | |
| 1151 test_profile->set_off_the_record(true); | |
| 1152 for (int i = 0; i < 8; ++i) { | |
| 1153 SCOPED_TRACE(::testing::Message::Message() << "Iteration " << i << | |
| 1154 " incognito mode=" << test_profile->IsOffTheRecord()); | |
| 1155 SimulateNavigation(GURL("http://www.google.de"), "Das Google", "de", true); | |
| 1156 infobar = GetTranslateInfoBar(); | |
| 1157 ASSERT_TRUE(infobar != NULL); | |
| 1158 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); | |
| 1159 if (i < 7) { | |
| 1160 EXPECT_FALSE(infobar->ShouldShowNeverTranslateButton()); | |
| 1161 infobar->TranslationDeclined(); | |
| 1162 } else { | |
| 1163 EXPECT_TRUE(infobar->ShouldShowNeverTranslateButton()); | |
| 1164 } | |
| 1165 if (i == 3) | |
| 1166 test_profile->set_off_the_record(false); | |
| 1167 } | |
| 1168 // Simulate the user pressing "Never translate French". | |
| 1169 infobar->NeverTranslatePageLanguage(); | |
| 1170 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("de")); | |
| 1171 // No translation should have occured and the infobar should be gone. | |
| 1172 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 1173 process()->sink().ClearMessages(); | |
| 1174 ASSERT_TRUE(GetTranslateInfoBar() == NULL); | |
| 1175 } | |
| 1176 | |
| 1177 // Tests that we don't show a translate infobar when a page instructs that it | |
| 1178 // should not be translated. | |
| 1179 TEST_F(TranslateManagerTest, NonTranslatablePage) { | |
| 1180 // Simulate navigating to a page. | |
| 1181 SimulateNavigation(GURL("http://mail.google.fr"), "Le Google", "fr", false); | |
| 1182 | |
| 1183 // We should not have an infobar. | |
| 1184 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
| 1185 | |
| 1186 // The context menu should be disabled. | |
| 1187 scoped_ptr<TestRenderViewContextMenu> menu( | |
| 1188 TestRenderViewContextMenu::CreateContextMenu(contents())); | |
| 1189 menu->Init(); | |
| 1190 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1191 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
| 1192 } | |
| 1193 | |
| 1194 // Tests that the script is expired and refetched as expected. | |
| 1195 TEST_F(TranslateManagerTest, ScriptExpires) { | |
| 1196 ExpireTranslateScriptImmediately(); | |
| 1197 | |
| 1198 // Simulate navigating to a page and translating it. | |
| 1199 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
| 1200 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
| 1201 ASSERT_TRUE(infobar != NULL); | |
| 1202 process()->sink().ClearMessages(); | |
| 1203 infobar->Translate(); | |
| 1204 SimulateURLFetch(true); | |
| 1205 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
| 1206 TranslateErrors::NONE)); | |
| 1207 | |
| 1208 // A task should have been posted to clear the script, run it. | |
| 1209 MessageLoop::current()->RunAllPending(); | |
| 1210 | |
| 1211 // Do another navigation and translation. | |
| 1212 SimulateNavigation(GURL("http://www.google.es"), "El Google", "es", true); | |
| 1213 infobar = GetTranslateInfoBar(); | |
| 1214 ASSERT_TRUE(infobar != NULL); | |
| 1215 process()->sink().ClearMessages(); | |
| 1216 infobar->Translate(); | |
| 1217 // If we don't simulate the URL fetch, the TranslateManager should be waiting | |
| 1218 // for the script and no message should have been sent to the renderer. | |
| 1219 EXPECT_TRUE( | |
| 1220 process()->sink().GetFirstMessageMatching(ViewMsg_TranslatePage::ID) == | |
| 1221 NULL); | |
| 1222 // Now simulate the URL fetch. | |
| 1223 SimulateURLFetch(true); | |
| 1224 // Now the message should have been sent. | |
| 1225 int page_id = 0; | |
| 1226 std::string original_lang, target_lang; | |
| 1227 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
| 1228 EXPECT_EQ("es", original_lang); | |
| 1229 EXPECT_EQ("en", target_lang); | |
| 1230 } | |
| OLD | NEW |