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