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