| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <stddef.h> |
| |
| #include <memory> |
| #include <set> |
| #include <tuple> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/command_line.h" |
| #include "base/macros.h" |
| #include "base/run_loop.h" |
| #include "base/scoped_observer.h" |
| #include "base/stl_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "build/build_config.h" |
| #include "chrome/app/chrome_command_ids.h" |
| #include "chrome/browser/extensions/test_extension_system.h" |
| #include "chrome/browser/infobars/infobar_service.h" |
| #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" |
| #include "chrome/browser/translate/chrome_translate_client.h" |
| #include "chrome/browser/translate/translate_service.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/browser/ui/translate/translate_bubble_factory.h" |
| #include "chrome/browser/ui/translate/translate_bubble_model.h" |
| #include "chrome/browser/ui/translate/translate_bubble_model_impl.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| #include "chrome/test/base/testing_browser_process.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "components/infobars/core/infobar.h" |
| #include "components/infobars/core/infobar_manager.h" |
| #include "components/prefs/pref_change_registrar.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/translate/content/browser/content_translate_driver.h" |
| #include "components/translate/content/common/translate.mojom.h" |
| #include "components/translate/core/browser/translate_accept_languages.h" |
| #include "components/translate/core/browser/translate_download_manager.h" |
| #include "components/translate/core/browser/translate_infobar_delegate.h" |
| #include "components/translate/core/browser/translate_language_list.h" |
| #include "components/translate/core/browser/translate_manager.h" |
| #include "components/translate/core/browser/translate_pref_names.h" |
| #include "components/translate/core/browser/translate_prefs.h" |
| #include "components/translate/core/browser/translate_script.h" |
| #include "components/translate/core/browser/translate_ui_delegate.h" |
| #include "components/translate/core/common/language_detection_details.h" |
| #include "content/public/browser/navigation_details.h" |
| #include "content/public/browser/navigation_entry.h" |
| #include "content/public/browser/notification_details.h" |
| #include "content/public/browser/notification_registrar.h" |
| #include "content/public/browser/notification_types.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/browser_side_navigation_policy.h" |
| #include "content/public/common/url_constants.h" |
| #include "content/public/test/navigation_simulator.h" |
| #include "content/public/test/test_renderer_host.h" |
| #include "mojo/public/cpp/bindings/binding.h" |
| #include "net/base/net_errors.h" |
| #include "net/url_request/test_url_fetcher_factory.h" |
| #include "net/url_request/url_fetcher_delegate.h" |
| #include "net/url_request/url_request_status.h" |
| #include "net/url_request/url_request_test_util.h" |
| #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" |
| #include "services/network/test/test_url_loader_factory.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "third_party/blink/public/web/web_context_menu_data.h" |
| #include "ui/base/page_transition_types.h" |
| #include "url/gurl.h" |
| |
| namespace { |
| |
| class MockTranslateBubbleFactory : public TranslateBubbleFactory { |
| public: |
| MockTranslateBubbleFactory() {} |
| |
| ShowTranslateBubbleResult ShowImplementation( |
| BrowserWindow* window, |
| content::WebContents* web_contents, |
| translate::TranslateStep step, |
| translate::TranslateErrors::Type error_type) override { |
| if (model_) { |
| model_->SetViewState( |
| TranslateBubbleModelImpl::TranslateStepToViewState(step)); |
| return ShowTranslateBubbleResult::SUCCESS; |
| } |
| |
| ChromeTranslateClient* chrome_translate_client = |
| ChromeTranslateClient::FromWebContents(web_contents); |
| std::string source_language = |
| chrome_translate_client->GetLanguageState().original_language(); |
| std::string target_language = |
| translate::TranslateDownloadManager::GetLanguageCode( |
| g_browser_process->GetApplicationLocale()); |
| |
| std::unique_ptr<translate::TranslateUIDelegate> ui_delegate( |
| new translate::TranslateUIDelegate( |
| chrome_translate_client->GetTranslateManager()->GetWeakPtr(), |
| source_language, target_language)); |
| model_.reset(new TranslateBubbleModelImpl(step, std::move(ui_delegate))); |
| return ShowTranslateBubbleResult::SUCCESS; |
| } |
| |
| bool DismissBubble() { |
| if (!model_) |
| return false; |
| model_->DeclineTranslation(); |
| model_->OnBubbleClosing(); |
| model_.reset(); |
| return true; |
| } |
| |
| TranslateBubbleModel* model() { return model_.get(); } |
| |
| private: |
| std::unique_ptr<TranslateBubbleModel> model_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MockTranslateBubbleFactory); |
| }; |
| |
| class FakePageImpl : public translate::mojom::Page { |
| public: |
| FakePageImpl() |
| : called_translate_(false), |
| called_revert_translation_(false), |
| binding_(this) {} |
| ~FakePageImpl() override {} |
| |
| translate::mojom::PagePtr BindToNewPagePtr() { |
| binding_.Close(); |
| translate_callback_pending_.Reset(); |
| translate::mojom::PagePtr page; |
| binding_.Bind(mojo::MakeRequest(&page)); |
| return page; |
| } |
| |
| // translate::mojom::Page implementation. |
| void Translate(const std::string& translate_script, |
| const std::string& source_lang, |
| const std::string& target_lang, |
| TranslateCallback callback) override { |
| // Ensure pending callback gets called. |
| if (translate_callback_pending_) { |
| std::move(translate_callback_pending_) |
| .Run(true, "", "", translate::TranslateErrors::NONE); |
| } |
| |
| called_translate_ = true; |
| source_lang_ = source_lang; |
| target_lang_ = target_lang; |
| |
| translate_callback_pending_ = std::move(callback); |
| } |
| |
| void RevertTranslation() override { called_revert_translation_ = true; } |
| |
| void PageTranslated(bool cancelled, |
| const std::string& source_lang, |
| const std::string& target_lang, |
| translate::TranslateErrors::Type error) { |
| std::move(translate_callback_pending_) |
| .Run(cancelled, source_lang, target_lang, error); |
| } |
| |
| bool called_translate_; |
| base::Optional<std::string> source_lang_; |
| base::Optional<std::string> target_lang_; |
| bool called_revert_translation_; |
| |
| private: |
| TranslateCallback translate_callback_pending_; |
| |
| mojo::Binding<translate::mojom::Page> binding_; |
| |
| DISALLOW_COPY_AND_ASSIGN(FakePageImpl); |
| }; |
| |
| } // namespace |
| |
| // An observer that keeps track of whether a navigation entry was committed. |
| class NavEntryCommittedObserver : public content::NotificationObserver { |
| public: |
| explicit NavEntryCommittedObserver(content::WebContents* web_contents) { |
| registrar_.Add(this, |
| content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| content::Source<content::NavigationController>( |
| &web_contents->GetController())); |
| } |
| |
| void Observe(int type, |
| const content::NotificationSource& source, |
| const content::NotificationDetails& details) override { |
| DCHECK(type == content::NOTIFICATION_NAV_ENTRY_COMMITTED); |
| details_ = |
| *(content::Details<content::LoadCommittedDetails>(details).ptr()); |
| } |
| |
| const content::LoadCommittedDetails& load_committed_details() const { |
| return details_; |
| } |
| |
| private: |
| content::LoadCommittedDetails details_; |
| content::NotificationRegistrar registrar_; |
| |
| DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver); |
| }; |
| |
| class TranslateManagerRenderViewHostTest |
| : public ChromeRenderViewHostTestHarness, |
| public infobars::InfoBarManager::Observer { |
| public: |
| TranslateManagerRenderViewHostTest() |
| : pref_callback_( |
| base::Bind(&TranslateManagerRenderViewHostTest::OnPreferenceChanged, |
| base::Unretained(this))), |
| test_shared_loader_factory_( |
| base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( |
| &test_url_loader_factory_)), |
| infobar_observer_(this) {} |
| |
| #if !defined(USE_AURA) && !defined(OS_MACOSX) |
| // Ensure that we are testing under the bubble UI. |
| // TODO(groby): Remove once the bubble is enabled by default everywhere. |
| // http://crbug.com/507442 |
| void EnableBubbleTest() { |
| if (TranslateService::IsTranslateBubbleEnabled()) { |
| bubble_factory_.reset(new MockTranslateBubbleFactory); |
| TranslateBubbleFactory::SetFactory(bubble_factory_.get()); |
| } |
| } |
| |
| bool TranslateUiVisible() { |
| if (bubble_factory_) { |
| TranslateBubbleModel* bubble = bubble_factory_->model(); |
| return bubble != nullptr; |
| } else { |
| bool result = (GetTranslateInfoBar() != nullptr); |
| EXPECT_EQ(infobar_service()->infobar_count() != 0, result); |
| return result; |
| } |
| } |
| |
| bool CloseTranslateUi() { |
| if (bubble_factory_) { |
| return bubble_factory_->DismissBubble(); |
| } else { |
| return CloseTranslateInfoBar(); |
| } |
| } |
| |
| void SimulateTranslatePress() { |
| // Simulate the user translating. |
| if (bubble_factory_.get()) { |
| bubble_factory_->model()->Translate(); |
| } else { |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != nullptr); |
| infobar->Translate(); |
| } |
| } |
| |
| translate::TranslateStep CurrentStep() { |
| if (bubble_factory_.get()) { |
| TranslateBubbleModel::ViewState view_state = |
| bubble_factory_->model()->GetViewState(); |
| switch (view_state) { |
| case TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE: |
| return translate::TRANSLATE_STEP_BEFORE_TRANSLATE; |
| case TranslateBubbleModel::VIEW_STATE_TRANSLATING: |
| return translate::TRANSLATE_STEP_TRANSLATING; |
| case TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE: |
| return translate::TRANSLATE_STEP_AFTER_TRANSLATE; |
| case TranslateBubbleModel::VIEW_STATE_ERROR: |
| return translate::TRANSLATE_STEP_TRANSLATE_ERROR; |
| case TranslateBubbleModel::VIEW_STATE_ADVANCED: |
| NOTREACHED(); |
| break; |
| } |
| NOTREACHED(); |
| return translate::TRANSLATE_STEP_TRANSLATE_ERROR; |
| } else { |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| return infobar->translate_step(); |
| } |
| } |
| #endif // defined(USE_AURA) && !defined(OS_MACOSX) |
| |
| // Simulates navigating to a page and getting the page contents and language |
| // for that navigation. |
| void SimulateNavigation(const GURL& url, |
| const std::string& lang, |
| bool page_translatable) { |
| if (main_rfh()->GetLastCommittedURL() == url) { |
| content::NavigationSimulator::Reload(web_contents()); |
| } else { |
| content::NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(), |
| url); |
| } |
| SimulateOnTranslateLanguageDetermined(lang, page_translatable); |
| } |
| |
| void SimulateOnTranslateLanguageDetermined(const std::string& lang, |
| bool page_translatable) { |
| translate::LanguageDetectionDetails details; |
| details.adopted_language = lang; |
| ChromeTranslateClient::FromWebContents(web_contents()) |
| ->translate_driver() |
| .OnPageReady(fake_page_.BindToNewPagePtr(), details, page_translatable); |
| } |
| |
| void SimulateOnPageTranslated(const std::string& source_lang, |
| const std::string& target_lang, |
| translate::TranslateErrors::Type error) { |
| // Ensure fake_page_ Translate() call gets dispatched. |
| base::RunLoop().RunUntilIdle(); |
| |
| fake_page_.PageTranslated(false, source_lang, target_lang, error); |
| |
| // Ensure fake_page_ Translate() response callback gets dispatched. |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| void SimulateOnPageTranslated(const std::string& source_lang, |
| const std::string& target_lang) { |
| SimulateOnPageTranslated(source_lang, target_lang, |
| translate::TranslateErrors::NONE); |
| } |
| |
| bool GetTranslateMessage(std::string* original_lang, |
| std::string* target_lang) { |
| base::RunLoop().RunUntilIdle(); |
| |
| if (!fake_page_.called_translate_) |
| return false; |
| EXPECT_TRUE(fake_page_.source_lang_); |
| EXPECT_TRUE(fake_page_.target_lang_); |
| |
| if (original_lang) |
| *original_lang = *fake_page_.source_lang_; |
| if (target_lang) |
| *target_lang = *fake_page_.target_lang_; |
| |
| // Reset |
| fake_page_.called_translate_ = false; |
| fake_page_.source_lang_ = base::nullopt; |
| fake_page_.target_lang_ = base::nullopt; |
| |
| return true; |
| } |
| |
| bool IsTranslationReverted() { |
| base::RunLoop().RunUntilIdle(); |
| return fake_page_.called_revert_translation_; |
| } |
| |
| InfoBarService* infobar_service() { |
| return InfoBarService::FromWebContents(web_contents()); |
| } |
| |
| // Returns the translate infobar if there is 1 infobar and it is a translate |
| // infobar. |
| translate::TranslateInfoBarDelegate* GetTranslateInfoBar() { |
| return (infobar_service()->infobar_count() == 1) ? |
| infobar_service()->infobar_at(0)->delegate()-> |
| AsTranslateInfoBarDelegate() : |
| NULL; |
| } |
| |
| #if !defined(USE_AURA) && !defined(OS_MACOSX) |
| // If there is 1 infobar and it is a translate infobar, closes it and returns |
| // true. Returns false otherwise. |
| bool CloseTranslateInfoBar() { |
| infobars::InfoBarDelegate* infobar = GetTranslateInfoBar(); |
| if (!infobar) |
| return false; |
| infobar->InfoBarDismissed(); // Simulates closing the infobar. |
| infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0)); |
| return true; |
| } |
| |
| // Checks whether |infobar| has been removed and clears the removed infobar |
| // list. |
| bool CheckInfoBarRemovedAndReset(infobars::InfoBarDelegate* delegate) { |
| bool found = removed_infobars_.count(delegate) != 0; |
| removed_infobars_.clear(); |
| return found; |
| } |
| |
| void ExpireTranslateScriptImmediately() { |
| translate::TranslateDownloadManager::GetInstance() |
| ->SetTranslateScriptExpirationDelay(0); |
| } |
| |
| // If there is 1 infobar and it is a translate infobar, deny translation and |
| // returns true. Returns false otherwise. |
| bool DenyTranslation() { |
| if (bubble_factory_.get()) { |
| return bubble_factory_->DismissBubble(); |
| } else { |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| if (!infobar) |
| return false; |
| infobar->TranslationDeclined(); |
| infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0)); |
| return true; |
| } |
| } |
| #endif // defined(USE_AURA) && !defined(OS_MACOSX) |
| |
| void ReloadAndWait(bool successful_reload) { |
| NavEntryCommittedObserver nav_observer(web_contents()); |
| if (successful_reload) { |
| content::NavigationSimulator::Reload(web_contents()); |
| } else { |
| content::NavigationSimulator::ReloadAndFail(web_contents(), |
| net::ERR_TIMED_OUT); |
| } |
| |
| // Ensures it is really handled a reload. |
| const content::LoadCommittedDetails& nav_details = |
| nav_observer.load_committed_details(); |
| EXPECT_TRUE(nav_details.entry); // There was a navigation. |
| EXPECT_TRUE(ui::PageTransitionCoreTypeIs( |
| ui::PAGE_TRANSITION_RELOAD, nav_details.entry->GetTransitionType())); |
| |
| // The TranslateManager class processes the navigation entry committed |
| // notification in a posted task; process that task. |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TestRenderViewContextMenu* CreateContextMenu() { |
| content::ContextMenuParams params; |
| params.media_type = blink::WebContextMenuData::kMediaTypeNone; |
| params.x = 0; |
| params.y = 0; |
| params.has_image_contents = true; |
| params.media_flags = 0; |
| params.spellcheck_enabled = false; |
| params.is_editable = false; |
| params.page_url = |
| web_contents()->GetController().GetLastCommittedEntry()->GetURL(); |
| #if defined(OS_MACOSX) |
| params.writing_direction_default = 0; |
| params.writing_direction_left_to_right = 0; |
| params.writing_direction_right_to_left = 0; |
| #endif // OS_MACOSX |
| params.edit_flags = blink::WebContextMenuData::kCanTranslate; |
| return new TestRenderViewContextMenu(web_contents()->GetMainFrame(), |
| params); |
| } |
| |
| void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override { |
| removed_infobars_.insert(infobar->delegate()); |
| } |
| |
| void OnManagerShuttingDown(infobars::InfoBarManager* manager) override { |
| infobar_observer_.Remove(manager); |
| } |
| |
| MOCK_METHOD1(OnPreferenceChanged, void(const std::string&)); |
| |
| protected: |
| void SetUp() override { |
| // Setup the test environment, including the threads and message loops. This |
| // must be done before base::ThreadTaskRunnerHandle::Get() is called when |
| // setting up the net::TestURLRequestContextGetter below. |
| ChromeRenderViewHostTestHarness::SetUp(); |
| |
| // Clears the translate script so it is fetched every time and sets the |
| // expiration delay to a large value by default (in case it was zeroed in a |
| // previous test). |
| TranslateService::InitializeForTesting( |
| network::mojom::ConnectionType::CONNECTION_WIFI); |
| translate::TranslateDownloadManager* download_manager = |
| translate::TranslateDownloadManager::GetInstance(); |
| download_manager->ClearTranslateScriptForTesting(); |
| download_manager->SetTranslateScriptExpirationDelay(60 * 60 * 1000); |
| download_manager->set_url_loader_factory(test_shared_loader_factory_); |
| |
| InfoBarService::CreateForWebContents(web_contents()); |
| ChromeTranslateClient::CreateForWebContents(web_contents()); |
| ChromeTranslateClient::FromWebContents(web_contents()) |
| ->translate_driver() |
| .set_translate_max_reload_attempts(0); |
| |
| infobar_observer_.Add(infobar_service()); |
| } |
| |
| void TearDown() override { |
| infobar_observer_.Remove(infobar_service()); |
| |
| ChromeRenderViewHostTestHarness::TearDown(); |
| TranslateService::ShutdownForTesting(); |
| } |
| |
| void SimulateTranslateScriptURLFetch(bool success) { |
| GURL url = translate::TranslateDownloadManager::GetInstance() |
| ->script() |
| ->GetTranslateScriptURL(); |
| test_url_loader_factory_.AddResponse( |
| url.spec(), std::string(), |
| success ? net::HTTP_OK : net::HTTP_INTERNAL_SERVER_ERROR); |
| base::RunLoop().RunUntilIdle(); |
| |
| test_url_loader_factory_.ClearResponses(); |
| } |
| |
| void SimulateSupportedLanguagesURLFetch( |
| bool success, |
| const std::vector<std::string>& languages) { |
| std::string data; |
| if (success) { |
| data = base::StringPrintf( |
| "{\"sl\": {\"bla\": \"bla\"}, \"%s\": {", |
| translate::TranslateLanguageList::kTargetLanguagesKey); |
| const char* comma = ""; |
| for (size_t i = 0; i < languages.size(); ++i) { |
| data += base::StringPrintf( |
| "%s\"%s\": \"UnusedFullName\"", comma, languages[i].c_str()); |
| if (i == 0) |
| comma = ","; |
| } |
| data += "}}"; |
| } |
| GURL url = translate::TranslateDownloadManager::GetInstance() |
| ->language_list() |
| ->LanguageFetchURLForTesting(); |
| EXPECT_TRUE(test_url_loader_factory_.IsPending(url.spec())); |
| test_url_loader_factory_.AddResponse( |
| url.spec(), data, |
| success ? net::HTTP_OK : net::HTTP_INTERNAL_SERVER_ERROR); |
| EXPECT_FALSE(test_url_loader_factory_.IsPending(url.spec())); |
| base::RunLoop().RunUntilIdle(); |
| |
| test_url_loader_factory_.ClearResponses(); |
| } |
| |
| void SetPrefObserverExpectation(const char* path) { |
| EXPECT_CALL(*this, OnPreferenceChanged(std::string(path))); |
| } |
| |
| PrefChangeRegistrar::NamedChangeCallback pref_callback_; |
| |
| private: |
| network::TestURLLoaderFactory test_url_loader_factory_; |
| scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; |
| |
| // The infobars that have been removed. |
| // WARNING: the pointers point to deleted objects, use only for comparison. |
| std::set<infobars::InfoBarDelegate*> removed_infobars_; |
| |
| std::unique_ptr<MockTranslateBubbleFactory> bubble_factory_; |
| FakePageImpl fake_page_; |
| |
| ScopedObserver<infobars::InfoBarManager, infobars::InfoBarManager::Observer> |
| infobar_observer_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TranslateManagerRenderViewHostTest); |
| }; |
| |
| // A variant of the above test class that sets the UI language to an invalid |
| // code (and restores it afterwards). This is required because a significant |
| // amount of logic using the UI language has already occured by the time we |
| // enter an individual test body. |
| |
| static const char* kInvalidLocale = "qbz"; |
| class TranslateManagerRenderViewHostInvalidLocaleTest |
| : public TranslateManagerRenderViewHostTest { |
| public: |
| TranslateManagerRenderViewHostInvalidLocaleTest() |
| : original_locale_(g_browser_process->GetApplicationLocale()) { |
| SetApplicationLocale(kInvalidLocale); |
| } |
| |
| ~TranslateManagerRenderViewHostInvalidLocaleTest() override { |
| SetApplicationLocale(original_locale_); |
| } |
| |
| private: |
| const std::string original_locale_; |
| |
| void SetApplicationLocale(const std::string& locale) { |
| g_browser_process->SetApplicationLocale(locale); |
| translate::TranslateDownloadManager::GetInstance()->set_application_locale( |
| g_browser_process->GetApplicationLocale()); |
| } |
| |
| DISALLOW_COPY_AND_ASSIGN(TranslateManagerRenderViewHostInvalidLocaleTest); |
| }; |
| |
| // A list of languages to fake being returned by the translate server. |
| // Use only langauges for which Chrome's copy of ICU has |
| // display names in English locale. To save space, Chrome's copy of ICU |
| // does not have the display name for a language unless it's in the |
| // Accept-Language list. |
| static const char* kServerLanguageList[] = { |
| "ach", "ak", "af", "en-CA", "zh", "yi", "fr-FR", "tl", "iw", "in", "xx"}; |
| |
| // Test the fetching of languages from the translate server |
| TEST_F(TranslateManagerRenderViewHostTest, FetchLanguagesFromTranslateServer) { |
| std::vector<std::string> server_languages; |
| for (size_t i = 0; i < arraysize(kServerLanguageList); ++i) |
| server_languages.push_back(kServerLanguageList[i]); |
| |
| // First, get the default languages list. Note that calling |
| // GetSupportedLanguages() invokes RequestLanguageList() internally. |
| std::vector<std::string> default_supported_languages; |
| translate::TranslateDownloadManager::GetSupportedLanguages( |
| true /* translate_allowed */, &default_supported_languages); |
| // To make sure we got the defaults and don't confuse them with the mocks. |
| ASSERT_NE(default_supported_languages.size(), server_languages.size()); |
| |
| // Check that we still get the defaults until the URLFetch has completed. |
| std::vector<std::string> current_supported_languages; |
| translate::TranslateDownloadManager::GetSupportedLanguages( |
| true /* translate_allowed */, ¤t_supported_languages); |
| EXPECT_EQ(default_supported_languages, current_supported_languages); |
| |
| // Also check that it didn't change if we failed the URL fetch. |
| SimulateSupportedLanguagesURLFetch(false, std::vector<std::string>()); |
| current_supported_languages.clear(); |
| translate::TranslateDownloadManager::GetSupportedLanguages( |
| true /* translate_allowed */, ¤t_supported_languages); |
| EXPECT_EQ(default_supported_languages, current_supported_languages); |
| |
| // Now check that we got the appropriate set of languages from the server. |
| SimulateSupportedLanguagesURLFetch(true, server_languages); |
| current_supported_languages.clear(); |
| translate::TranslateDownloadManager::GetSupportedLanguages( |
| true /* translate_allowed */, ¤t_supported_languages); |
| // "xx" can't be displayed in the Translate infobar, so this is eliminated. |
| EXPECT_EQ(server_languages.size() - 1, current_supported_languages.size()); |
| // Not sure we need to guarantee the order of languages, so we find them. |
| for (size_t i = 0; i < server_languages.size(); ++i) { |
| const std::string& lang = server_languages[i]; |
| if (lang == "xx") |
| continue; |
| EXPECT_TRUE(base::ContainsValue(current_supported_languages, lang)) |
| << "lang=" << lang; |
| } |
| } |
| |
| // The following tests depend on the translate infobar. They should be ported to |
| // use the translate bubble. On Aura there is no infobar so the tests are not |
| // compiled. |
| #if !defined(USE_AURA) && !defined(OS_MACOSX) |
| TEST_F(TranslateManagerRenderViewHostTest, NormalTranslate) { |
| // See BubbleNormalTranslate for corresponding bubble UX testing. |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| // http://crbug.com/695624 |
| return; |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| // We should have an infobar. |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, |
| infobar->translate_step()); |
| |
| // Simulate clicking translate. |
| infobar->Translate(); |
| |
| // The "Translating..." infobar should be showing. |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATING, infobar->translate_step()); |
| |
| // Simulate the translate script being retrieved (it only needs to be done |
| // once in the test as it is cached). |
| SimulateTranslateScriptURLFetch(true); |
| |
| // Test that we sent the right message to the renderer. |
| std::string original_lang, target_lang; |
| EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); |
| EXPECT_EQ("fr", original_lang); |
| EXPECT_EQ("en", target_lang); |
| |
| // Simulate the render notifying the translation has been done. |
| SimulateOnPageTranslated("fr", "en"); |
| |
| // The after translate infobar should be showing. |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_AFTER_TRANSLATE, |
| infobar->translate_step()); |
| |
| // Simulate changing the original language and translating. |
| std::string new_original_lang = infobar->language_code_at(0); |
| infobar->UpdateOriginalLanguage(new_original_lang); |
| infobar->Translate(); |
| EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); |
| EXPECT_EQ(new_original_lang, original_lang); |
| EXPECT_EQ("en", target_lang); |
| // Simulate the render notifying the translation has been done. |
| SimulateOnPageTranslated(new_original_lang, "en"); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| |
| // Simulate changing the target language and translating. |
| std::string new_target_lang = infobar->language_code_at(1); |
| infobar->UpdateTargetLanguage(new_target_lang); |
| infobar->Translate(); |
| EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); |
| EXPECT_EQ(new_original_lang, original_lang); |
| EXPECT_EQ(new_target_lang, target_lang); |
| // Simulate the render notifying the translation has been done. |
| SimulateOnPageTranslated(new_original_lang, new_target_lang); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(new_target_lang, infobar->target_language_code()); |
| |
| // Reloading should trigger translation iff Always Translate is on. |
| ReloadAndWait(true); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, |
| infobar->translate_step()); |
| infobar->UpdateTargetLanguage(new_target_lang); |
| infobar->ToggleAlwaysTranslate(); |
| ReloadAndWait(true); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATING, infobar->translate_step()); |
| EXPECT_EQ(new_target_lang, infobar->target_language_code()); |
| } |
| |
| TEST_F(TranslateManagerRenderViewHostTest, TranslateScriptNotAvailable) { |
| // See BubbleTranslateScriptNotAvailable for corresponding bubble UX testing. |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| // We should have an infobar. |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, |
| infobar->translate_step()); |
| |
| // Simulate clicking translate. |
| infobar->Translate(); |
| SimulateTranslateScriptURLFetch(false); |
| |
| // We should not have sent any message to translate to the renderer. |
| EXPECT_FALSE(GetTranslateMessage(NULL, NULL)); |
| |
| // And we should have an error infobar showing. |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATE_ERROR, |
| infobar->translate_step()); |
| } |
| |
| // Ensures we deal correctly with pages for which the browser does not recognize |
| // the language (the translate server may or not detect the language). |
| TEST_F(TranslateManagerRenderViewHostTest, TranslateUnknownLanguage) { |
| // See BubbleUnknownLanguage for corresponding bubble UX testing. |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| // Simulate navigating to a page ("und" is the string returned by the CLD for |
| // languages it does not recognize). |
| SimulateNavigation(GURL("http://www.google.mys"), "und", true); |
| |
| // We should not have an infobar as we don't know the language. |
| ASSERT_TRUE(GetTranslateInfoBar() == NULL); |
| |
| // Translate the page anyway throught the context menu. |
| std::unique_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); |
| menu->Init(); |
| menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); |
| |
| // To test that bug #49018 if fixed, make sure we deal correctly with errors. |
| // Simulate a failure to fetch the translate script. |
| SimulateTranslateScriptURLFetch(false); |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATE_ERROR, |
| infobar->translate_step()); |
| EXPECT_TRUE(infobar->is_error()); |
| infobar->MessageInfoBarButtonPressed(); |
| SimulateTranslateScriptURLFetch(true); // This time succeed. |
| |
| // Simulate the render notifying the translation has been done, the server |
| // having detected the page was in a known and supported language. |
| SimulateOnPageTranslated("fr", "en"); |
| |
| // The after translate infobar should be showing. |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_AFTER_TRANSLATE, |
| infobar->translate_step()); |
| EXPECT_EQ("fr", infobar->original_language_code()); |
| EXPECT_EQ("en", infobar->target_language_code()); |
| |
| // Let's run the same steps but this time the server detects the page is |
| // already in English. |
| SimulateNavigation(GURL("http://www.google.com"), "und", true); |
| menu.reset(CreateContextMenu()); |
| menu->Init(); |
| menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); |
| SimulateOnPageTranslated("en", "en", |
| translate::TranslateErrors::IDENTICAL_LANGUAGES); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATE_ERROR, |
| infobar->translate_step()); |
| EXPECT_EQ(translate::TranslateErrors::IDENTICAL_LANGUAGES, |
| infobar->error_type()); |
| |
| // Let's run the same steps again but this time the server fails to detect the |
| // page's language (it returns an empty string). |
| SimulateNavigation(GURL("http://www.google.com"), "und", true); |
| menu.reset(CreateContextMenu()); |
| menu->Init(); |
| menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); |
| SimulateOnPageTranslated(std::string(), "en", |
| translate::TranslateErrors::UNKNOWN_LANGUAGE); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATE_ERROR, |
| infobar->translate_step()); |
| EXPECT_EQ(translate::TranslateErrors::UNKNOWN_LANGUAGE, |
| infobar->error_type()); |
| } |
| |
| // Tests that we show/don't show an info-bar for the languages. |
| TEST_F(TranslateManagerRenderViewHostTest, TestLanguages) { |
| // This only makes sense for infobars, because the check for supported |
| // languages moved out of the Infobar into the TranslateManager. |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| std::vector<std::string> languages; |
| languages.push_back("en"); |
| languages.push_back("ja"); |
| languages.push_back("fr"); |
| languages.push_back("ht"); |
| languages.push_back("xx"); |
| languages.push_back("zh"); |
| languages.push_back("zh-CN"); |
| languages.push_back("und"); |
| |
| GURL url("http://www.google.com"); |
| for (size_t i = 0; i < languages.size(); ++i) { |
| std::string lang = languages[i]; |
| SCOPED_TRACE(::testing::Message() << "Iteration " << i |
| << " language=" << lang); |
| |
| // We should not have a translate infobar. |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar == NULL); |
| |
| SimulateNavigation(url, lang, true); |
| |
| // Verify we have/don't have an info-bar as expected. |
| infobar = GetTranslateInfoBar(); |
| bool expected = |
| translate::TranslateDownloadManager::IsSupportedLanguage(lang) && |
| lang != "en"; |
| EXPECT_EQ(expected, infobar != NULL); |
| |
| if (infobar != NULL) |
| EXPECT_TRUE(CloseTranslateInfoBar()); |
| } |
| } |
| |
| // Tests auto-translate on page. |
| TEST_F(TranslateManagerRenderViewHostTest, AutoTranslateOnNavigate) { |
| EnableBubbleTest(); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| SimulateTranslatePress(); |
| SimulateTranslateScriptURLFetch(true); |
| SimulateOnPageTranslated("fr", "en"); |
| |
| // Now navigate to a new page in the same language. |
| SimulateNavigation(GURL("http://news.google.fr"), "fr", true); |
| |
| // This should have automatically triggered a translation. |
| std::string original_lang, target_lang; |
| EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); |
| EXPECT_EQ("fr", original_lang); |
| EXPECT_EQ("en", target_lang); |
| |
| // Now navigate to a page in a different language. |
| SimulateNavigation(GURL("http://news.google.es"), "es", true); |
| |
| // This should not have triggered a translate. |
| EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); |
| } |
| |
| // Tests that multiple OnPageContents do not cause multiple infobars. |
| TEST_F(TranslateManagerRenderViewHostTest, MultipleOnPageContents) { |
| EnableBubbleTest(); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| // Simulate clicking 'Nope' (don't translate). |
| EXPECT_TRUE(TranslateUiVisible()); |
| EXPECT_TRUE(DenyTranslation()); |
| EXPECT_FALSE(TranslateUiVisible()); |
| |
| // Send a new PageContents, we should not show the translate UI. |
| SimulateOnTranslateLanguageDetermined("fr", true); |
| EXPECT_FALSE(TranslateUiVisible()); |
| |
| // Do the same steps but simulate closing the infobar this time. |
| SimulateNavigation(GURL("http://www.youtube.de"), "de", true); |
| EXPECT_TRUE(TranslateUiVisible()); |
| EXPECT_TRUE(CloseTranslateUi()); |
| EXPECT_FALSE(TranslateUiVisible()); |
| SimulateOnTranslateLanguageDetermined("de", true); |
| EXPECT_FALSE(TranslateUiVisible()); |
| } |
| |
| // Test that reloading the page brings back the infobar if the |
| // reload succeeded and does not bring it back the reload fails. |
| TEST_F(TranslateManagerRenderViewHostTest, Reload) { |
| EnableBubbleTest(); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| EXPECT_TRUE(CloseTranslateUi()); |
| |
| // Reload should bring back the infobar if the reload succeeds. |
| ReloadAndWait(true); |
| EXPECT_TRUE(TranslateUiVisible()); |
| EXPECT_TRUE(CloseTranslateUi()); |
| |
| // ...But not show it if the reload fails. |
| ReloadAndWait(false); |
| EXPECT_FALSE(TranslateUiVisible()); |
| |
| // If we set reload attempts to a high value, we will not see the infobar |
| // immediately. |
| ChromeTranslateClient::FromWebContents(web_contents()) |
| ->translate_driver() |
| .set_translate_max_reload_attempts(100); |
| ReloadAndWait(true); |
| EXPECT_FALSE(TranslateUiVisible()); |
| } |
| |
| // Test that reloading the page by way of typing again the URL in the |
| // location bar brings back the infobar. |
| TEST_F(TranslateManagerRenderViewHostTest, ReloadFromLocationBar) { |
| EnableBubbleTest(); |
| |
| GURL url("http://www.google.fr"); |
| SimulateNavigation(url, "fr", true); |
| |
| EXPECT_TRUE(CloseTranslateUi()); |
| |
| // Create a pending navigation and simulate a page load. That should be the |
| // equivalent of typing the URL again in the location bar. |
| NavEntryCommittedObserver nav_observer(web_contents()); |
| web_contents()->GetController().LoadURL( |
| url, content::Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); |
| int pending_id = |
| web_contents()->GetController().GetPendingEntry()->GetUniqueID(); |
| content::RenderFrameHostTester::For(web_contents()->GetMainFrame()) |
| ->SendNavigateWithTransition(pending_id, false, url, |
| ui::PAGE_TRANSITION_TYPED); |
| |
| // Test that we are really getting a same page navigation, the test would be |
| // useless if it was not the case. |
| const content::LoadCommittedDetails& nav_details = |
| nav_observer.load_committed_details(); |
| EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation. |
| EXPECT_EQ(content::NAVIGATION_TYPE_SAME_PAGE, nav_details.type); |
| |
| // The TranslateManager class processes the navigation entry committed |
| // notification in a posted task; process that task. |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_TRUE(CloseTranslateUi()); |
| } |
| |
| // Tests that a closed translate infobar does not reappear when performing |
| // same-document navigation. |
| TEST_F(TranslateManagerRenderViewHostTest, CloseInfoBarSameDocumentNavigation) { |
| EnableBubbleTest(); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| EXPECT_TRUE(CloseTranslateUi()); |
| |
| // For same-document, no infobar should be shown. |
| SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); |
| EXPECT_FALSE(TranslateUiVisible()); |
| |
| // This is deliberately different behavior for bubbles - same language |
| // navigation does not show a bubble, ever. Blame ChromeTranslateClient. |
| if (!TranslateService::IsTranslateBubbleEnabled()) { |
| // Navigate out of page, a new infobar should show. |
| SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); |
| EXPECT_TRUE(TranslateUiVisible()); |
| } |
| } |
| |
| // Tests that a closed translate infobar does not reappear when navigating |
| // in a subframe. (http://crbug.com/48215) |
| TEST_F(TranslateManagerRenderViewHostTest, CloseInfoBarInSubframeNavigation) { |
| EnableBubbleTest(); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| EXPECT_TRUE(CloseTranslateUi()); |
| |
| content::RenderFrameHostTester* subframe_tester = |
| content::RenderFrameHostTester::For( |
| content::RenderFrameHostTester::For(main_rfh()) |
| ->AppendChild("subframe")); |
| |
| // Simulate a sub-frame auto-navigating. |
| subframe_tester->SendNavigateWithTransition( |
| 0, false, GURL("http://pub.com"), ui::PAGE_TRANSITION_AUTO_SUBFRAME); |
| EXPECT_FALSE(TranslateUiVisible()); |
| |
| // Simulate the user navigating in a sub-frame. |
| subframe_tester->SendNavigateWithTransition( |
| 1, true, GURL("http://pub.com"), ui::PAGE_TRANSITION_MANUAL_SUBFRAME); |
| EXPECT_FALSE(TranslateUiVisible()); |
| |
| // This is deliberately different behavior for bubbles - same language |
| // navigation does not show a bubble, ever. Blame ChromeTranslateClient. |
| if (!TranslateService::IsTranslateBubbleEnabled()) { |
| // Navigate out of page, a new infobar should show. |
| SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); |
| EXPECT_TRUE(TranslateUiVisible()); |
| } |
| } |
| |
| // Tests that denying translation is sticky when performing same-document |
| // navigation. |
| TEST_F(TranslateManagerRenderViewHostTest, |
| DenyTranslateSameDocumentNavigation) { |
| EnableBubbleTest(); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| // Simulate clicking 'Nope' (don't translate). |
| EXPECT_TRUE(DenyTranslation()); |
| |
| // Same-document navigation, no infobar should be shown. |
| SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); |
| EXPECT_FALSE(TranslateUiVisible()); |
| |
| // Navigate to a new document, a new infobar should show. (Infobar only). |
| SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); |
| EXPECT_NE(TranslateService::IsTranslateBubbleEnabled(), TranslateUiVisible()); |
| } |
| |
| // Tests that after translating and closing the infobar, the infobar does not |
| // return for same-document navigation. |
| TEST_F(TranslateManagerRenderViewHostTest, |
| TranslateCloseInfoBarSameDocumentNavigation) { |
| EnableBubbleTest(); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| // Simulate the user translating. |
| SimulateTranslatePress(); |
| |
| // Simulate the translate script being retrieved. |
| SimulateTranslateScriptURLFetch(true); |
| SimulateOnPageTranslated("fr", "en"); |
| |
| EXPECT_TRUE(CloseTranslateUi()); |
| |
| // Same-document navigation, no infobar should be shown. |
| SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); |
| EXPECT_FALSE(TranslateUiVisible()); |
| |
| // Navigate to a new document, a new infobar should show. |
| // Note that we navigate to a page in a different language so we don't trigger |
| // the auto-translate feature (it would translate the page automatically and |
| // the before translate infobar would not be shown). |
| SimulateNavigation(GURL("http://www.google.de"), "de", true); |
| EXPECT_TRUE(TranslateUiVisible()); |
| } |
| |
| // Tests that the after translate the infobar still shows when performing |
| // same-document navigation. |
| TEST_F(TranslateManagerRenderViewHostTest, TranslateSameDocumentNavigation) { |
| EnableBubbleTest(); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| // Simulate the user translating. |
| SimulateTranslatePress(); |
| SimulateTranslateScriptURLFetch(true); |
| SimulateOnPageTranslated("fr", "en"); |
| // The after translate UI is showing. |
| EXPECT_TRUE(TranslateUiVisible()); |
| |
| // Remember infobar, so removal can be verified. |
| translate::TranslateInfoBarDelegate* infobar = nullptr; |
| if (!TranslateService::IsTranslateBubbleEnabled()) |
| infobar = GetTranslateInfoBar(); |
| |
| // Navigate to a new document, a new infobar should show. |
| // See note in TranslateCloseInfoBarSameDocumentNavigation test on why it is |
| // important to navigate to a page in a different language for this test. |
| SimulateNavigation(GURL("http://www.google.de"), "de", true); |
| // The old infobar is gone. Can't verify this for bubbles. |
| // Also, does not apply - existing bubbles are reused. |
| if (!TranslateService::IsTranslateBubbleEnabled()) |
| EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar)); |
| // And there is a new one. |
| EXPECT_TRUE(TranslateUiVisible()); |
| } |
| |
| // Tests that no translate infobar is shown when navigating to a page in an |
| // unsupported language. |
| TEST_F(TranslateManagerRenderViewHostTest, CLDReportsUnsupportedPageLanguage) { |
| EnableBubbleTest(); |
| |
| // Simulate navigating to a page and getting an unsupported language. |
| SimulateNavigation(GURL("http://www.google.com"), kInvalidLocale, true); |
| |
| // No info-bar should be shown. |
| EXPECT_FALSE(TranslateUiVisible()); |
| } |
| |
| // Tests that we deal correctly with unsupported languages returned by the |
| // server. |
| // The translation server might return a language we don't support. |
| TEST_F(TranslateManagerRenderViewHostTest, ServerReportsUnsupportedLanguage) { |
| EnableBubbleTest(); |
| |
| SimulateNavigation(GURL("http://mail.google.fr"), "fr", true); |
| SimulateTranslatePress(); |
| SimulateTranslateScriptURLFetch(true); |
| // Simulate the render notifying the translation has been done, but it |
| // reports a language we don't support. |
| SimulateOnPageTranslated(kInvalidLocale, "en"); |
| |
| // An error infobar should be showing to report that we don't support this |
| // language. |
| EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATE_ERROR, CurrentStep()); |
| |
| // This infobar should have a button (so the string should not be empty). |
| // The error string on bubbles is currently not retrievable. |
| // TODO(http://crbug.com/589301): OSX does not have an error view (yet). |
| if (!TranslateService::IsTranslateBubbleEnabled()) { |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar); |
| ASSERT_FALSE(infobar->GetMessageInfoBarButtonText().empty()); |
| |
| // Pressing the button on that infobar should revert to the original |
| // language. |
| infobar->MessageInfoBarButtonPressed(); |
| EXPECT_TRUE(IsTranslationReverted()); |
| // And it should have removed the infobar. |
| EXPECT_TRUE(GetTranslateInfoBar() == NULL); |
| } |
| } |
| |
| // Tests that no translate infobar is shown and context menu is disabled, when |
| // Chrome is in a language that the translate server does not support. |
| TEST_F(TranslateManagerRenderViewHostInvalidLocaleTest, UnsupportedUILanguage) { |
| // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| // Make sure that the accept language list only contains unsupported languages |
| Profile* profile = |
| Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| PrefService* prefs = profile->GetPrefs(); |
| prefs->SetString(prefs::kAcceptLanguages, kInvalidLocale); |
| |
| // Simulate navigating to a page in a language supported by the translate |
| // server. |
| SimulateNavigation(GURL("http://www.google.com"), "en", true); |
| |
| // No info-bar should be shown. |
| EXPECT_TRUE(GetTranslateInfoBar() == NULL); |
| |
| // And the context menu option should be disabled too. |
| std::unique_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); |
| menu->Init(); |
| EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| } |
| |
| // Tests that the first supported accept language is selected |
| TEST_F(TranslateManagerRenderViewHostInvalidLocaleTest, |
| TranslateAcceptLanguage) { |
| // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| // Set an invalid language and French as the only accepted languages |
| Profile* profile = |
| Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| PrefService* prefs = profile->GetPrefs(); |
| prefs->SetString(prefs::kAcceptLanguages, |
| std::string(kInvalidLocale) + ",fr"); |
| |
| // Go to a German page |
| SimulateNavigation(GURL("http://google.de"), "de", true); |
| |
| // Expect the infobar to pop up |
| EXPECT_TRUE(GetTranslateInfoBar() != NULL); |
| |
| // Set an invalid language and English-US as the only accepted languages to |
| // test the country code removal code which was causing a crash as filed in |
| // Issue 90106, a crash caused by a language with a country code that wasn't |
| // recognized. |
| prefs->SetString(prefs::kAcceptLanguages, |
| std::string(kInvalidLocale) + ",en-us"); |
| |
| // Go to a German page |
| SimulateNavigation(GURL("http://google.de"), "de", true); |
| |
| // Expect the infobar to pop up |
| EXPECT_TRUE(GetTranslateInfoBar() != NULL); |
| } |
| |
| // Tests that the translate enabled preference is honored. |
| TEST_F(TranslateManagerRenderViewHostTest, TranslateEnabledPref) { |
| // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| // Make sure the pref allows translate. |
| Profile* profile = |
| Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| PrefService* prefs = profile->GetPrefs(); |
| prefs->SetBoolean(prefs::kOfferTranslateEnabled, true); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| // An infobar should be shown. |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| EXPECT_TRUE(infobar != NULL); |
| |
| // Disable translate. |
| prefs->SetBoolean(prefs::kOfferTranslateEnabled, false); |
| |
| // Navigate to a new page, that should close the previous infobar. |
| GURL url("http://www.youtube.fr"); |
| NavigateAndCommit(url); |
| infobar = GetTranslateInfoBar(); |
| EXPECT_TRUE(infobar == NULL); |
| |
| // Simulate getting the page contents and language, that should not trigger |
| // a translate infobar. |
| SimulateOnTranslateLanguageDetermined("fr", true); |
| infobar = GetTranslateInfoBar(); |
| EXPECT_TRUE(infobar == NULL); |
| } |
| |
| // Tests the "Never translate <language>" pref. |
| TEST_F(TranslateManagerRenderViewHostTest, NeverTranslateLanguagePref) { |
| // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| GURL url("http://www.google.fr"); |
| SimulateNavigation(url, "fr", true); |
| |
| // An infobar should be shown. |
| EXPECT_TRUE(GetTranslateInfoBar() != NULL); |
| |
| // Select never translate this language. |
| Profile* profile = |
| Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| PrefService* prefs = profile->GetPrefs(); |
| PrefChangeRegistrar registrar; |
| registrar.Init(prefs); |
| registrar.Add(translate::TranslatePrefs::kPrefTranslateBlockedLanguages, |
| pref_callback_); |
| std::unique_ptr<translate::TranslatePrefs> translate_prefs( |
| ChromeTranslateClient::CreateTranslatePrefs(prefs)); |
| EXPECT_FALSE(translate_prefs->IsBlockedLanguage("fr")); |
| translate::TranslateAcceptLanguages* accept_languages = |
| ChromeTranslateClient::GetTranslateAcceptLanguages(profile); |
| EXPECT_TRUE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); |
| SetPrefObserverExpectation( |
| translate::TranslatePrefs::kPrefTranslateBlockedLanguages); |
| translate_prefs->AddToLanguageList("fr", /*force_blocked=*/true); |
| EXPECT_TRUE(translate_prefs->IsBlockedLanguage("fr")); |
| EXPECT_FALSE(translate_prefs->IsSiteBlacklisted(url.host())); |
| EXPECT_FALSE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); |
| |
| EXPECT_TRUE(CloseTranslateInfoBar()); |
| |
| // Navigate to a new page also in French. |
| SimulateNavigation(GURL("http://wwww.youtube.fr"), "fr", true); |
| |
| // There should not be a translate infobar. |
| EXPECT_TRUE(GetTranslateInfoBar() == NULL); |
| |
| // Remove the language from the blacklist. |
| SetPrefObserverExpectation( |
| translate::TranslatePrefs::kPrefTranslateBlockedLanguages); |
| translate_prefs->UnblockLanguage("fr"); |
| EXPECT_FALSE(translate_prefs->IsBlockedLanguage("fr")); |
| EXPECT_FALSE(translate_prefs->IsSiteBlacklisted(url.host())); |
| EXPECT_TRUE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); |
| |
| // Navigate to a page in French. |
| SimulateNavigation(url, "fr", true); |
| |
| // There should be a translate infobar. |
| EXPECT_TRUE(GetTranslateInfoBar() != NULL); |
| } |
| |
| // Tests the "Never translate this site" pref. |
| TEST_F(TranslateManagerRenderViewHostTest, NeverTranslateSitePref) { |
| // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| GURL url("http://www.google.fr"); |
| std::string host(url.host()); |
| SimulateNavigation(url, "fr", true); |
| |
| // An infobar should be shown. |
| EXPECT_TRUE(GetTranslateInfoBar() != NULL); |
| |
| // Select never translate this site. |
| Profile* profile = |
| Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| PrefService* prefs = profile->GetPrefs(); |
| PrefChangeRegistrar registrar; |
| registrar.Init(prefs); |
| registrar.Add( |
| translate::TranslatePrefs::kPrefTranslateSiteBlacklistDeprecated, |
| pref_callback_); |
| std::unique_ptr<translate::TranslatePrefs> translate_prefs( |
| ChromeTranslateClient::CreateTranslatePrefs(prefs)); |
| EXPECT_FALSE(translate_prefs->IsSiteBlacklisted(host)); |
| translate::TranslateAcceptLanguages* accept_languages = |
| ChromeTranslateClient::GetTranslateAcceptLanguages(profile); |
| EXPECT_TRUE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); |
| SetPrefObserverExpectation( |
| translate::TranslatePrefs::kPrefTranslateSiteBlacklistDeprecated); |
| translate_prefs->BlacklistSite(host); |
| EXPECT_TRUE(translate_prefs->IsSiteBlacklisted(host)); |
| EXPECT_TRUE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); |
| |
| EXPECT_TRUE(CloseTranslateInfoBar()); |
| |
| // Navigate to a new page also on the same site. |
| SimulateNavigation(GURL("http://www.google.fr/hello"), "fr", true); |
| |
| // There should not be a translate infobar. |
| EXPECT_TRUE(GetTranslateInfoBar() == NULL); |
| |
| // Remove the site from the blacklist. |
| SetPrefObserverExpectation( |
| translate::TranslatePrefs::kPrefTranslateSiteBlacklistDeprecated); |
| translate_prefs->RemoveSiteFromBlacklist(host); |
| EXPECT_FALSE(translate_prefs->IsSiteBlacklisted(host)); |
| EXPECT_TRUE(translate_prefs->CanTranslateLanguage(accept_languages, "fr")); |
| |
| // Navigate to a page in French. |
| SimulateNavigation(url, "fr", true); |
| |
| // There should be a translate infobar. |
| EXPECT_TRUE(GetTranslateInfoBar() != NULL); |
| } |
| |
| // Tests the "Always translate this language" pref. |
| TEST_F(TranslateManagerRenderViewHostTest, AlwaysTranslateLanguagePref) { |
| // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| // Select always translate French to English. |
| Profile* profile = |
| Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| PrefService* prefs = profile->GetPrefs(); |
| PrefChangeRegistrar registrar; |
| registrar.Init(prefs); |
| registrar.Add(translate::TranslatePrefs::kPrefTranslateWhitelists, |
| pref_callback_); |
| std::unique_ptr<translate::TranslatePrefs> translate_prefs( |
| ChromeTranslateClient::CreateTranslatePrefs(prefs)); |
| SetPrefObserverExpectation( |
| translate::TranslatePrefs::kPrefTranslateWhitelists); |
| translate_prefs->WhitelistLanguagePair("fr", "en"); |
| |
| // Load a page in French. |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| // It should have triggered an automatic translation to English. |
| |
| // The translating infobar should be showing. |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATING, infobar->translate_step()); |
| SimulateTranslateScriptURLFetch(true); |
| std::string original_lang, target_lang; |
| EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); |
| EXPECT_EQ("fr", original_lang); |
| EXPECT_EQ("en", target_lang); |
| |
| // Try another language, it should not be autotranslated. |
| SimulateNavigation(GURL("http://www.google.es"), "es", true); |
| EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); |
| EXPECT_TRUE(GetTranslateInfoBar() != NULL); |
| EXPECT_TRUE(CloseTranslateInfoBar()); |
| |
| // Let's switch to incognito mode, it should not be autotranslated in that |
| // case either. |
| TestingProfile* test_profile = |
| static_cast<TestingProfile*>(web_contents()->GetBrowserContext()); |
| test_profile->ForceIncognito(true); |
| SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true); |
| EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); |
| EXPECT_TRUE(GetTranslateInfoBar() != NULL); |
| EXPECT_TRUE(CloseTranslateInfoBar()); |
| test_profile->ForceIncognito(false); // Get back to non incognito. |
| |
| // Now revert the always translate pref and make sure we go back to expected |
| // behavior, which is show a "before translate" infobar. |
| SetPrefObserverExpectation( |
| translate::TranslatePrefs::kPrefTranslateWhitelists); |
| translate_prefs->RemoveLanguagePairFromWhitelist("fr", "en"); |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, |
| infobar->translate_step()); |
| } |
| |
| // Context menu. |
| TEST_F(TranslateManagerRenderViewHostTest, ContextMenu) { |
| // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| // Blacklist www.google.fr and French for translation. |
| GURL url("http://www.google.fr"); |
| Profile* profile = |
| Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| std::unique_ptr<translate::TranslatePrefs> translate_prefs( |
| ChromeTranslateClient::CreateTranslatePrefs(profile->GetPrefs())); |
| translate_prefs->AddToLanguageList("fr", /*force_blocked=*/true); |
| translate_prefs->BlacklistSite(url.host()); |
| EXPECT_TRUE(translate_prefs->IsBlockedLanguage("fr")); |
| EXPECT_TRUE(translate_prefs->IsSiteBlacklisted(url.host())); |
| |
| // Simulate navigating to a page in French. The translate menu should show but |
| // should only be enabled when the page language has been received. |
| NavigateAndCommit(url); |
| std::unique_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); |
| menu->Init(); |
| EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| |
| // Simulate receiving the language. |
| SimulateOnTranslateLanguageDetermined("fr", true); |
| menu.reset(CreateContextMenu()); |
| menu->Init(); |
| EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| |
| // Use the menu to translate the page. |
| menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); |
| |
| // That should have triggered a translation. |
| // The "translating..." infobar should be showing. |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_TRANSLATING, infobar->translate_step()); |
| SimulateTranslateScriptURLFetch(true); |
| std::string original_lang, target_lang; |
| EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); |
| EXPECT_EQ("fr", original_lang); |
| EXPECT_EQ("en", target_lang); |
| |
| // This should also have reverted the blacklisting of this site and language. |
| EXPECT_FALSE(translate_prefs->IsBlockedLanguage("fr")); |
| EXPECT_FALSE(translate_prefs->IsSiteBlacklisted(url.host())); |
| |
| // Let's simulate the page being translated. |
| SimulateOnPageTranslated("fr", "en"); |
| |
| // The translate menu should now be disabled. |
| menu.reset(CreateContextMenu()); |
| menu->Init(); |
| EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| |
| // Test that selecting translate in the context menu WHILE the page is being |
| // translated does nothing (this could happen if autotranslate kicks-in and |
| // the user selects the menu while the translation is being performed). |
| SimulateNavigation(GURL("http://www.google.es"), "es", true); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| infobar->Translate(); |
| EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); |
| menu.reset(CreateContextMenu()); |
| menu->Init(); |
| EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); |
| // No message expected since the translation should have been ignored. |
| EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); |
| |
| // Now test that selecting translate in the context menu AFTER the page has |
| // been translated does nothing. |
| SimulateNavigation(GURL("http://www.google.de"), "de", true); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| infobar->Translate(); |
| EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); |
| menu.reset(CreateContextMenu()); |
| menu->Init(); |
| EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| SimulateOnPageTranslated("de", "en"); |
| menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); |
| // No message expected since the translation should have been ignored. |
| EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); |
| |
| // Test that the translate context menu is enabled when the page is in an |
| // unknown language. |
| SimulateNavigation(url, "und", true); |
| menu.reset(CreateContextMenu()); |
| menu->Init(); |
| EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| |
| // Test that the translate context menu is enabled even if the page is in an |
| // unsupported language. |
| SimulateNavigation(url, kInvalidLocale, true); |
| menu.reset(CreateContextMenu()); |
| menu->Init(); |
| EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| } |
| |
| // Tests that an extra always/never translate button is shown on the "before |
| // translate" infobar when the translation is accepted/declined 3 times, |
| // only when not in incognito mode. |
| TEST_F(TranslateManagerRenderViewHostTest, BeforeTranslateExtraButtons) { |
| // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| Profile* profile = |
| Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| std::unique_ptr<translate::TranslatePrefs> translate_prefs( |
| ChromeTranslateClient::CreateTranslatePrefs(profile->GetPrefs())); |
| translate_prefs->ResetTranslationAcceptedCount("fr"); |
| translate_prefs->ResetTranslationDeniedCount("fr"); |
| translate_prefs->ResetTranslationAcceptedCount("de"); |
| translate_prefs->ResetTranslationDeniedCount("de"); |
| |
| // We'll do 4 times in incognito mode first to make sure the button is not |
| // shown in that case, then 4 times in normal mode. |
| translate::TranslateInfoBarDelegate* infobar; |
| TestingProfile* test_profile = |
| static_cast<TestingProfile*>(web_contents()->GetBrowserContext()); |
| test_profile->ForceIncognito(true); |
| for (int i = 0; i < 8; ++i) { |
| SCOPED_TRACE(::testing::Message() << "Iteration " << i << " incognito mode=" |
| << test_profile->IsOffTheRecord()); |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, |
| infobar->translate_step()); |
| if (i < 7) { |
| EXPECT_FALSE(infobar->ShouldShowAlwaysTranslateShortcut()); |
| infobar->Translate(); |
| } else { |
| EXPECT_TRUE(infobar->ShouldShowAlwaysTranslateShortcut()); |
| } |
| if (i == 3) |
| test_profile->ForceIncognito(false); |
| } |
| // Simulate the user pressing "Always translate French". |
| infobar->AlwaysTranslatePageLanguage(); |
| EXPECT_TRUE(translate_prefs->IsLanguagePairWhitelisted("fr", "en")); |
| // Simulate the translate script being retrieved (it only needs to be done |
| // once in the test as it is cached). |
| SimulateTranslateScriptURLFetch(true); |
| // That should have triggered a page translate. |
| std::string original_lang, target_lang; |
| EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); |
| |
| // Now test that declining the translation causes a "never translate" button |
| // to be shown (in non incognito mode only). |
| test_profile->ForceIncognito(true); |
| for (int i = 0; i < 8; ++i) { |
| SCOPED_TRACE(::testing::Message() << "Iteration " << i << " incognito mode=" |
| << test_profile->IsOffTheRecord()); |
| SimulateNavigation(GURL("http://www.google.de"), "de", true); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, |
| infobar->translate_step()); |
| if (i < 7) { |
| EXPECT_FALSE(infobar->ShouldShowNeverTranslateShortcut()); |
| infobar->TranslationDeclined(); |
| } else { |
| EXPECT_TRUE(infobar->ShouldShowNeverTranslateShortcut()); |
| } |
| if (i == 3) |
| test_profile->ForceIncognito(false); |
| } |
| // Simulate the user pressing "Never translate French". |
| infobar->NeverTranslatePageLanguage(); |
| EXPECT_TRUE(translate_prefs->IsBlockedLanguage("de")); |
| // No translation should have occured and the infobar should be gone. |
| EXPECT_FALSE(GetTranslateMessage(&original_lang, &target_lang)); |
| ASSERT_TRUE(GetTranslateInfoBar() == NULL); |
| } |
| |
| // Tests that we don't show a translate infobar when a page instructs that it |
| // should not be translated. |
| TEST_F(TranslateManagerRenderViewHostTest, NonTranslatablePage) { |
| // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| SimulateNavigation(GURL("http://mail.google.fr"), "fr", false); |
| |
| // We should not have an infobar. |
| EXPECT_TRUE(GetTranslateInfoBar() == NULL); |
| |
| // The context menu is enabled to allow users to force translation. |
| std::unique_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); |
| menu->Init(); |
| EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); |
| } |
| |
| // Tests that the script is expired and refetched as expected. |
| TEST_F(TranslateManagerRenderViewHostTest, ScriptExpires) { |
| // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 |
| if (TranslateService::IsTranslateBubbleEnabled()) |
| return; |
| |
| ExpireTranslateScriptImmediately(); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| infobar->Translate(); |
| SimulateTranslateScriptURLFetch(true); |
| // The translate request should have been sent. |
| EXPECT_TRUE(GetTranslateMessage(NULL, NULL)); |
| SimulateOnPageTranslated("fr", "en"); |
| |
| // A task should have been posted to clear the script, run it. |
| base::RunLoop().RunUntilIdle(); |
| |
| // Do another navigation and translation. |
| SimulateNavigation(GURL("http://www.google.es"), "es", true); |
| infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar != NULL); |
| infobar->Translate(); |
| // If we don't simulate the URL fetch, the TranslateManager should be waiting |
| // for the script and no message should have been sent to the renderer. |
| EXPECT_FALSE(GetTranslateMessage(NULL, NULL)); |
| // Now simulate the URL fetch. |
| SimulateTranslateScriptURLFetch(true); |
| // Now the message should have been sent. |
| std::string original_lang, target_lang; |
| EXPECT_TRUE(GetTranslateMessage(&original_lang, &target_lang)); |
| EXPECT_EQ("es", original_lang); |
| EXPECT_EQ("en", target_lang); |
| } |
| |
| #else |
| // The following tests depend on the translate bubble UI. |
| TEST_F(TranslateManagerRenderViewHostTest, BubbleNormalTranslate) { |
| // See NormalTranslate for corresponding infobar UX testing. |
| EXPECT_TRUE(TranslateService::IsTranslateBubbleEnabled()); |
| |
| MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; |
| std::unique_ptr<TranslateBubbleFactory> factory_ptr(factory); |
| TranslateBubbleFactory::SetFactory(factory); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| // Check the bubble exists instead of the infobar. |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar == NULL); |
| TranslateBubbleModel* bubble = factory->model(); |
| ASSERT_TRUE(bubble != NULL); |
| EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE, |
| bubble->GetViewState()); |
| |
| // Simulate clicking translate. |
| bubble->Translate(); |
| |
| // Check the bubble shows "Translating...". |
| bubble = factory->model(); |
| ASSERT_TRUE(bubble != NULL); |
| EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_TRANSLATING, |
| bubble->GetViewState()); |
| |
| // Set up a simulation of the translate script being retrieved (it only |
| // needs to be done once in the test as it is cached). |
| SimulateTranslateScriptURLFetch(true); |
| |
| // Simulate the render notifying the translation has been done. |
| SimulateOnPageTranslated("fr", "en"); |
| |
| // Check the bubble shows "Translated." |
| bubble = factory->model(); |
| ASSERT_TRUE(bubble != NULL); |
| EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE, |
| bubble->GetViewState()); |
| } |
| |
| TEST_F(TranslateManagerRenderViewHostTest, BubbleTranslateScriptNotAvailable) { |
| // See TranslateScriptNotAvailable for corresponding infobar UX testing. |
| EXPECT_TRUE(TranslateService::IsTranslateBubbleEnabled()); |
| |
| MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; |
| std::unique_ptr<TranslateBubbleFactory> factory_ptr(factory); |
| TranslateBubbleFactory::SetFactory(factory); |
| |
| SimulateNavigation(GURL("http://www.google.fr"), "fr", true); |
| |
| // Check the bubble exists instead of the infobar. |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar == NULL); |
| TranslateBubbleModel* bubble = factory->model(); |
| ASSERT_TRUE(bubble != NULL); |
| EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE, |
| bubble->GetViewState()); |
| |
| // Simulate clicking translate. |
| bubble->Translate(); |
| SimulateTranslateScriptURLFetch(false); |
| |
| // We should not have sent any message to translate to the renderer. |
| EXPECT_FALSE(GetTranslateMessage(NULL, NULL)); |
| |
| // And we should have an error infobar showing. |
| bubble = factory->model(); |
| ASSERT_TRUE(bubble != NULL); |
| EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ERROR, bubble->GetViewState()); |
| } |
| |
| TEST_F(TranslateManagerRenderViewHostTest, BubbleUnknownLanguage) { |
| // See TranslateUnknownLanguage for corresponding infobar UX testing. |
| EXPECT_TRUE(TranslateService::IsTranslateBubbleEnabled()); |
| |
| MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; |
| std::unique_ptr<TranslateBubbleFactory> factory_ptr(factory); |
| TranslateBubbleFactory::SetFactory(factory); |
| |
| // Simulate navigating to a page ("und" is the string returned by the CLD for |
| // languages it does not recognize). |
| SimulateNavigation(GURL("http://www.google.mys"), "und", true); |
| |
| // We should not have a bubble as we don't know the language. |
| ASSERT_TRUE(factory->model() == NULL); |
| |
| // Translate the page anyway throught the context menu. |
| std::unique_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); |
| menu->Init(); |
| menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); |
| |
| // Check the bubble exists instead of the infobar. |
| translate::TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); |
| ASSERT_TRUE(infobar == NULL); |
| TranslateBubbleModel* bubble = factory->model(); |
| ASSERT_TRUE(bubble != NULL); |
| EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_TRANSLATING, |
| bubble->GetViewState()); |
| } |
| #endif // defined(USE_AURA) && !defined(OS_MACOSX) |