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