summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-23 07:26:32 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-23 07:26:32 +0000
commit192d8c5ea712cca42ea1d6ff692cd77d099c0a35 (patch)
treeadc818cdd39ff402645f391f773bf359e7b753f0 /chrome/browser
parent781a7edbdb3288b237acbeff4926b47b243cef17 (diff)
downloadchromium_src-192d8c5ea712cca42ea1d6ff692cd77d099c0a35.zip
chromium_src-192d8c5ea712cca42ea1d6ff692cd77d099c0a35.tar.gz
chromium_src-192d8c5ea712cca42ea1d6ff692cd77d099c0a35.tar.bz2
Make the translation bar not show up again when you closed it in a page
and navigate in page. This is the case with web apps like GMail where many actions result in an in-page navigation. It would originally bring back the translation infobar, which is very anoying. This CL fixes the is_in_page state of LoadCommittedDetails, it was always false. This triggered a bug in the SSLManager that was wrongly not setting the SSL states when an in-page navigation is performed. Since we create a new navigation entry for in-page navigations, not setting these states would make a bad page being reported as OK after an in-page navigation. See original review: http://codereview.chromium.org/650146/show BUG=36304 TEST=Login to gmail, change the GMail language to a language different than the Chrome language. When a translate infobar shows up, close it. Click on the different links in GMail (inbox, drafts, select email...) the translate infobar should not show again. Review URL: http://codereview.chromium.org/650207 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39700 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/renderer_host/test/test_render_view_host.cc7
-rw-r--r--chrome/browser/renderer_host/test/test_render_view_host.h3
-rw-r--r--chrome/browser/ssl/ssl_manager.cc5
-rw-r--r--chrome/browser/tab_contents/language_state.cc25
-rw-r--r--chrome/browser/tab_contents/language_state.h9
-rw-r--r--chrome/browser/tab_contents/navigation_controller.cc13
-rw-r--r--chrome/browser/tab_contents/navigation_controller_unittest.cc15
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc3
-rw-r--r--chrome/browser/translate/translate_manager.cc6
-rw-r--r--chrome/browser/translate/translate_manager_unittest.cc223
10 files changed, 267 insertions, 42 deletions
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.cc b/chrome/browser/renderer_host/test/test_render_view_host.cc
index 776ef53..1c71d05 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.cc
+++ b/chrome/browser/renderer_host/test/test_render_view_host.cc
@@ -121,6 +121,13 @@ void RenderViewHostTestHarness::NavigateAndCommit(const GURL& url) {
rvh()->SendNavigate(process()->max_page_id() + 1, url);
}
+void RenderViewHostTestHarness::Reload() {
+ NavigationEntry* entry = controller().GetLastCommittedEntry();
+ DCHECK(entry);
+ controller().Reload(false);
+ rvh()->SendNavigate(entry->page_id(), entry->url());
+}
+
void RenderViewHostTestHarness::SetUp() {
// See comment above profile_ decl for why we check for NULL here.
if (!profile_.get())
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h
index cfd3aa2..063b7dd 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.h
+++ b/chrome/browser/renderer_host/test/test_render_view_host.h
@@ -252,6 +252,9 @@ class RenderViewHostTestHarness : public testing::Test {
// emulates what happens on a new navigation.
void NavigateAndCommit(const GURL& url);
+ // Simulates a reload of the current page.
+ void Reload();
+
protected:
// testing::Test
virtual void SetUp();
diff --git a/chrome/browser/ssl/ssl_manager.cc b/chrome/browser/ssl/ssl_manager.cc
index c55a47b..b869d65 100644
--- a/chrome/browser/ssl/ssl_manager.cc
+++ b/chrome/browser/ssl/ssl_manager.cc
@@ -170,11 +170,6 @@ void SSLManager::DidCommitProvisionalLoad(
NavigationController::LoadCommittedDetails* details =
Details<NavigationController::LoadCommittedDetails>(in_details).ptr();
- // Ignore in-page navigations, they should not change the security style or
- // the info-bars.
- if (details->is_in_page)
- return;
-
NavigationEntry* entry = controller_->GetActiveEntry();
if (details->is_main_frame) {
diff --git a/chrome/browser/tab_contents/language_state.cc b/chrome/browser/tab_contents/language_state.cc
index 0a62027..d294eec 100644
--- a/chrome/browser/tab_contents/language_state.cc
+++ b/chrome/browser/tab_contents/language_state.cc
@@ -10,26 +10,41 @@
LanguageState::LanguageState(NavigationController* nav_controller)
: navigation_controller_(nav_controller),
translation_pending_(false),
- translation_declined_(false) {
+ translation_declined_(false),
+ in_page_navigation_(false) {
}
LanguageState::~LanguageState() {
}
-void LanguageState::DidNavigate(bool reload) {
- if (!reload) {
+void LanguageState::DidNavigate(bool reload, bool in_page) {
+ in_page_navigation_ = in_page;
+ if (in_page)
+ return; // Don't reset our states, the page has not changed.
+
+ if (reload) {
+ // We might not get a LanguageDetermined notifications on reloads. Make sure
+ // to keep the original language and to set current_lang_ so
+ // IsPageTranslated() returns false.
+ current_lang_ = original_lang_;
+ } else {
prev_original_lang_ = original_lang_;
prev_current_lang_ = current_lang_;
original_lang_.clear();
+ current_lang_.clear();
}
- current_lang_.clear();
-
translation_pending_ = false;
translation_declined_ = false;
}
void LanguageState::LanguageDetermined(const std::string& page_language) {
+ if (in_page_navigation_ && !original_lang_.empty()) {
+ // In-page navigation, we don't expect our states to change.
+ // Note that we'll set the languages if original_lang_ is empty. This might
+ // happen if the we did not get called on the top-page.
+ return;
+ }
original_lang_ = page_language;
current_lang_ = page_language;
}
diff --git a/chrome/browser/tab_contents/language_state.h b/chrome/browser/tab_contents/language_state.h
index 21dea9d..f428229 100644
--- a/chrome/browser/tab_contents/language_state.h
+++ b/chrome/browser/tab_contents/language_state.h
@@ -27,7 +27,7 @@ class LanguageState {
// Should be called when the page did a new navigation (whether it is a main
// frame or sub-frame navigation).
- void DidNavigate(bool reload);
+ void DidNavigate(bool reload, bool in_page_navigation);
// Should be called when the language of the page has been determined.
void LanguageDetermined(const std::string& page_language);
@@ -56,6 +56,10 @@ class LanguageState {
bool translation_declined() const { return translation_declined_; }
void set_translation_declined(bool value) { translation_declined_ = value; }
+ // Whether the current page was navigated through an in-page (fragment)
+ // navigation.
+ bool in_page_navigation() const { return in_page_navigation_; }
+
private:
// The languages this page is in. Note that current_lang_ is different from
// original_lang_ when the page has been translated.
@@ -86,6 +90,9 @@ class LanguageState {
// load happens in the page after the user closed the infobar.
bool translation_declined_;
+ // Whether the current navigation is a fragment navigation (in page).
+ bool in_page_navigation_;
+
DISALLOW_COPY_AND_ASSIGN(LanguageState);
};
diff --git a/chrome/browser/tab_contents/navigation_controller.cc b/chrome/browser/tab_contents/navigation_controller.cc
index 3edb1ce..27d502a 100644
--- a/chrome/browser/tab_contents/navigation_controller.cc
+++ b/chrome/browser/tab_contents/navigation_controller.cc
@@ -86,8 +86,15 @@ void ConfigureEntriesForRestore(
// See NavigationController::IsURLInPageNavigation for how this works and why.
bool AreURLsInPageNavigation(const GURL& existing_url, const GURL& new_url) {
- if (existing_url == new_url || !new_url.has_ref())
+ if (existing_url == new_url || !new_url.has_ref()) {
+ // TODO(jcampan): what about when navigating back from a ref URL to the top
+ // non ref URL? Nothing is loaded in that case but we return false here.
+ // The user could also navigate from the ref URL to the non ref URL by
+ // entering the non ref URL in the location bar or through a bookmark, in
+ // which case there would be a load. I am not sure if the non-load/load
+ // scenarios can be differentiated with the TransitionType.
return false;
+ }
url_canon::Replacements<char> replacements;
replacements.ClearRef();
@@ -468,6 +475,9 @@ bool NavigationController::RendererDidNavigate(
pending_entry_->set_restore_type(NavigationEntry::RESTORE_NONE);
}
+ // is_in_page must be computed before the entry gets committed.
+ details->is_in_page = IsURLInPageNavigation(params.url);
+
// Do navigation-type specific actions. These will make and commit an entry.
details->type = ClassifyNavigation(params);
switch (details->type) {
@@ -519,7 +529,6 @@ bool NavigationController::RendererDidNavigate(
// Now prep the rest of the details for the notification and broadcast.
details->entry = GetActiveEntry();
- details->is_in_page = IsURLInPageNavigation(params.url);
details->is_main_frame = PageTransition::IsMainFrame(params.transition);
details->serialized_security_info = params.security_info;
details->is_content_filtered = params.is_content_filtered;
diff --git a/chrome/browser/tab_contents/navigation_controller_unittest.cc b/chrome/browser/tab_contents/navigation_controller_unittest.cc
index ea6a8c3..c0d75c2 100644
--- a/chrome/browser/tab_contents/navigation_controller_unittest.cc
+++ b/chrome/browser/tab_contents/navigation_controller_unittest.cc
@@ -1065,6 +1065,7 @@ TEST_F(NavigationControllerTest, InPage) {
EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details));
EXPECT_TRUE(notifications.Check1AndReset(
NotificationType::NAV_ENTRY_COMMITTED));
+ EXPECT_TRUE(details.is_in_page);
EXPECT_EQ(2, controller().entry_count());
// Go back one.
@@ -1075,6 +1076,9 @@ TEST_F(NavigationControllerTest, InPage) {
EXPECT_TRUE(controller().RendererDidNavigate(back_params, 0, &details));
EXPECT_TRUE(notifications.Check1AndReset(
NotificationType::NAV_ENTRY_COMMITTED));
+ // is_in_page is false in that case but should be true.
+ // See comment in AreURLsInPageNavigation() in navigation_controller.cc
+ // EXPECT_TRUE(details.is_in_page);
EXPECT_EQ(2, controller().entry_count());
EXPECT_EQ(0, controller().GetCurrentEntryIndex());
EXPECT_EQ(back_params.url, controller().GetActiveEntry()->url());
@@ -1087,6 +1091,7 @@ TEST_F(NavigationControllerTest, InPage) {
EXPECT_TRUE(controller().RendererDidNavigate(forward_params, 0, &details));
EXPECT_TRUE(notifications.Check1AndReset(
NotificationType::NAV_ENTRY_COMMITTED));
+ EXPECT_TRUE(details.is_in_page);
EXPECT_EQ(2, controller().entry_count());
EXPECT_EQ(1, controller().GetCurrentEntryIndex());
EXPECT_EQ(forward_params.url,
@@ -1102,6 +1107,16 @@ TEST_F(NavigationControllerTest, InPage) {
EXPECT_TRUE(controller().RendererDidNavigate(forward_params, 0, &details));
EXPECT_EQ(forward_params.url,
controller().GetActiveEntry()->url());
+
+ // Finally, navigate to an unrelated URL to make sure in_page is not sticky.
+ const GURL url3("http:////bar");
+ params.page_id = 2;
+ params.url = url3;
+ notifications.Reset();
+ EXPECT_TRUE(controller().RendererDidNavigate(params, 0, &details));
+ EXPECT_TRUE(notifications.Check1AndReset(
+ NotificationType::NAV_ENTRY_COMMITTED));
+ EXPECT_FALSE(details.is_in_page);
}
// NotificationObserver implementation used in verifying we've received the
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 4f7e823..98f463b 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -1522,7 +1522,8 @@ void TabContents::DidNavigateAnyFramePostCommit(
// Let the LanguageState clear its state.
language_state_.DidNavigate(details.entry->transition_type() ==
- PageTransition::RELOAD);
+ PageTransition::RELOAD,
+ details.is_in_page);
}
void TabContents::CloseConstrainedWindows() {
diff --git a/chrome/browser/translate/translate_manager.cc b/chrome/browser/translate/translate_manager.cc
index 6763a3f..00312b1 100644
--- a/chrome/browser/translate/translate_manager.cc
+++ b/chrome/browser/translate/translate_manager.cc
@@ -65,8 +65,10 @@ void TranslateManager::Observe(NotificationType type,
std::string language = *(Details<std::string>(details).ptr());
// We may get this notifications multiple times. Make sure to translate
// only once.
- if (!tab->language_state().translation_pending() &&
- !tab->language_state().translation_declined()) {
+ LanguageState& language_state = tab->language_state();
+ if (!language_state.translation_pending() &&
+ !language_state.translation_declined() &&
+ !language_state.IsPageTranslated()) {
InitiateTranslation(tab, language);
}
break;
diff --git a/chrome/browser/translate/translate_manager_unittest.cc b/chrome/browser/translate/translate_manager_unittest.cc
index 34d81f2..5480fb4 100644
--- a/chrome/browser/translate/translate_manager_unittest.cc
+++ b/chrome/browser/translate/translate_manager_unittest.cc
@@ -8,6 +8,8 @@
#include "chrome/browser/translate/translate_infobars_delegates.h"
#include "chrome/browser/translate/translate_manager.h"
#include "chrome/common/ipc_test_sink.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
class TestTranslateManager : public TranslateManager {
@@ -15,8 +17,11 @@ class TestTranslateManager : public TranslateManager {
TestTranslateManager() {}
};
-class TranslateManagerTest : public RenderViewHostTestHarness {
+class TranslateManagerTest : public RenderViewHostTestHarness,
+ public NotificationObserver {
public:
+ TranslateManagerTest() {}
+
// Simluates navigating to a page and getting teh page contents and language
// for that navigation.
void SimulateNavigation(const GURL& url, int page_id,
@@ -48,24 +53,98 @@ class TranslateManagerTest : public RenderViewHostTestHarness {
return true;
}
+ // Returns the translate infobar if there is 1 infobar and it is a translate
+ // infobar.
+ TranslateInfoBarDelegate* GetTranslateInfoBar() {
+ if (contents()->infobar_delegate_count() != 1)
+ return NULL;
+ return contents()->GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate();
+ }
+
+ // If there is 1 infobar and it is a translate infobar, closes it and returns
+ // true. Returns false otherwise.
+ bool CloseTranslateInfoBar() {
+ TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
+ if (!infobar)
+ return false;
+ infobar->InfoBarDismissed(); // Simulates closing the infobar.
+ contents()->RemoveInfoBar(infobar);
+ return true;
+ }
+
+ // Checks whether |infobar| has been removed and clears the removed infobar
+ // list.
+ bool CheckInfoBarRemovedAndReset(InfoBarDelegate* infobar) {
+ bool found = std::find(removed_infobars_.begin(), removed_infobars_.end(),
+ infobar) != removed_infobars_.end();
+ removed_infobars_.clear();
+ return found;
+ }
+
+ // Returns true if at least one infobar was closed.
+ bool InfoBarRemoved() {
+ return !removed_infobars_.empty();
+ }
+
+ // If there is 1 infobar and it is a translate infobar, deny translation and
+ // returns true. Returns false otherwise.
+ bool DenyTranslation() {
+ TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
+ if (!infobar)
+ return false;
+ infobar->TranslationDeclined();
+ contents()->RemoveInfoBar(infobar);
+ return true;
+ }
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(type == NotificationType::TAB_CONTENTS_INFOBAR_REMOVED);
+ removed_infobars_.push_back(Details<InfoBarDelegate>(details).ptr());
+ }
+
protected:
virtual void SetUp() {
- RenderViewHostTestHarness::SetUp();
-
TranslateManager::set_test_enabled(true);
// This must be created after set_test_enabled() has been called to register
- // notifications properly.
+ // notifications properly. Note that we do this before calling
+ // RenderViewHostTestHarness::SetUp() to match what's done in Chrome, where
+ // the TranslateManager is created before the TabContents. This matters for
+ // as they both register for similar events and we want the notifications
+ // to happen in the same sequence (TranslateManager first, TabContents
+ // second).
translate_manager_.reset(new TestTranslateManager());
+
+ RenderViewHostTestHarness::SetUp();
+
+ notification_registrar_.Add(
+ this,
+ NotificationType::TAB_CONTENTS_INFOBAR_REMOVED,
+ Source<TabContents>(contents()));
}
virtual void TearDown() {
+ notification_registrar_.Remove(
+ this,
+ NotificationType::TAB_CONTENTS_INFOBAR_REMOVED,
+ Source<TabContents>(contents()));
+
RenderViewHostTestHarness::TearDown();
TranslateManager::set_test_enabled(false);
}
private:
+ NotificationRegistrar notification_registrar_;
+
scoped_ptr<TestTranslateManager> translate_manager_;
+
+ // The list of infobars that have been removed.
+ // WARNING: the pointers points to deleted objects, use only for comparison.
+ std::vector<InfoBarDelegate*> removed_infobars_;
+
+ DISALLOW_COPY_AND_ASSIGN(TranslateManagerTest);
};
TEST_F(TranslateManagerTest, NormalTranslate) {
@@ -73,15 +152,14 @@ TEST_F(TranslateManagerTest, NormalTranslate) {
SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr");
// We should have an info-bar.
- ASSERT_EQ(1, contents()->infobar_delegate_count());
- TranslateInfoBarDelegate* infobar =
- contents()->GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate();
+ TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
ASSERT_TRUE(infobar != NULL);
EXPECT_EQ(TranslateInfoBarDelegate::kBeforeTranslate, infobar->state());
// Simulate clicking translate.
process()->sink().ClearMessages();
infobar->Translate();
+ EXPECT_FALSE(InfoBarRemoved());
// Test that we sent the right message to the renderer.
int page_id = 0;
@@ -91,9 +169,8 @@ TEST_F(TranslateManagerTest, NormalTranslate) {
EXPECT_EQ("fr", original_lang);
EXPECT_EQ("en", target_lang);
- // The infobar should now be in the translating state.
- ASSERT_EQ(1, contents()->infobar_delegate_count());
- ASSERT_EQ(infobar, contents()->GetInfoBarDelegateAt(0)); // Same instance.
+ // The infobar should still be there but in the translating state.
+ ASSERT_EQ(infobar, GetTranslateInfoBar()); // Same instance.
// TODO(jcampan): the state is not set if the button is not clicked.
// Refactor the infobar code so we can simulate the click.
// EXPECT_EQ(TranslateInfoBarDelegate::kTranslating, infobar->state());
@@ -102,8 +179,8 @@ TEST_F(TranslateManagerTest, NormalTranslate) {
rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en"));
// The infobar should have changed to the after state.
- ASSERT_EQ(1, contents()->infobar_delegate_count());
- ASSERT_EQ(infobar, contents()->GetInfoBarDelegateAt(0));
+ EXPECT_FALSE(InfoBarRemoved());
+ ASSERT_EQ(infobar, GetTranslateInfoBar());
// TODO(jcampan): the TranslateInfoBar is listening for the PAGE_TRANSLATED
// notification. Since in unit-test, no actual info-bar is
// created, it does not get the notification and does not
@@ -133,9 +210,7 @@ TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) {
SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr");
// Simulate the user translating.
- ASSERT_EQ(1, contents()->infobar_delegate_count());
- TranslateInfoBarDelegate* infobar =
- contents()->GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate();
+ TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
ASSERT_TRUE(infobar != NULL);
infobar->Translate();
rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en"));
@@ -166,12 +241,7 @@ TEST_F(TranslateManagerTest, MultipleOnPageContents) {
SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr");
// Simulate clicking 'Nope' (don't translate).
- ASSERT_EQ(1, contents()->infobar_delegate_count());
- TranslateInfoBarDelegate* infobar =
- contents()->GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate();
- ASSERT_TRUE(infobar != NULL);
- infobar->TranslationDeclined();
- contents()->RemoveInfoBar(infobar);
+ EXPECT_TRUE(DenyTranslation());
EXPECT_EQ(0, contents()->infobar_delegate_count());
// Send a new PageContents, we should not show an infobar.
@@ -180,12 +250,113 @@ TEST_F(TranslateManagerTest, MultipleOnPageContents) {
// Do the same steps but simulate closing the infobar this time.
SimulateNavigation(GURL("http://www.youtube.fr"), 1, L"Le YouTube", "fr");
- ASSERT_EQ(1, contents()->infobar_delegate_count());
- infobar = contents()->GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate();
- ASSERT_TRUE(infobar != NULL);
- infobar->InfoBarDismissed(); // Simulates closing the infobar.
- contents()->RemoveInfoBar(infobar);
+ EXPECT_TRUE(CloseTranslateInfoBar());
EXPECT_EQ(0, contents()->infobar_delegate_count());
SimulateOnPageContents(GURL("http://www.youtube.fr"), 1, L"Le YouTube", "fr");
EXPECT_EQ(0, contents()->infobar_delegate_count());
}
+
+// Test that reloading the page brings back the infobar.
+TEST_F(TranslateManagerTest, Reload) {
+ // Simulate navigating to a page and gettings its language.
+ SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr");
+
+ // Close the infobar.
+ EXPECT_TRUE(CloseTranslateInfoBar());
+
+ // Reload should bring back the infobar.
+ Reload();
+ // The TranslateManager class processes the navigation entry committed
+ // notification in a posted task; process that task.
+ MessageLoop::current()->RunAllPending();
+ EXPECT_TRUE(GetTranslateInfoBar() != NULL);
+}
+
+// Tests that a close translate infobar does not reappear when navigating
+// in-page.
+TEST_F(TranslateManagerTest, CloseInfoBarInPageNavigation) {
+ // Simulate navigating to a page and gettings its language.
+ SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr");
+
+ // Close the infobar.
+ EXPECT_TRUE(CloseTranslateInfoBar());
+
+ // Navigate in page, no infobar should be shown.
+ SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, L"Le Google", "fr");
+ EXPECT_TRUE(GetTranslateInfoBar() == NULL);
+
+ // Navigate out of page, a new infobar should show.
+ SimulateNavigation(GURL("http://www.google.fr/foot"), 0, L"Le Google", "fr");
+ EXPECT_TRUE(GetTranslateInfoBar() != NULL);
+}
+
+// Tests that denying translation is sticky when navigating in page.
+TEST_F(TranslateManagerTest, DenyTranslateInPageNavigation) {
+ // Simulate navigating to a page and gettings its language.
+ SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr");
+
+ // Simulate clicking 'Nope' (don't translate).
+ EXPECT_TRUE(DenyTranslation());
+
+ // Navigate in page, no infobar should be shown.
+ SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, L"Le Google", "fr");
+ EXPECT_TRUE(GetTranslateInfoBar() == NULL);
+
+ // Navigate out of page, a new infobar should show.
+ SimulateNavigation(GURL("http://www.google.fr/foot"), 0, L"Le Google", "fr");
+ EXPECT_TRUE(GetTranslateInfoBar() != NULL);
+}
+
+// Tests that after translating and closing the infobar, the infobar does not
+// return when navigating in page.
+TEST_F(TranslateManagerTest, TranslateCloseInfoBarInPageNavigation) {
+ // Simulate navigating to a page and gettings its language.
+ SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr");
+
+ // Simulate the user translating.
+ TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
+ ASSERT_TRUE(infobar != NULL);
+ infobar->Translate();
+ rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en"));
+
+ // Close the infobar.
+ EXPECT_TRUE(CloseTranslateInfoBar());
+
+ // Navigate in page, no infobar should be shown.
+ SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, L"Le Google", "fr");
+ EXPECT_TRUE(GetTranslateInfoBar() == NULL);
+
+ // Navigate out of page, a new infobar should show.
+ // Note that we navigate to a page in a different language so we don't trigger
+ // the auto-translate feature (it would translate the page automatically and
+ // the before translate inforbar would not be shown).
+ SimulateNavigation(GURL("http://www.google.de"), 0, L"Das Google", "de");
+ EXPECT_TRUE(GetTranslateInfoBar() != NULL);
+}
+
+// Tests that the after translate the infobar still shows when navigating
+// in-page.
+TEST_F(TranslateManagerTest, TranslateInPageNavigation) {
+ // Simulate navigating to a page and gettings its language.
+ SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr");
+
+ // Simulate the user translating.
+ TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
+ ASSERT_TRUE(infobar != NULL);
+ infobar->Translate();
+ rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en"));
+
+ // Navigate in page, the same infobar should still be shown.
+ SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, L"Le Google", "fr");
+ EXPECT_FALSE(InfoBarRemoved());
+ EXPECT_EQ(infobar, GetTranslateInfoBar());
+
+ // Navigate out of page, a new infobar should show.
+ // See note in TranslateCloseInfoBarInPageNavigation test on why it is
+ // important to navigate to a page in a different language for this test.
+ SimulateNavigation(GURL("http://www.google.de"), 0, L"Das Google", "de");
+ // The old infobar is gone.
+ EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar));
+ // And there is a new one.
+ EXPECT_TRUE(GetTranslateInfoBar() != NULL);
+}