Index: content/browser/web_contents/navigation_controller_impl_unittest.cc |
diff --git a/content/browser/web_contents/navigation_controller_impl_unittest.cc b/content/browser/web_contents/navigation_controller_impl_unittest.cc |
deleted file mode 100644 |
index 2d8758bedb8ed586be04afb33d1e237f397e6116..0000000000000000000000000000000000000000 |
--- a/content/browser/web_contents/navigation_controller_impl_unittest.cc |
+++ /dev/null |
@@ -1,3794 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "base/basictypes.h" |
-#include "base/bind.h" |
-#include "base/file_util.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/path_service.h" |
-#include "base/stl_util.h" |
-#include "base/strings/string_util.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "base/time/time.h" |
-#include "content/browser/renderer_host/test_render_view_host.h" |
-#include "content/browser/site_instance_impl.h" |
-#include "content/browser/web_contents/navigation_controller_impl.h" |
-#include "content/browser/web_contents/navigation_entry_impl.h" |
-#include "content/browser/web_contents/web_contents_impl.h" |
-#include "content/browser/web_contents/web_contents_screenshot_manager.h" |
-#include "content/common/view_messages.h" |
-#include "content/public/browser/navigation_details.h" |
-#include "content/public/browser/notification_registrar.h" |
-#include "content/public/browser/notification_types.h" |
-#include "content/public/browser/render_view_host.h" |
-#include "content/public/browser/web_contents_delegate.h" |
-#include "content/public/browser/web_contents_observer.h" |
-#include "content/public/common/page_state.h" |
-#include "content/public/common/url_constants.h" |
-#include "content/public/test/mock_render_process_host.h" |
-#include "content/public/test/test_notification_tracker.h" |
-#include "content/public/test/test_utils.h" |
-#include "content/test/test_web_contents.h" |
-#include "net/base/net_util.h" |
-#include "skia/ext/platform_canvas.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-using base::Time; |
- |
-namespace { |
- |
-// Creates an image with a 1x1 SkBitmap of the specified |color|. |
-gfx::Image CreateImage(SkColor color) { |
- SkBitmap bitmap; |
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); |
- bitmap.allocPixels(); |
- bitmap.eraseColor(color); |
- return gfx::Image::CreateFrom1xBitmap(bitmap); |
-} |
- |
-// Returns true if images |a| and |b| have the same pixel data. |
-bool DoImagesMatch(const gfx::Image& a, const gfx::Image& b) { |
- // Assume that if the 1x bitmaps match, the images match. |
- SkBitmap a_bitmap = a.AsBitmap(); |
- SkBitmap b_bitmap = b.AsBitmap(); |
- |
- if (a_bitmap.width() != b_bitmap.width() || |
- a_bitmap.height() != b_bitmap.height()) { |
- return false; |
- } |
- SkAutoLockPixels a_bitmap_lock(a_bitmap); |
- SkAutoLockPixels b_bitmap_lock(b_bitmap); |
- return memcmp(a_bitmap.getPixels(), |
- b_bitmap.getPixels(), |
- a_bitmap.getSize()) == 0; |
-} |
- |
-class MockScreenshotManager : public content::WebContentsScreenshotManager { |
- public: |
- explicit MockScreenshotManager(content::NavigationControllerImpl* owner) |
- : content::WebContentsScreenshotManager(owner), |
- encoding_screenshot_in_progress_(false) { |
- } |
- |
- virtual ~MockScreenshotManager() { |
- } |
- |
- void TakeScreenshotFor(content::NavigationEntryImpl* entry) { |
- SkBitmap bitmap; |
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); |
- bitmap.allocPixels(); |
- bitmap.eraseRGB(0, 0, 0); |
- encoding_screenshot_in_progress_ = true; |
- OnScreenshotTaken(entry->GetUniqueID(), true, bitmap); |
- WaitUntilScreenshotIsReady(); |
- } |
- |
- int GetScreenshotCount() { |
- return content::WebContentsScreenshotManager::GetScreenshotCount(); |
- } |
- |
- void WaitUntilScreenshotIsReady() { |
- if (!encoding_screenshot_in_progress_) |
- return; |
- message_loop_runner_ = new content::MessageLoopRunner; |
- message_loop_runner_->Run(); |
- } |
- |
- private: |
- // Overridden from content::WebContentsScreenshotManager: |
- virtual void TakeScreenshotImpl( |
- content::RenderViewHost* host, |
- content::NavigationEntryImpl* entry) OVERRIDE { |
- } |
- |
- virtual void OnScreenshotSet(content::NavigationEntryImpl* entry) OVERRIDE { |
- encoding_screenshot_in_progress_ = false; |
- WebContentsScreenshotManager::OnScreenshotSet(entry); |
- if (message_loop_runner_.get()) |
- message_loop_runner_->Quit(); |
- } |
- |
- scoped_refptr<content::MessageLoopRunner> message_loop_runner_; |
- bool encoding_screenshot_in_progress_; |
- |
- DISALLOW_COPY_AND_ASSIGN(MockScreenshotManager); |
-}; |
- |
-} // namespace |
- |
-namespace content { |
- |
-// TimeSmoother tests ---------------------------------------------------------- |
- |
-// With no duplicates, GetSmoothedTime should be the identity |
-// function. |
-TEST(TimeSmoother, Basic) { |
- NavigationControllerImpl::TimeSmoother smoother; |
- for (int64 i = 1; i < 1000; ++i) { |
- base::Time t = base::Time::FromInternalValue(i); |
- EXPECT_EQ(t, smoother.GetSmoothedTime(t)); |
- } |
-} |
- |
-// With a single duplicate and timestamps thereafter increasing by one |
-// microsecond, the smoothed time should always be one behind. |
-TEST(TimeSmoother, SingleDuplicate) { |
- NavigationControllerImpl::TimeSmoother smoother; |
- base::Time t = base::Time::FromInternalValue(1); |
- EXPECT_EQ(t, smoother.GetSmoothedTime(t)); |
- for (int64 i = 1; i < 1000; ++i) { |
- base::Time expected_t = base::Time::FromInternalValue(i + 1); |
- t = base::Time::FromInternalValue(i); |
- EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t)); |
- } |
-} |
- |
-// With k duplicates and timestamps thereafter increasing by one |
-// microsecond, the smoothed time should always be k behind. |
-TEST(TimeSmoother, ManyDuplicates) { |
- const int64 kNumDuplicates = 100; |
- NavigationControllerImpl::TimeSmoother smoother; |
- base::Time t = base::Time::FromInternalValue(1); |
- for (int64 i = 0; i < kNumDuplicates; ++i) { |
- base::Time expected_t = base::Time::FromInternalValue(i + 1); |
- EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t)); |
- } |
- for (int64 i = 1; i < 1000; ++i) { |
- base::Time expected_t = |
- base::Time::FromInternalValue(i + kNumDuplicates); |
- t = base::Time::FromInternalValue(i); |
- EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t)); |
- } |
-} |
- |
-// If the clock jumps far back enough after a run of duplicates, it |
-// should immediately jump to that value. |
-TEST(TimeSmoother, ClockBackwardsJump) { |
- const int64 kNumDuplicates = 100; |
- NavigationControllerImpl::TimeSmoother smoother; |
- base::Time t = base::Time::FromInternalValue(1000); |
- for (int64 i = 0; i < kNumDuplicates; ++i) { |
- base::Time expected_t = base::Time::FromInternalValue(i + 1000); |
- EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t)); |
- } |
- t = base::Time::FromInternalValue(500); |
- EXPECT_EQ(t, smoother.GetSmoothedTime(t)); |
-} |
- |
-// NavigationControllerTest ---------------------------------------------------- |
- |
-class NavigationControllerTest |
- : public RenderViewHostImplTestHarness, |
- public WebContentsObserver { |
- public: |
- NavigationControllerTest() : navigation_entry_committed_counter_(0) { |
- } |
- |
- virtual void SetUp() OVERRIDE { |
- RenderViewHostImplTestHarness::SetUp(); |
- WebContents* web_contents = RenderViewHostImplTestHarness::web_contents(); |
- ASSERT_TRUE(web_contents); // The WebContents should be created by now. |
- WebContentsObserver::Observe(web_contents); |
- } |
- |
- // WebContentsObserver: |
- virtual void NavigateToPendingEntry( |
- const GURL& url, |
- NavigationController::ReloadType reload_type) OVERRIDE { |
- navigated_url_ = url; |
- } |
- |
- virtual void NavigationEntryCommitted( |
- const LoadCommittedDetails& load_details) OVERRIDE { |
- navigation_entry_committed_counter_++; |
- } |
- |
- const GURL& navigated_url() const { |
- return navigated_url_; |
- } |
- |
- NavigationControllerImpl& controller_impl() { |
- return static_cast<NavigationControllerImpl&>(controller()); |
- } |
- |
- protected: |
- GURL navigated_url_; |
- size_t navigation_entry_committed_counter_; |
-}; |
- |
-void RegisterForAllNavNotifications(TestNotificationTracker* tracker, |
- NavigationController* controller) { |
- tracker->ListenFor(NOTIFICATION_NAV_LIST_PRUNED, |
- Source<NavigationController>(controller)); |
- tracker->ListenFor(NOTIFICATION_NAV_ENTRY_CHANGED, |
- Source<NavigationController>(controller)); |
-} |
- |
-SiteInstance* GetSiteInstanceFromEntry(NavigationEntry* entry) { |
- return NavigationEntryImpl::FromNavigationEntry(entry)->site_instance(); |
-} |
- |
-class TestWebContentsDelegate : public WebContentsDelegate { |
- public: |
- explicit TestWebContentsDelegate() : |
- navigation_state_change_count_(0) {} |
- |
- int navigation_state_change_count() { |
- return navigation_state_change_count_; |
- } |
- |
- // Keep track of whether the tab has notified us of a navigation state change. |
- virtual void NavigationStateChanged(const WebContents* source, |
- unsigned changed_flags) OVERRIDE { |
- navigation_state_change_count_++; |
- } |
- |
- private: |
- // The number of times NavigationStateChanged has been called. |
- int navigation_state_change_count_; |
-}; |
- |
-// ----------------------------------------------------------------------------- |
- |
-TEST_F(NavigationControllerTest, Defaults) { |
- NavigationControllerImpl& controller = controller_impl(); |
- |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_FALSE(controller.GetVisibleEntry()); |
- EXPECT_FALSE(controller.GetLastCommittedEntry()); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), -1); |
- EXPECT_EQ(controller.GetEntryCount(), 0); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
-} |
- |
-TEST_F(NavigationControllerTest, GoToOffset) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const int kNumUrls = 5; |
- std::vector<GURL> urls(kNumUrls); |
- for (int i = 0; i < kNumUrls; ++i) { |
- urls[i] = GURL(base::StringPrintf("http://www.a.com/%d", i)); |
- } |
- |
- test_rvh()->SendNavigate(0, urls[0]); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(urls[0], controller.GetVisibleEntry()->GetVirtualURL()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- EXPECT_FALSE(controller.CanGoToOffset(1)); |
- |
- for (int i = 1; i <= 4; ++i) { |
- test_rvh()->SendNavigate(i, urls[i]); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(urls[i], controller.GetVisibleEntry()->GetVirtualURL()); |
- EXPECT_TRUE(controller.CanGoToOffset(-i)); |
- EXPECT_FALSE(controller.CanGoToOffset(-(i + 1))); |
- EXPECT_FALSE(controller.CanGoToOffset(1)); |
- } |
- |
- // We have loaded 5 pages, and are currently at the last-loaded page. |
- int url_index = 4; |
- |
- enum Tests { |
- GO_TO_MIDDLE_PAGE = -2, |
- GO_FORWARDS = 1, |
- GO_BACKWARDS = -1, |
- GO_TO_BEGINNING = -2, |
- GO_TO_END = 4, |
- NUM_TESTS = 5, |
- }; |
- |
- const int test_offsets[NUM_TESTS] = { |
- GO_TO_MIDDLE_PAGE, |
- GO_FORWARDS, |
- GO_BACKWARDS, |
- GO_TO_BEGINNING, |
- GO_TO_END |
- }; |
- |
- for (int test = 0; test < NUM_TESTS; ++test) { |
- int offset = test_offsets[test]; |
- controller.GoToOffset(offset); |
- url_index += offset; |
- // Check that the GoToOffset will land on the expected page. |
- EXPECT_EQ(urls[url_index], controller.GetPendingEntry()->GetVirtualURL()); |
- test_rvh()->SendNavigate(url_index, urls[url_index]); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- // Check that we can go to any valid offset into the history. |
- for (size_t j = 0; j < urls.size(); ++j) |
- EXPECT_TRUE(controller.CanGoToOffset(j - url_index)); |
- // Check that we can't go beyond the beginning or end of the history. |
- EXPECT_FALSE(controller.CanGoToOffset(-(url_index + 1))); |
- EXPECT_FALSE(controller.CanGoToOffset(urls.size() - url_index)); |
- } |
-} |
- |
-TEST_F(NavigationControllerTest, LoadURL) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- // Creating a pending notification should not have issued any of the |
- // notifications we're listening for. |
- EXPECT_EQ(0U, notifications.size()); |
- |
- // The load should now be pending. |
- EXPECT_EQ(controller.GetEntryCount(), 0); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), -1); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_FALSE(controller.GetLastCommittedEntry()); |
- ASSERT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(controller.GetPendingEntry(), controller.GetVisibleEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- EXPECT_EQ(contents()->GetMaxPageID(), -1); |
- |
- // Neither the timestamp nor the status code should have been set yet. |
- EXPECT_TRUE(controller.GetPendingEntry()->GetTimestamp().is_null()); |
- EXPECT_EQ(0, controller.GetPendingEntry()->GetHttpStatusCode()); |
- |
- // We should have gotten no notifications from the preceeding checks. |
- EXPECT_EQ(0U, notifications.size()); |
- |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // The load should now be committed. |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- ASSERT_TRUE(controller.GetVisibleEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- EXPECT_EQ(contents()->GetMaxPageID(), 0); |
- EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry( |
- controller.GetLastCommittedEntry())->bindings()); |
- |
- // The timestamp should have been set. |
- EXPECT_FALSE(controller.GetVisibleEntry()->GetTimestamp().is_null()); |
- |
- // Load another... |
- controller.LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- |
- // The load should now be pending. |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- ASSERT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(controller.GetPendingEntry(), controller.GetVisibleEntry()); |
- // TODO(darin): maybe this should really be true? |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- EXPECT_EQ(contents()->GetMaxPageID(), 0); |
- |
- EXPECT_TRUE(controller.GetPendingEntry()->GetTimestamp().is_null()); |
- |
- // Simulate the beforeunload ack for the cross-site transition, and then the |
- // commit. |
- test_rvh()->SendShouldCloseACK(true); |
- static_cast<TestRenderViewHost*>( |
- contents()->GetPendingRenderViewHost())->SendNavigate(1, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // The load should now be committed. |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- ASSERT_TRUE(controller.GetVisibleEntry()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- EXPECT_EQ(contents()->GetMaxPageID(), 1); |
- |
- EXPECT_FALSE(controller.GetVisibleEntry()->GetTimestamp().is_null()); |
-} |
- |
-namespace { |
- |
-base::Time GetFixedTime(base::Time time) { |
- return time; |
-} |
- |
-} // namespace |
- |
-TEST_F(NavigationControllerTest, LoadURLSameTime) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // Set the clock to always return a timestamp of 1. |
- controller.SetGetTimestampCallbackForTest( |
- base::Bind(&GetFixedTime, base::Time::FromInternalValue(1))); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Load another... |
- controller.LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- |
- // Simulate the beforeunload ack for the cross-site transition, and then the |
- // commit. |
- test_rvh()->SendShouldCloseACK(true); |
- test_rvh()->SendNavigate(1, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // The two loads should now be committed. |
- ASSERT_EQ(controller.GetEntryCount(), 2); |
- |
- // Timestamps should be distinct despite the clock returning the |
- // same value. |
- EXPECT_EQ(1u, |
- controller.GetEntryAtIndex(0)->GetTimestamp().ToInternalValue()); |
- EXPECT_EQ(2u, |
- controller.GetEntryAtIndex(1)->GetTimestamp().ToInternalValue()); |
-} |
- |
-void CheckNavigationEntryMatchLoadParams( |
- NavigationController::LoadURLParams& load_params, |
- NavigationEntryImpl* entry) { |
- EXPECT_EQ(load_params.url, entry->GetURL()); |
- EXPECT_EQ(load_params.referrer.url, entry->GetReferrer().url); |
- EXPECT_EQ(load_params.referrer.policy, entry->GetReferrer().policy); |
- EXPECT_EQ(load_params.transition_type, entry->GetTransitionType()); |
- EXPECT_EQ(load_params.extra_headers, entry->extra_headers()); |
- |
- EXPECT_EQ(load_params.is_renderer_initiated, entry->is_renderer_initiated()); |
- EXPECT_EQ(load_params.base_url_for_data_url, entry->GetBaseURLForDataURL()); |
- if (!load_params.virtual_url_for_data_url.is_empty()) { |
- EXPECT_EQ(load_params.virtual_url_for_data_url, entry->GetVirtualURL()); |
- } |
- if (NavigationController::UA_OVERRIDE_INHERIT != |
- load_params.override_user_agent) { |
- bool should_override = (NavigationController::UA_OVERRIDE_TRUE == |
- load_params.override_user_agent); |
- EXPECT_EQ(should_override, entry->GetIsOverridingUserAgent()); |
- } |
- EXPECT_EQ(load_params.browser_initiated_post_data, |
- entry->GetBrowserInitiatedPostData()); |
- EXPECT_EQ(load_params.transferred_global_request_id, |
- entry->transferred_global_request_id()); |
-} |
- |
-TEST_F(NavigationControllerTest, LoadURLWithParams) { |
- NavigationControllerImpl& controller = controller_impl(); |
- |
- NavigationController::LoadURLParams load_params(GURL("http://foo")); |
- load_params.referrer = |
- Referrer(GURL("http://referrer"), WebKit::WebReferrerPolicyDefault); |
- load_params.transition_type = PAGE_TRANSITION_GENERATED; |
- load_params.extra_headers = "content-type: text/plain"; |
- load_params.load_type = NavigationController::LOAD_TYPE_DEFAULT; |
- load_params.is_renderer_initiated = true; |
- load_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE; |
- load_params.transferred_global_request_id = GlobalRequestID(2, 3); |
- |
- controller.LoadURLWithParams(load_params); |
- NavigationEntryImpl* entry = |
- NavigationEntryImpl::FromNavigationEntry( |
- controller.GetPendingEntry()); |
- |
- // The timestamp should not have been set yet. |
- ASSERT_TRUE(entry); |
- EXPECT_TRUE(entry->GetTimestamp().is_null()); |
- |
- CheckNavigationEntryMatchLoadParams(load_params, entry); |
-} |
- |
-TEST_F(NavigationControllerTest, LoadURLWithExtraParams_Data) { |
- NavigationControllerImpl& controller = controller_impl(); |
- |
- NavigationController::LoadURLParams load_params( |
- GURL("data:text/html,dataurl")); |
- load_params.load_type = NavigationController::LOAD_TYPE_DATA; |
- load_params.base_url_for_data_url = GURL("http://foo"); |
- load_params.virtual_url_for_data_url = GURL(kAboutBlankURL); |
- load_params.override_user_agent = NavigationController::UA_OVERRIDE_FALSE; |
- |
- controller.LoadURLWithParams(load_params); |
- NavigationEntryImpl* entry = |
- NavigationEntryImpl::FromNavigationEntry( |
- controller.GetPendingEntry()); |
- |
- CheckNavigationEntryMatchLoadParams(load_params, entry); |
-} |
- |
-TEST_F(NavigationControllerTest, LoadURLWithExtraParams_HttpPost) { |
- NavigationControllerImpl& controller = controller_impl(); |
- |
- NavigationController::LoadURLParams load_params(GURL("https://posturl")); |
- load_params.transition_type = PAGE_TRANSITION_TYPED; |
- load_params.load_type = |
- NavigationController::LOAD_TYPE_BROWSER_INITIATED_HTTP_POST; |
- load_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE; |
- |
- |
- const unsigned char* raw_data = |
- reinterpret_cast<const unsigned char*>("d\n\0a2"); |
- const int length = 5; |
- std::vector<unsigned char> post_data_vector(raw_data, raw_data+length); |
- scoped_refptr<base::RefCountedBytes> data = |
- base::RefCountedBytes::TakeVector(&post_data_vector); |
- load_params.browser_initiated_post_data = data.get(); |
- |
- controller.LoadURLWithParams(load_params); |
- NavigationEntryImpl* entry = |
- NavigationEntryImpl::FromNavigationEntry( |
- controller.GetPendingEntry()); |
- |
- CheckNavigationEntryMatchLoadParams(load_params, entry); |
-} |
- |
-// Tests what happens when the same page is loaded again. Should not create a |
-// new session history entry. This is what happens when you press enter in the |
-// URL bar to reload: a pending entry is created and then it is discarded when |
-// the load commits (because WebCore didn't actually make a new entry). |
-TEST_F(NavigationControllerTest, LoadURL_SamePage) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(0U, notifications.size()); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- ASSERT_TRUE(controller.GetVisibleEntry()); |
- const base::Time timestamp = controller.GetVisibleEntry()->GetTimestamp(); |
- EXPECT_FALSE(timestamp.is_null()); |
- |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(0U, notifications.size()); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // We should not have produced a new session history entry. |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- ASSERT_TRUE(controller.GetVisibleEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- |
- // The timestamp should have been updated. |
- // |
- // TODO(akalin): Change this EXPECT_GE (and other similar ones) to |
- // EXPECT_GT once we guarantee that timestamps are unique. |
- EXPECT_GE(controller.GetVisibleEntry()->GetTimestamp(), timestamp); |
-} |
- |
-// Tests loading a URL but discarding it before the load commits. |
-TEST_F(NavigationControllerTest, LoadURL_Discarded) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(0U, notifications.size()); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- ASSERT_TRUE(controller.GetVisibleEntry()); |
- const base::Time timestamp = controller.GetVisibleEntry()->GetTimestamp(); |
- EXPECT_FALSE(timestamp.is_null()); |
- |
- controller.LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- controller.DiscardNonCommittedEntries(); |
- EXPECT_EQ(0U, notifications.size()); |
- |
- // Should not have produced a new session history entry. |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- ASSERT_TRUE(controller.GetVisibleEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- |
- // Timestamp should not have changed. |
- EXPECT_EQ(timestamp, controller.GetVisibleEntry()->GetTimestamp()); |
-} |
- |
-// Tests navigations that come in unrequested. This happens when the user |
-// navigates from the web page, and here we test that there is no pending entry. |
-TEST_F(NavigationControllerTest, LoadURL_NoPending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // First make an existing committed entry. |
- const GURL kExistingURL1("http://eh"); |
- controller.LoadURL( |
- kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, kExistingURL1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Do a new navigation without making a pending one. |
- const GURL kNewURL("http://see"); |
- test_rvh()->SendNavigate(99, kNewURL); |
- |
- // There should no longer be any pending entry, and the third navigation we |
- // just made should be committed. |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL()); |
-} |
- |
-// Tests navigating to a new URL when there is a new pending navigation that is |
-// not the one that just loaded. This will happen if the user types in a URL to |
-// somewhere slow, and then navigates the current page before the typed URL |
-// commits. |
-TEST_F(NavigationControllerTest, LoadURL_NewPending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // First make an existing committed entry. |
- const GURL kExistingURL1("http://eh"); |
- controller.LoadURL( |
- kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, kExistingURL1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Make a pending entry to somewhere new. |
- const GURL kExistingURL2("http://bee"); |
- controller.LoadURL( |
- kExistingURL2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(0U, notifications.size()); |
- |
- // After the beforeunload but before it commits, do a new navigation. |
- test_rvh()->SendShouldCloseACK(true); |
- const GURL kNewURL("http://see"); |
- static_cast<TestRenderViewHost*>( |
- contents()->GetPendingRenderViewHost())->SendNavigate(3, kNewURL); |
- |
- // There should no longer be any pending entry, and the third navigation we |
- // just made should be committed. |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL()); |
-} |
- |
-// Tests navigating to a new URL when there is a pending back/forward |
-// navigation. This will happen if the user hits back, but before that commits, |
-// they navigate somewhere new. |
-TEST_F(NavigationControllerTest, LoadURL_ExistingPending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // First make some history. |
- const GURL kExistingURL1("http://foo/eh"); |
- controller.LoadURL( |
- kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, kExistingURL1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- const GURL kExistingURL2("http://foo/bee"); |
- controller.LoadURL( |
- kExistingURL2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(1, kExistingURL2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Now make a pending back/forward navigation. The zeroth entry should be |
- // pending. |
- controller.GoBack(); |
- EXPECT_EQ(0U, notifications.size()); |
- EXPECT_EQ(0, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
- |
- // Before that commits, do a new navigation. |
- const GURL kNewURL("http://foo/see"); |
- LoadCommittedDetails details; |
- test_rvh()->SendNavigate(3, kNewURL); |
- |
- // There should no longer be any pending entry, and the third navigation we |
- // just made should be committed. |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL()); |
-} |
- |
-// Tests navigating to a new URL when there is a pending back/forward |
-// navigation to a cross-process, privileged URL. This will happen if the user |
-// hits back, but before that commits, they navigate somewhere new. |
-TEST_F(NavigationControllerTest, LoadURL_PrivilegedPending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // First make some history, starting with a privileged URL. |
- const GURL kExistingURL1("http://privileged"); |
- controller.LoadURL( |
- kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- // Pretend it has bindings so we can tell if we incorrectly copy it. |
- test_rvh()->AllowBindings(2); |
- test_rvh()->SendNavigate(0, kExistingURL1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Navigate cross-process to a second URL. |
- const GURL kExistingURL2("http://foo/eh"); |
- controller.LoadURL( |
- kExistingURL2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendShouldCloseACK(true); |
- TestRenderViewHost* foo_rvh = static_cast<TestRenderViewHost*>( |
- contents()->GetPendingRenderViewHost()); |
- foo_rvh->SendNavigate(1, kExistingURL2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Now make a pending back/forward navigation to a privileged entry. |
- // The zeroth entry should be pending. |
- controller.GoBack(); |
- foo_rvh->SendShouldCloseACK(true); |
- EXPECT_EQ(0U, notifications.size()); |
- EXPECT_EQ(0, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(2, NavigationEntryImpl::FromNavigationEntry( |
- controller.GetPendingEntry())->bindings()); |
- |
- // Before that commits, do a new navigation. |
- const GURL kNewURL("http://foo/bee"); |
- LoadCommittedDetails details; |
- foo_rvh->SendNavigate(3, kNewURL); |
- |
- // There should no longer be any pending entry, and the third navigation we |
- // just made should be committed. |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry( |
- controller.GetLastCommittedEntry())->bindings()); |
-} |
- |
-// Tests navigating to an existing URL when there is a pending new navigation. |
-// This will happen if the user enters a URL, but before that commits, the |
-// current page fires history.back(). |
-TEST_F(NavigationControllerTest, LoadURL_BackPreemptsPending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // First make some history. |
- const GURL kExistingURL1("http://foo/eh"); |
- controller.LoadURL( |
- kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, kExistingURL1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- const GURL kExistingURL2("http://foo/bee"); |
- controller.LoadURL( |
- kExistingURL2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(1, kExistingURL2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Now make a pending new navigation. |
- const GURL kNewURL("http://foo/see"); |
- controller.LoadURL( |
- kNewURL, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(0U, notifications.size()); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
- |
- // Before that commits, a back navigation from the renderer commits. |
- test_rvh()->SendNavigate(0, kExistingURL1); |
- |
- // There should no longer be any pending entry, and the back navigation we |
- // just made should be committed. |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(kExistingURL1, controller.GetVisibleEntry()->GetURL()); |
-} |
- |
-// Tests an ignored navigation when there is a pending new navigation. |
-// This will happen if the user enters a URL, but before that commits, the |
-// current blank page reloads. See http://crbug.com/77507. |
-TEST_F(NavigationControllerTest, LoadURL_IgnorePreemptsPending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // Set a WebContentsDelegate to listen for state changes. |
- scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate()); |
- EXPECT_FALSE(contents()->GetDelegate()); |
- contents()->SetDelegate(delegate.get()); |
- |
- // Without any navigations, the renderer starts at about:blank. |
- const GURL kExistingURL(kAboutBlankURL); |
- |
- // Now make a pending new navigation. |
- const GURL kNewURL("http://eh"); |
- controller.LoadURL( |
- kNewURL, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(0U, notifications.size()); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(1, delegate->navigation_state_change_count()); |
- |
- // Before that commits, a document.write and location.reload can cause the |
- // renderer to send a FrameNavigate with page_id -1. |
- test_rvh()->SendNavigate(-1, kExistingURL); |
- |
- // This should clear the pending entry and notify of a navigation state |
- // change, so that we do not keep displaying kNewURL. |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(2, delegate->navigation_state_change_count()); |
- |
- contents()->SetDelegate(NULL); |
-} |
- |
-// Tests that the pending entry state is correct after an abort. |
-// We do not want to clear the pending entry, so that the user doesn't |
-// lose a typed URL. (See http://crbug.com/9682.) |
-TEST_F(NavigationControllerTest, LoadURL_AbortDoesntCancelPending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // Set a WebContentsDelegate to listen for state changes. |
- scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate()); |
- EXPECT_FALSE(contents()->GetDelegate()); |
- contents()->SetDelegate(delegate.get()); |
- |
- // Start with a pending new navigation. |
- const GURL kNewURL("http://eh"); |
- controller.LoadURL( |
- kNewURL, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(0U, notifications.size()); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(1, delegate->navigation_state_change_count()); |
- |
- // It may abort before committing, if it's a download or due to a stop or |
- // a new navigation from the user. |
- ViewHostMsg_DidFailProvisionalLoadWithError_Params params; |
- params.frame_id = 1; |
- params.is_main_frame = true; |
- params.error_code = net::ERR_ABORTED; |
- params.error_description = string16(); |
- params.url = kNewURL; |
- params.showing_repost_interstitial = false; |
- test_rvh()->OnMessageReceived( |
- ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id |
- params)); |
- |
- // This should not clear the pending entry or notify of a navigation state |
- // change, so that we keep displaying kNewURL (until the user clears it). |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(1, delegate->navigation_state_change_count()); |
- NavigationEntry* pending_entry = controller.GetPendingEntry(); |
- |
- // Ensure that a reload keeps the same pending entry. |
- controller.Reload(true); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(pending_entry, controller.GetPendingEntry()); |
- EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex()); |
- |
- contents()->SetDelegate(NULL); |
-} |
- |
-// Tests that the pending URL is not visible during a renderer-initiated |
-// redirect and abort. See http://crbug.com/83031. |
-TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // First make an existing committed entry. |
- const GURL kExistingURL("http://foo/eh"); |
- controller.LoadURL(kExistingURL, content::Referrer(), |
- content::PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, kExistingURL); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Set a WebContentsDelegate to listen for state changes. |
- scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate()); |
- EXPECT_FALSE(contents()->GetDelegate()); |
- contents()->SetDelegate(delegate.get()); |
- |
- // Now make a pending new navigation, initiated by the renderer. |
- const GURL kNewURL("http://foo/bee"); |
- NavigationController::LoadURLParams load_url_params(kNewURL); |
- load_url_params.transition_type = PAGE_TRANSITION_TYPED; |
- load_url_params.is_renderer_initiated = true; |
- controller.LoadURLWithParams(load_url_params); |
- EXPECT_EQ(0U, notifications.size()); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(0, delegate->navigation_state_change_count()); |
- |
- // The visible entry should be the last committed URL, not the pending one. |
- EXPECT_EQ(kExistingURL, controller.GetVisibleEntry()->GetURL()); |
- |
- // Now the navigation redirects. |
- const GURL kRedirectURL("http://foo/see"); |
- test_rvh()->OnMessageReceived( |
- ViewHostMsg_DidRedirectProvisionalLoad(0, // routing_id |
- -1, // pending page_id |
- kNewURL, // old url |
- kRedirectURL)); // new url |
- |
- // We don't want to change the NavigationEntry's url, in case it cancels. |
- // Prevents regression of http://crbug.com/77786. |
- EXPECT_EQ(kNewURL, controller.GetPendingEntry()->GetURL()); |
- |
- // It may abort before committing, if it's a download or due to a stop or |
- // a new navigation from the user. |
- ViewHostMsg_DidFailProvisionalLoadWithError_Params params; |
- params.frame_id = 1; |
- params.is_main_frame = true; |
- params.error_code = net::ERR_ABORTED; |
- params.error_description = string16(); |
- params.url = kRedirectURL; |
- params.showing_repost_interstitial = false; |
- test_rvh()->OnMessageReceived( |
- ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id |
- params)); |
- |
- // Because the pending entry is renderer initiated and not visible, we |
- // clear it when it fails. |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(0, delegate->navigation_state_change_count()); |
- |
- // The visible entry should be the last committed URL, not the pending one, |
- // so that no spoof is possible. |
- EXPECT_EQ(kExistingURL, controller.GetVisibleEntry()->GetURL()); |
- |
- contents()->SetDelegate(NULL); |
-} |
- |
-// Ensure that NavigationEntries track which bindings their RenderViewHost had |
-// at the time they committed. http://crbug.com/173672. |
-TEST_F(NavigationControllerTest, LoadURL_WithBindings) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- |
- // Navigate to a first, unprivileged URL. |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(NavigationEntryImpl::kInvalidBindings, |
- NavigationEntryImpl::FromNavigationEntry( |
- controller.GetPendingEntry())->bindings()); |
- |
- // Commit. |
- TestRenderViewHost* orig_rvh = static_cast<TestRenderViewHost*>(test_rvh()); |
- orig_rvh->SendNavigate(0, url1); |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry( |
- controller.GetLastCommittedEntry())->bindings()); |
- |
- // Manually increase the number of active views in the SiteInstance |
- // that orig_rvh belongs to, to prevent it from being destroyed when |
- // it gets swapped out, so that we can reuse orig_rvh when the |
- // controller goes back. |
- static_cast<SiteInstanceImpl*>(orig_rvh->GetSiteInstance())-> |
- increment_active_view_count(); |
- |
- // Navigate to a second URL, simulate the beforeunload ack for the cross-site |
- // transition, and set bindings on the pending RenderViewHost to simulate a |
- // privileged url. |
- controller.LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- orig_rvh->SendShouldCloseACK(true); |
- contents()->GetPendingRenderViewHost()->AllowBindings(1); |
- static_cast<TestRenderViewHost*>( |
- contents()->GetPendingRenderViewHost())->SendNavigate(1, url2); |
- |
- // The second load should be committed, and bindings should be remembered. |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_EQ(1, NavigationEntryImpl::FromNavigationEntry( |
- controller.GetLastCommittedEntry())->bindings()); |
- |
- // Going back, the first entry should still appear unprivileged. |
- controller.GoBack(); |
- orig_rvh->SendNavigate(0, url1); |
- EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry( |
- controller.GetLastCommittedEntry())->bindings()); |
-} |
- |
-TEST_F(NavigationControllerTest, Reload) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(0U, notifications.size()); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- ASSERT_TRUE(controller.GetVisibleEntry()); |
- controller.GetVisibleEntry()->SetTitle(ASCIIToUTF16("Title")); |
- controller.Reload(true); |
- EXPECT_EQ(0U, notifications.size()); |
- |
- const base::Time timestamp = controller.GetVisibleEntry()->GetTimestamp(); |
- EXPECT_FALSE(timestamp.is_null()); |
- |
- // The reload is pending. |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), 0); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- // Make sure the title has been cleared (will be redrawn just after reload). |
- // Avoids a stale cached title when the new page being reloaded has no title. |
- // See http://crbug.com/96041. |
- EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty()); |
- |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Now the reload is committed. |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- |
- // The timestamp should have been updated. |
- ASSERT_TRUE(controller.GetVisibleEntry()); |
- EXPECT_GE(controller.GetVisibleEntry()->GetTimestamp(), timestamp); |
-} |
- |
-// Tests what happens when a reload navigation produces a new page. |
-TEST_F(NavigationControllerTest, Reload_GeneratesNewPage) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- controller.Reload(true); |
- EXPECT_EQ(0U, notifications.size()); |
- |
- test_rvh()->SendNavigate(1, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Now the reload is committed. |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
-} |
- |
-#if !defined(OS_ANDROID) // http://crbug.com/157428 |
-TEST_F(NavigationControllerTest, ReloadOriginalRequestURL) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL original_url("http://foo1"); |
- const GURL final_url("http://foo2"); |
- |
- // Load up the original URL, but get redirected. |
- controller.LoadURL( |
- original_url, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(0U, notifications.size()); |
- test_rvh()->SendNavigateWithOriginalRequestURL(0, final_url, original_url); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // The NavigationEntry should save both the original URL and the final |
- // redirected URL. |
- EXPECT_EQ( |
- original_url, controller.GetVisibleEntry()->GetOriginalRequestURL()); |
- EXPECT_EQ(final_url, controller.GetVisibleEntry()->GetURL()); |
- |
- // Reload using the original URL. |
- controller.GetVisibleEntry()->SetTitle(ASCIIToUTF16("Title")); |
- controller.ReloadOriginalRequestURL(false); |
- EXPECT_EQ(0U, notifications.size()); |
- |
- // The reload is pending. The request should point to the original URL. |
- EXPECT_EQ(original_url, navigated_url()); |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), 0); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- |
- // Make sure the title has been cleared (will be redrawn just after reload). |
- // Avoids a stale cached title when the new page being reloaded has no title. |
- // See http://crbug.com/96041. |
- EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty()); |
- |
- // Send that the navigation has proceeded; say it got redirected again. |
- test_rvh()->SendNavigate(0, final_url); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Now the reload is committed. |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
-} |
- |
-#endif // !defined(OS_ANDROID) |
- |
-// Tests what happens when we navigate back successfully |
-TEST_F(NavigationControllerTest, Back) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- const GURL url2("http://foo2"); |
- test_rvh()->SendNavigate(1, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- controller.GoBack(); |
- EXPECT_EQ(0U, notifications.size()); |
- |
- // We should now have a pending navigation to go back. |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), 0); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoToOffset(-1)); |
- EXPECT_TRUE(controller.CanGoForward()); |
- EXPECT_TRUE(controller.CanGoToOffset(1)); |
- EXPECT_FALSE(controller.CanGoToOffset(2)); // Cannot go foward 2 steps. |
- |
- // Timestamp for entry 1 should be on or after that of entry 0. |
- EXPECT_FALSE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null()); |
- EXPECT_GE(controller.GetEntryAtIndex(1)->GetTimestamp(), |
- controller.GetEntryAtIndex(0)->GetTimestamp()); |
- |
- test_rvh()->SendNavigate(0, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // The back navigation completed successfully. |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoToOffset(-1)); |
- EXPECT_TRUE(controller.CanGoForward()); |
- EXPECT_TRUE(controller.CanGoToOffset(1)); |
- EXPECT_FALSE(controller.CanGoToOffset(2)); // Cannot go foward 2 steps. |
- |
- // Timestamp for entry 0 should be on or after that of entry 1 |
- // (since we went back to it). |
- EXPECT_GE(controller.GetEntryAtIndex(0)->GetTimestamp(), |
- controller.GetEntryAtIndex(1)->GetTimestamp()); |
-} |
- |
-// Tests what happens when a back navigation produces a new page. |
-TEST_F(NavigationControllerTest, Back_GeneratesNewPage) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo/1"); |
- const GURL url2("http://foo/2"); |
- const GURL url3("http://foo/3"); |
- |
- controller.LoadURL( |
- url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- controller.LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(1, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- controller.GoBack(); |
- EXPECT_EQ(0U, notifications.size()); |
- |
- // We should now have a pending navigation to go back. |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), 0); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_TRUE(controller.CanGoForward()); |
- |
- test_rvh()->SendNavigate(2, url3); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // The back navigation resulted in a completely new navigation. |
- // TODO(darin): perhaps this behavior will be confusing to users? |
- EXPECT_EQ(controller.GetEntryCount(), 3); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 2); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
-} |
- |
-// Receives a back message when there is a new pending navigation entry. |
-TEST_F(NavigationControllerTest, Back_NewPending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL kUrl1("http://foo1"); |
- const GURL kUrl2("http://foo2"); |
- const GURL kUrl3("http://foo3"); |
- |
- // First navigate two places so we have some back history. |
- test_rvh()->SendNavigate(0, kUrl1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // controller.LoadURL(kUrl2, PAGE_TRANSITION_TYPED); |
- test_rvh()->SendNavigate(1, kUrl2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Now start a new pending navigation and go back before it commits. |
- controller.LoadURL(kUrl3, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(kUrl3, controller.GetPendingEntry()->GetURL()); |
- controller.GoBack(); |
- |
- // The pending navigation should now be the "back" item and the new one |
- // should be gone. |
- EXPECT_EQ(0, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(kUrl1, controller.GetPendingEntry()->GetURL()); |
-} |
- |
-// Receives a back message when there is a different renavigation already |
-// pending. |
-TEST_F(NavigationControllerTest, Back_OtherBackPending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL kUrl1("http://foo/1"); |
- const GURL kUrl2("http://foo/2"); |
- const GURL kUrl3("http://foo/3"); |
- |
- // First navigate three places so we have some back history. |
- test_rvh()->SendNavigate(0, kUrl1); |
- test_rvh()->SendNavigate(1, kUrl2); |
- test_rvh()->SendNavigate(2, kUrl3); |
- |
- // With nothing pending, say we get a navigation to the second entry. |
- test_rvh()->SendNavigate(1, kUrl2); |
- |
- // We know all the entries have the same site instance, so we can just grab |
- // a random one for looking up other entries. |
- SiteInstance* site_instance = |
- NavigationEntryImpl::FromNavigationEntry( |
- controller.GetLastCommittedEntry())->site_instance(); |
- |
- // That second URL should be the last committed and it should have gotten the |
- // new title. |
- EXPECT_EQ(kUrl2, controller.GetEntryWithPageID(site_instance, 1)->GetURL()); |
- EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- |
- // Now go forward to the last item again and say it was committed. |
- controller.GoForward(); |
- test_rvh()->SendNavigate(2, kUrl3); |
- |
- // Now start going back one to the second page. It will be pending. |
- controller.GoBack(); |
- EXPECT_EQ(1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); |
- |
- // Not synthesize a totally new back event to the first page. This will not |
- // match the pending one. |
- test_rvh()->SendNavigate(0, kUrl1); |
- |
- // The committed navigation should clear the pending entry. |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- |
- // But the navigated entry should be the last committed. |
- EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(kUrl1, controller.GetLastCommittedEntry()->GetURL()); |
-} |
- |
-// Tests what happens when we navigate forward successfully. |
-TEST_F(NavigationControllerTest, Forward) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- test_rvh()->SendNavigate(1, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- controller.GoBack(); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- controller.GoForward(); |
- |
- // We should now have a pending navigation to go forward. |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), 1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_TRUE(controller.CanGoToOffset(-1)); |
- EXPECT_FALSE(controller.CanGoToOffset(-2)); // Cannot go back 2 steps. |
- EXPECT_FALSE(controller.CanGoForward()); |
- EXPECT_FALSE(controller.CanGoToOffset(1)); |
- |
- // Timestamp for entry 0 should be on or after that of entry 1 |
- // (since we went back to it). |
- EXPECT_FALSE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null()); |
- EXPECT_GE(controller.GetEntryAtIndex(0)->GetTimestamp(), |
- controller.GetEntryAtIndex(1)->GetTimestamp()); |
- |
- test_rvh()->SendNavigate(1, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // The forward navigation completed successfully. |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_TRUE(controller.CanGoToOffset(-1)); |
- EXPECT_FALSE(controller.CanGoToOffset(-2)); // Cannot go back 2 steps. |
- EXPECT_FALSE(controller.CanGoForward()); |
- EXPECT_FALSE(controller.CanGoToOffset(1)); |
- |
- // Timestamp for entry 1 should be on or after that of entry 0 |
- // (since we went forward to it). |
- EXPECT_GE(controller.GetEntryAtIndex(1)->GetTimestamp(), |
- controller.GetEntryAtIndex(0)->GetTimestamp()); |
-} |
- |
-// Tests what happens when a forward navigation produces a new page. |
-TEST_F(NavigationControllerTest, Forward_GeneratesNewPage) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- const GURL url3("http://foo3"); |
- |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- test_rvh()->SendNavigate(1, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- controller.GoBack(); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- controller.GoForward(); |
- EXPECT_EQ(0U, notifications.size()); |
- |
- // Should now have a pending navigation to go forward. |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), 1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- |
- test_rvh()->SendNavigate(2, url3); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_TRUE(notifications.Check1AndReset(NOTIFICATION_NAV_LIST_PRUNED)); |
- |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
-} |
- |
-// Two consequent navigation for the same URL entered in should be considered |
-// as SAME_PAGE navigation even when we are redirected to some other page. |
-TEST_F(NavigationControllerTest, Redirect) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); // Redirection target |
- |
- // First request |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- |
- EXPECT_EQ(0U, notifications.size()); |
- test_rvh()->SendNavigate(0, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Second request |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); |
- |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 0; |
- params.url = url2; |
- params.transition = PAGE_TRANSITION_SERVER_REDIRECT; |
- params.redirects.push_back(GURL("http://foo1")); |
- params.redirects.push_back(GURL("http://foo2")); |
- params.should_update_history = false; |
- params.gesture = NavigationGestureAuto; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url2); |
- |
- LoadCommittedDetails details; |
- |
- EXPECT_EQ(0U, notifications.size()); |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- EXPECT_TRUE(details.type == NAVIGATION_TYPE_SAME_PAGE); |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); |
- |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
-} |
- |
-// Similar to Redirect above, but the first URL is requested by POST, |
-// the second URL is requested by GET. NavigationEntry::has_post_data_ |
-// must be cleared. http://crbug.com/21245 |
-TEST_F(NavigationControllerTest, PostThenRedirect) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); // Redirection target |
- |
- // First request as POST |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- controller.GetVisibleEntry()->SetHasPostData(true); |
- |
- EXPECT_EQ(0U, notifications.size()); |
- test_rvh()->SendNavigate(0, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Second request |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); |
- |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 0; |
- params.url = url2; |
- params.transition = PAGE_TRANSITION_SERVER_REDIRECT; |
- params.redirects.push_back(GURL("http://foo1")); |
- params.redirects.push_back(GURL("http://foo2")); |
- params.should_update_history = false; |
- params.gesture = NavigationGestureAuto; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url2); |
- |
- LoadCommittedDetails details; |
- |
- EXPECT_EQ(0U, notifications.size()); |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- EXPECT_TRUE(details.type == NAVIGATION_TYPE_SAME_PAGE); |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_FALSE(controller.GetVisibleEntry()->GetHasPostData()); |
- |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
-} |
- |
-// A redirect right off the bat should be a NEW_PAGE. |
-TEST_F(NavigationControllerTest, ImmediateRedirect) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); // Redirection target |
- |
- // First request |
- controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); |
- |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 0; |
- params.url = url2; |
- params.transition = PAGE_TRANSITION_SERVER_REDIRECT; |
- params.redirects.push_back(GURL("http://foo1")); |
- params.redirects.push_back(GURL("http://foo2")); |
- params.should_update_history = false; |
- params.gesture = NavigationGestureAuto; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url2); |
- |
- LoadCommittedDetails details; |
- |
- EXPECT_EQ(0U, notifications.size()); |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- EXPECT_TRUE(details.type == NAVIGATION_TYPE_NEW_PAGE); |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); |
- |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
-} |
- |
-// Tests navigation via link click within a subframe. A new navigation entry |
-// should be created. |
-TEST_F(NavigationControllerTest, NewSubframe) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- const GURL url2("http://foo2"); |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 1; |
- params.url = url2; |
- params.transition = PAGE_TRANSITION_MANUAL_SUBFRAME; |
- params.should_update_history = false; |
- params.gesture = NavigationGestureUser; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url2); |
- |
- LoadCommittedDetails details; |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(url1, details.previous_url); |
- EXPECT_FALSE(details.is_in_page); |
- EXPECT_FALSE(details.is_main_frame); |
- |
- // The new entry should be appended. |
- EXPECT_EQ(2, controller.GetEntryCount()); |
- |
- // New entry should refer to the new page, but the old URL (entries only |
- // reflect the toplevel URL). |
- EXPECT_EQ(url1, details.entry->GetURL()); |
- EXPECT_EQ(params.page_id, details.entry->GetPageID()); |
-} |
- |
-// Some pages create a popup, then write an iframe into it. This causes a |
-// subframe navigation without having any committed entry. Such navigations |
-// just get thrown on the ground, but we shouldn't crash. |
-TEST_F(NavigationControllerTest, SubframeOnEmptyPage) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // Navigation controller currently has no entries. |
- const GURL url("http://foo2"); |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 1; |
- params.url = url; |
- params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; |
- params.should_update_history = false; |
- params.gesture = NavigationGestureAuto; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url); |
- |
- LoadCommittedDetails details; |
- EXPECT_FALSE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(0U, notifications.size()); |
-} |
- |
-// Auto subframes are ones the page loads automatically like ads. They should |
-// not create new navigation entries. |
-TEST_F(NavigationControllerTest, AutoSubframe) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- const GURL url2("http://foo2"); |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 0; |
- params.url = url2; |
- params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; |
- params.should_update_history = false; |
- params.gesture = NavigationGestureUser; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url2); |
- |
- // Navigating should do nothing. |
- LoadCommittedDetails details; |
- EXPECT_FALSE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(0U, notifications.size()); |
- |
- // There should still be only one entry. |
- EXPECT_EQ(1, controller.GetEntryCount()); |
-} |
- |
-// Tests navigation and then going back to a subframe navigation. |
-TEST_F(NavigationControllerTest, BackSubframe) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // Main page. |
- const GURL url1("http://foo1"); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // First manual subframe navigation. |
- const GURL url2("http://foo2"); |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 1; |
- params.url = url2; |
- params.transition = PAGE_TRANSITION_MANUAL_SUBFRAME; |
- params.should_update_history = false; |
- params.gesture = NavigationGestureUser; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url2); |
- |
- // This should generate a new entry. |
- LoadCommittedDetails details; |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(2, controller.GetEntryCount()); |
- |
- // Second manual subframe navigation should also make a new entry. |
- const GURL url3("http://foo3"); |
- params.page_id = 2; |
- params.url = url3; |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(3, controller.GetEntryCount()); |
- EXPECT_EQ(2, controller.GetCurrentEntryIndex()); |
- |
- // Go back one. |
- controller.GoBack(); |
- params.url = url2; |
- params.page_id = 1; |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(3, controller.GetEntryCount()); |
- EXPECT_EQ(1, controller.GetCurrentEntryIndex()); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- |
- // Go back one more. |
- controller.GoBack(); |
- params.url = url1; |
- params.page_id = 0; |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(3, controller.GetEntryCount()); |
- EXPECT_EQ(0, controller.GetCurrentEntryIndex()); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
-} |
- |
-TEST_F(NavigationControllerTest, LinkClick) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- test_rvh()->SendNavigate(1, url2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Should not have produced a new session history entry. |
- EXPECT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
-} |
- |
-TEST_F(NavigationControllerTest, InPage) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // Main page. |
- const GURL url1("http://foo"); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Ensure main page navigation to same url respects the was_within_same_page |
- // hint provided in the params. |
- ViewHostMsg_FrameNavigate_Params self_params; |
- self_params.page_id = 0; |
- self_params.url = url1; |
- self_params.transition = PAGE_TRANSITION_LINK; |
- self_params.should_update_history = false; |
- self_params.gesture = NavigationGestureUser; |
- self_params.is_post = false; |
- self_params.page_state = PageState::CreateFromURL(url1); |
- self_params.was_within_same_page = true; |
- |
- LoadCommittedDetails details; |
- EXPECT_TRUE(controller.RendererDidNavigate(self_params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_TRUE(details.is_in_page); |
- EXPECT_TRUE(details.did_replace_entry); |
- EXPECT_EQ(1, controller.GetEntryCount()); |
- |
- // Fragment navigation to a new page_id. |
- const GURL url2("http://foo#a"); |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 1; |
- params.url = url2; |
- params.transition = PAGE_TRANSITION_LINK; |
- params.should_update_history = false; |
- params.gesture = NavigationGestureUser; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url2); |
- params.was_within_same_page = true; |
- |
- // This should generate a new entry. |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_TRUE(details.is_in_page); |
- EXPECT_FALSE(details.did_replace_entry); |
- EXPECT_EQ(2, controller.GetEntryCount()); |
- |
- // Go back one. |
- ViewHostMsg_FrameNavigate_Params back_params(params); |
- controller.GoBack(); |
- back_params.url = url1; |
- back_params.page_id = 0; |
- EXPECT_TRUE(controller.RendererDidNavigate(back_params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_TRUE(details.is_in_page); |
- EXPECT_EQ(2, controller.GetEntryCount()); |
- EXPECT_EQ(0, controller.GetCurrentEntryIndex()); |
- EXPECT_EQ(back_params.url, controller.GetVisibleEntry()->GetURL()); |
- |
- // Go forward |
- ViewHostMsg_FrameNavigate_Params forward_params(params); |
- controller.GoForward(); |
- forward_params.url = url2; |
- forward_params.page_id = 1; |
- EXPECT_TRUE(controller.RendererDidNavigate(forward_params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_TRUE(details.is_in_page); |
- EXPECT_EQ(2, controller.GetEntryCount()); |
- EXPECT_EQ(1, controller.GetCurrentEntryIndex()); |
- EXPECT_EQ(forward_params.url, |
- controller.GetVisibleEntry()->GetURL()); |
- |
- // Now go back and forward again. This is to work around a bug where we would |
- // compare the incoming URL with the last committed entry rather than the |
- // one identified by an existing page ID. This would result in the second URL |
- // losing the reference fragment when you navigate away from it and then back. |
- controller.GoBack(); |
- EXPECT_TRUE(controller.RendererDidNavigate(back_params, &details)); |
- controller.GoForward(); |
- EXPECT_TRUE(controller.RendererDidNavigate(forward_params, &details)); |
- EXPECT_EQ(forward_params.url, |
- controller.GetVisibleEntry()->GetURL()); |
- |
- // 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; |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_FALSE(details.is_in_page); |
- EXPECT_EQ(3, controller.GetEntryCount()); |
- EXPECT_EQ(2, controller.GetCurrentEntryIndex()); |
-} |
- |
-TEST_F(NavigationControllerTest, InPage_Replace) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // Main page. |
- const GURL url1("http://foo"); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // First navigation. |
- const GURL url2("http://foo#a"); |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 0; // Same page_id |
- params.url = url2; |
- params.transition = PAGE_TRANSITION_LINK; |
- params.should_update_history = false; |
- params.gesture = NavigationGestureUser; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url2); |
- |
- // This should NOT generate a new entry, nor prune the list. |
- LoadCommittedDetails details; |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_TRUE(details.is_in_page); |
- EXPECT_TRUE(details.did_replace_entry); |
- EXPECT_EQ(1, controller.GetEntryCount()); |
-} |
- |
-// Tests for http://crbug.com/40395 |
-// Simulates this: |
-// <script> |
-// window.location.replace("#a"); |
-// window.location='http://foo3/'; |
-// </script> |
-TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // Load an initial page. |
- { |
- const GURL url("http://foo/"); |
- test_rvh()->SendNavigate(0, url); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- } |
- |
- // Navigate to a new page. |
- { |
- const GURL url("http://foo2/"); |
- test_rvh()->SendNavigate(1, url); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- } |
- |
- // Navigate within the page. |
- { |
- const GURL url("http://foo2/#a"); |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 1; // Same page_id |
- params.url = url; |
- params.transition = PAGE_TRANSITION_LINK; |
- params.redirects.push_back(url); |
- params.should_update_history = true; |
- params.gesture = NavigationGestureUnknown; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url); |
- |
- // This should NOT generate a new entry, nor prune the list. |
- LoadCommittedDetails details; |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_TRUE(details.is_in_page); |
- EXPECT_TRUE(details.did_replace_entry); |
- EXPECT_EQ(2, controller.GetEntryCount()); |
- } |
- |
- // Perform a client redirect to a new page. |
- { |
- const GURL url("http://foo3/"); |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 2; // New page_id |
- params.url = url; |
- params.transition = PAGE_TRANSITION_CLIENT_REDIRECT; |
- params.redirects.push_back(GURL("http://foo2/#a")); |
- params.redirects.push_back(url); |
- params.should_update_history = true; |
- params.gesture = NavigationGestureUnknown; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url); |
- |
- // This SHOULD generate a new entry. |
- LoadCommittedDetails details; |
- EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_FALSE(details.is_in_page); |
- EXPECT_EQ(3, controller.GetEntryCount()); |
- } |
- |
- // Verify that BACK brings us back to http://foo2/. |
- { |
- const GURL url("http://foo2/"); |
- controller.GoBack(); |
- test_rvh()->SendNavigate(1, url); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL()); |
- } |
-} |
- |
-// NotificationObserver implementation used in verifying we've received the |
-// NOTIFICATION_NAV_LIST_PRUNED method. |
-class PrunedListener : public NotificationObserver { |
- public: |
- explicit PrunedListener(NavigationControllerImpl* controller) |
- : notification_count_(0) { |
- registrar_.Add(this, NOTIFICATION_NAV_LIST_PRUNED, |
- Source<NavigationController>(controller)); |
- } |
- |
- virtual void Observe(int type, |
- const NotificationSource& source, |
- const NotificationDetails& details) OVERRIDE { |
- if (type == NOTIFICATION_NAV_LIST_PRUNED) { |
- notification_count_++; |
- details_ = *(Details<PrunedDetails>(details).ptr()); |
- } |
- } |
- |
- // Number of times NAV_LIST_PRUNED has been observed. |
- int notification_count_; |
- |
- // Details from the last NAV_LIST_PRUNED. |
- PrunedDetails details_; |
- |
- private: |
- NotificationRegistrar registrar_; |
- |
- DISALLOW_COPY_AND_ASSIGN(PrunedListener); |
-}; |
- |
-// Tests that we limit the number of navigation entries created correctly. |
-TEST_F(NavigationControllerTest, EnforceMaxNavigationCount) { |
- NavigationControllerImpl& controller = controller_impl(); |
- size_t original_count = NavigationControllerImpl::max_entry_count(); |
- const int kMaxEntryCount = 5; |
- |
- NavigationControllerImpl::set_max_entry_count_for_testing(kMaxEntryCount); |
- |
- int url_index; |
- // Load up to the max count, all entries should be there. |
- for (url_index = 0; url_index < kMaxEntryCount; url_index++) { |
- GURL url(base::StringPrintf("http://www.a.com/%d", url_index)); |
- controller.LoadURL( |
- url, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(url_index, url); |
- } |
- |
- EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount); |
- |
- // Created a PrunedListener to observe prune notifications. |
- PrunedListener listener(&controller); |
- |
- // Navigate some more. |
- GURL url(base::StringPrintf("http://www.a.com/%d", url_index)); |
- controller.LoadURL( |
- url, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(url_index, url); |
- url_index++; |
- |
- // We should have got a pruned navigation. |
- EXPECT_EQ(1, listener.notification_count_); |
- EXPECT_TRUE(listener.details_.from_front); |
- EXPECT_EQ(1, listener.details_.count); |
- |
- // We expect http://www.a.com/0 to be gone. |
- EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount); |
- EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), |
- GURL("http:////www.a.com/1")); |
- |
- // More navigations. |
- for (int i = 0; i < 3; i++) { |
- url = GURL(base::StringPrintf("http:////www.a.com/%d", url_index)); |
- controller.LoadURL( |
- url, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(url_index, url); |
- url_index++; |
- } |
- EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount); |
- EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), |
- GURL("http:////www.a.com/4")); |
- |
- NavigationControllerImpl::set_max_entry_count_for_testing(original_count); |
-} |
- |
-// Tests that we can do a restore and navigate to the restored entries and |
-// everything is updated properly. This can be tricky since there is no |
-// SiteInstance for the entries created initially. |
-TEST_F(NavigationControllerTest, RestoreNavigate) { |
- // Create a NavigationController with a restored set of tabs. |
- GURL url("http://foo"); |
- std::vector<NavigationEntry*> entries; |
- NavigationEntry* entry = NavigationControllerImpl::CreateNavigationEntry( |
- url, Referrer(), PAGE_TRANSITION_RELOAD, false, std::string(), |
- browser_context()); |
- entry->SetPageID(0); |
- entry->SetTitle(ASCIIToUTF16("Title")); |
- entry->SetPageState(PageState::CreateFromEncodedData("state")); |
- const base::Time timestamp = base::Time::Now(); |
- entry->SetTimestamp(timestamp); |
- entries.push_back(entry); |
- scoped_ptr<WebContentsImpl> our_contents(static_cast<WebContentsImpl*>( |
- WebContents::Create(WebContents::CreateParams(browser_context())))); |
- NavigationControllerImpl& our_controller = our_contents->GetController(); |
- our_controller.Restore( |
- 0, |
- NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, |
- &entries); |
- ASSERT_EQ(0u, entries.size()); |
- |
- // Before navigating to the restored entry, it should have a restore_type |
- // and no SiteInstance. |
- ASSERT_EQ(1, our_controller.GetEntryCount()); |
- EXPECT_EQ(NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY, |
- NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetEntryAtIndex(0))->restore_type()); |
- EXPECT_FALSE(NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetEntryAtIndex(0))->site_instance()); |
- |
- // After navigating, we should have one entry, and it should be "pending". |
- // It should now have a SiteInstance and no restore_type. |
- our_controller.GoToIndex(0); |
- EXPECT_EQ(1, our_controller.GetEntryCount()); |
- EXPECT_EQ(our_controller.GetEntryAtIndex(0), |
- our_controller.GetPendingEntry()); |
- EXPECT_EQ(0, our_controller.GetEntryAtIndex(0)->GetPageID()); |
- EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE, |
- NavigationEntryImpl::FromNavigationEntry |
- (our_controller.GetEntryAtIndex(0))->restore_type()); |
- EXPECT_TRUE(NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetEntryAtIndex(0))->site_instance()); |
- |
- // Timestamp should remain the same before the navigation finishes. |
- EXPECT_EQ(timestamp, our_controller.GetEntryAtIndex(0)->GetTimestamp()); |
- |
- // Say we navigated to that entry. |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 0; |
- params.url = url; |
- params.transition = PAGE_TRANSITION_LINK; |
- params.should_update_history = false; |
- params.gesture = NavigationGestureUser; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url); |
- LoadCommittedDetails details; |
- our_controller.RendererDidNavigate(params, &details); |
- |
- // There should be no longer any pending entry and one committed one. This |
- // means that we were able to locate the entry, assign its site instance, and |
- // commit it properly. |
- EXPECT_EQ(1, our_controller.GetEntryCount()); |
- EXPECT_EQ(0, our_controller.GetLastCommittedEntryIndex()); |
- EXPECT_FALSE(our_controller.GetPendingEntry()); |
- EXPECT_EQ(url, |
- NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetLastCommittedEntry())->site_instance()-> |
- GetSiteURL()); |
- EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE, |
- NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetEntryAtIndex(0))->restore_type()); |
- |
- // Timestamp should have been updated. |
- EXPECT_GE(our_controller.GetEntryAtIndex(0)->GetTimestamp(), timestamp); |
-} |
- |
-// Tests that we can still navigate to a restored entry after a different |
-// navigation fails and clears the pending entry. http://crbug.com/90085 |
-TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) { |
- // Create a NavigationController with a restored set of tabs. |
- GURL url("http://foo"); |
- std::vector<NavigationEntry*> entries; |
- NavigationEntry* entry = NavigationControllerImpl::CreateNavigationEntry( |
- url, Referrer(), PAGE_TRANSITION_RELOAD, false, std::string(), |
- browser_context()); |
- entry->SetPageID(0); |
- entry->SetTitle(ASCIIToUTF16("Title")); |
- entry->SetPageState(PageState::CreateFromEncodedData("state")); |
- entries.push_back(entry); |
- scoped_ptr<WebContentsImpl> our_contents(static_cast<WebContentsImpl*>( |
- WebContents::Create(WebContents::CreateParams(browser_context())))); |
- NavigationControllerImpl& our_controller = our_contents->GetController(); |
- our_controller.Restore( |
- 0, NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries); |
- ASSERT_EQ(0u, entries.size()); |
- |
- // Before navigating to the restored entry, it should have a restore_type |
- // and no SiteInstance. |
- EXPECT_EQ(NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY, |
- NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetEntryAtIndex(0))->restore_type()); |
- EXPECT_FALSE(NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetEntryAtIndex(0))->site_instance()); |
- |
- // After navigating, we should have one entry, and it should be "pending". |
- // It should now have a SiteInstance and no restore_type. |
- our_controller.GoToIndex(0); |
- EXPECT_EQ(1, our_controller.GetEntryCount()); |
- EXPECT_EQ(our_controller.GetEntryAtIndex(0), |
- our_controller.GetPendingEntry()); |
- EXPECT_EQ(0, our_controller.GetEntryAtIndex(0)->GetPageID()); |
- EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE, |
- NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetEntryAtIndex(0))->restore_type()); |
- EXPECT_TRUE(NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetEntryAtIndex(0))->site_instance()); |
- |
- // This pending navigation may have caused a different navigation to fail, |
- // which causes the pending entry to be cleared. |
- TestRenderViewHost* rvh = |
- static_cast<TestRenderViewHost*>(our_contents->GetRenderViewHost()); |
- ViewHostMsg_DidFailProvisionalLoadWithError_Params fail_load_params; |
- fail_load_params.frame_id = 1; |
- fail_load_params.is_main_frame = true; |
- fail_load_params.error_code = net::ERR_ABORTED; |
- fail_load_params.error_description = string16(); |
- fail_load_params.url = url; |
- fail_load_params.showing_repost_interstitial = false; |
- rvh->OnMessageReceived( |
- ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id |
- fail_load_params)); |
- |
- // Now the pending restored entry commits. |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 0; |
- params.url = url; |
- params.transition = PAGE_TRANSITION_LINK; |
- params.should_update_history = false; |
- params.gesture = NavigationGestureUser; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url); |
- LoadCommittedDetails details; |
- our_controller.RendererDidNavigate(params, &details); |
- |
- // There should be no pending entry and one committed one. |
- EXPECT_EQ(1, our_controller.GetEntryCount()); |
- EXPECT_EQ(0, our_controller.GetLastCommittedEntryIndex()); |
- EXPECT_FALSE(our_controller.GetPendingEntry()); |
- EXPECT_EQ(url, |
- NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetLastCommittedEntry())->site_instance()-> |
- GetSiteURL()); |
- EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE, |
- NavigationEntryImpl::FromNavigationEntry( |
- our_controller.GetEntryAtIndex(0))->restore_type()); |
-} |
- |
-// Make sure that the page type and stuff is correct after an interstitial. |
-TEST_F(NavigationControllerTest, Interstitial) { |
- NavigationControllerImpl& controller = controller_impl(); |
- // First navigate somewhere normal. |
- const GURL url1("http://foo"); |
- controller.LoadURL( |
- url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, url1); |
- |
- // Now navigate somewhere with an interstitial. |
- const GURL url2("http://bar"); |
- controller.LoadURL( |
- url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> |
- set_page_type(PAGE_TYPE_INTERSTITIAL); |
- |
- // At this point the interstitial will be displayed and the load will still |
- // be pending. If the user continues, the load will commit. |
- test_rvh()->SendNavigate(1, url2); |
- |
- // The page should be a normal page again. |
- EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL()); |
- EXPECT_EQ(PAGE_TYPE_NORMAL, |
- controller.GetLastCommittedEntry()->GetPageType()); |
-} |
- |
-TEST_F(NavigationControllerTest, RemoveEntry) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo/1"); |
- const GURL url2("http://foo/2"); |
- const GURL url3("http://foo/3"); |
- const GURL url4("http://foo/4"); |
- const GURL url5("http://foo/5"); |
- const GURL pending_url("http://foo/pending"); |
- const GURL default_url("http://foo/default"); |
- |
- controller.LoadURL( |
- url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, url1); |
- controller.LoadURL( |
- url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(1, url2); |
- controller.LoadURL( |
- url3, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(2, url3); |
- controller.LoadURL( |
- url4, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(3, url4); |
- controller.LoadURL( |
- url5, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(4, url5); |
- |
- // Try to remove the last entry. Will fail because it is the current entry. |
- EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1)); |
- EXPECT_EQ(5, controller.GetEntryCount()); |
- EXPECT_EQ(4, controller.GetLastCommittedEntryIndex()); |
- |
- // Go back, but don't commit yet. Check that we can't delete the current |
- // and pending entries. |
- controller.GoBack(); |
- EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1)); |
- EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 2)); |
- |
- // Now commit and delete the last entry. |
- test_rvh()->SendNavigate(3, url4); |
- EXPECT_TRUE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1)); |
- EXPECT_EQ(4, controller.GetEntryCount()); |
- EXPECT_EQ(3, controller.GetLastCommittedEntryIndex()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- |
- // Remove an entry which is not the last committed one. |
- EXPECT_TRUE(controller.RemoveEntryAtIndex(0)); |
- EXPECT_EQ(3, controller.GetEntryCount()); |
- EXPECT_EQ(2, controller.GetLastCommittedEntryIndex()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- |
- // Remove the 2 remaining entries. |
- controller.RemoveEntryAtIndex(1); |
- controller.RemoveEntryAtIndex(0); |
- |
- // This should leave us with only the last committed entry. |
- EXPECT_EQ(1, controller.GetEntryCount()); |
- EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
-} |
- |
-// Tests the transient entry, making sure it goes away with all navigations. |
-TEST_F(NavigationControllerTest, TransientEntry) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url0("http://foo/0"); |
- const GURL url1("http://foo/1"); |
- const GURL url2("http://foo/2"); |
- const GURL url3("http://foo/3"); |
- const GURL url3_ref("http://foo/3#bar"); |
- const GURL url4("http://foo/4"); |
- const GURL transient_url("http://foo/transient"); |
- |
- controller.LoadURL( |
- url0, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, url0); |
- controller.LoadURL( |
- url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(1, url1); |
- |
- notifications.Reset(); |
- |
- // Adding a transient with no pending entry. |
- NavigationEntryImpl* transient_entry = new NavigationEntryImpl; |
- transient_entry->SetURL(transient_url); |
- controller.SetTransientEntry(transient_entry); |
- |
- // We should not have received any notifications. |
- EXPECT_EQ(0U, notifications.size()); |
- |
- // Check our state. |
- EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_EQ(controller.GetEntryCount(), 3); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1); |
- EXPECT_EQ(controller.GetPendingEntryIndex(), -1); |
- EXPECT_TRUE(controller.GetLastCommittedEntry()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- EXPECT_EQ(contents()->GetMaxPageID(), 1); |
- |
- // Navigate. |
- controller.LoadURL( |
- url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(2, url2); |
- |
- // We should have navigated, transient entry should be gone. |
- EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_EQ(controller.GetEntryCount(), 3); |
- |
- // Add a transient again, then navigate with no pending entry this time. |
- transient_entry = new NavigationEntryImpl; |
- transient_entry->SetURL(transient_url); |
- controller.SetTransientEntry(transient_entry); |
- EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); |
- test_rvh()->SendNavigate(3, url3); |
- // Transient entry should be gone. |
- EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_EQ(controller.GetEntryCount(), 4); |
- |
- // Initiate a navigation, add a transient then commit navigation. |
- controller.LoadURL( |
- url4, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- transient_entry = new NavigationEntryImpl; |
- transient_entry->SetURL(transient_url); |
- controller.SetTransientEntry(transient_entry); |
- EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); |
- test_rvh()->SendNavigate(4, url4); |
- EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_EQ(controller.GetEntryCount(), 5); |
- |
- // Add a transient and go back. This should simply remove the transient. |
- transient_entry = new NavigationEntryImpl; |
- transient_entry->SetURL(transient_url); |
- controller.SetTransientEntry(transient_entry); |
- EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_TRUE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- controller.GoBack(); |
- // Transient entry should be gone. |
- EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_EQ(controller.GetEntryCount(), 5); |
- test_rvh()->SendNavigate(3, url3); |
- |
- // Add a transient and go to an entry before the current one. |
- transient_entry = new NavigationEntryImpl; |
- transient_entry->SetURL(transient_url); |
- controller.SetTransientEntry(transient_entry); |
- EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); |
- controller.GoToIndex(1); |
- // The navigation should have been initiated, transient entry should be gone. |
- EXPECT_FALSE(controller.GetTransientEntry()); |
- EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL()); |
- // Visible entry does not update for history navigations until commit. |
- EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL()); |
- test_rvh()->SendNavigate(1, url1); |
- EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); |
- |
- // Add a transient and go to an entry after the current one. |
- transient_entry = new NavigationEntryImpl; |
- transient_entry->SetURL(transient_url); |
- controller.SetTransientEntry(transient_entry); |
- EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); |
- controller.GoToIndex(3); |
- // The navigation should have been initiated, transient entry should be gone. |
- // Because of the transient entry that is removed, going to index 3 makes us |
- // land on url2 (which is visible after the commit). |
- EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL()); |
- EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); |
- test_rvh()->SendNavigate(2, url2); |
- EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); |
- |
- // Add a transient and go forward. |
- transient_entry = new NavigationEntryImpl; |
- transient_entry->SetURL(transient_url); |
- controller.SetTransientEntry(transient_entry); |
- EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_TRUE(controller.CanGoForward()); |
- controller.GoForward(); |
- // We should have navigated, transient entry should be gone. |
- EXPECT_FALSE(controller.GetTransientEntry()); |
- EXPECT_EQ(url3, controller.GetPendingEntry()->GetURL()); |
- EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); |
- test_rvh()->SendNavigate(3, url3); |
- EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL()); |
- |
- // Add a transient and do an in-page navigation, replacing the current entry. |
- transient_entry = new NavigationEntryImpl; |
- transient_entry->SetURL(transient_url); |
- controller.SetTransientEntry(transient_entry); |
- EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); |
- test_rvh()->SendNavigate(3, url3_ref); |
- // Transient entry should be gone. |
- EXPECT_FALSE(controller.GetTransientEntry()); |
- EXPECT_EQ(url3_ref, controller.GetVisibleEntry()->GetURL()); |
- |
- // Ensure the URLs are correct. |
- EXPECT_EQ(controller.GetEntryCount(), 5); |
- EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0); |
- EXPECT_EQ(controller.GetEntryAtIndex(1)->GetURL(), url1); |
- EXPECT_EQ(controller.GetEntryAtIndex(2)->GetURL(), url2); |
- EXPECT_EQ(controller.GetEntryAtIndex(3)->GetURL(), url3_ref); |
- EXPECT_EQ(controller.GetEntryAtIndex(4)->GetURL(), url4); |
-} |
- |
-// Test that Reload initiates a new navigation to a transient entry's URL. |
-TEST_F(NavigationControllerTest, ReloadTransient) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url0("http://foo/0"); |
- const GURL url1("http://foo/1"); |
- const GURL transient_url("http://foo/transient"); |
- |
- // Load |url0|, and start a pending navigation to |url1|. |
- controller.LoadURL( |
- url0, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- test_rvh()->SendNavigate(0, url0); |
- controller.LoadURL( |
- url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- |
- // A transient entry is added, interrupting the navigation. |
- NavigationEntryImpl* transient_entry = new NavigationEntryImpl; |
- transient_entry->SetURL(transient_url); |
- controller.SetTransientEntry(transient_entry); |
- EXPECT_TRUE(controller.GetTransientEntry()); |
- EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); |
- |
- // The page is reloaded, which should remove the pending entry for |url1| and |
- // the transient entry for |transient_url|, and start a navigation to |
- // |transient_url|. |
- controller.Reload(true); |
- EXPECT_FALSE(controller.GetTransientEntry()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); |
- ASSERT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0); |
- |
- // Load of |transient_url| completes. |
- test_rvh()->SendNavigate(1, transient_url); |
- ASSERT_EQ(controller.GetEntryCount(), 2); |
- EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0); |
- EXPECT_EQ(controller.GetEntryAtIndex(1)->GetURL(), transient_url); |
-} |
- |
-// Ensure that renderer initiated pending entries get replaced, so that we |
-// don't show a stale virtual URL when a navigation commits. |
-// See http://crbug.com/266922. |
-TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) { |
- NavigationControllerImpl& controller = controller_impl(); |
- |
- const GURL url1("nonexistent:12121"); |
- const GURL url1_fixed("http://nonexistent:12121/"); |
- const GURL url2("http://foo"); |
- |
- // We create pending entries for renderer-initiated navigations so that we |
- // can show them in new tabs when it is safe. |
- contents()->DidStartProvisionalLoadForFrame( |
- test_rvh(), 1, -1, true, url1); |
- |
- // Simulate what happens if a BrowserURLHandler rewrites the URL, causing |
- // the virtual URL to differ from the URL. |
- controller.GetPendingEntry()->SetURL(url1_fixed); |
- controller.GetPendingEntry()->SetVirtualURL(url1); |
- |
- EXPECT_EQ(url1_fixed, controller.GetPendingEntry()->GetURL()); |
- EXPECT_EQ(url1, controller.GetPendingEntry()->GetVirtualURL()); |
- EXPECT_TRUE( |
- NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> |
- is_renderer_initiated()); |
- |
- // If the user clicks another link, we should replace the pending entry. |
- contents()->DidStartProvisionalLoadForFrame( |
- test_rvh(), 1, -1, true, url2); |
- EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL()); |
- EXPECT_EQ(url2, controller.GetPendingEntry()->GetVirtualURL()); |
- |
- // Once it commits, the URL and virtual URL should reflect the actual page. |
- test_rvh()->SendNavigate(0, url2); |
- EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL()); |
- EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetVirtualURL()); |
- |
- // We should not replace the pending entry for an error URL. |
- contents()->DidStartProvisionalLoadForFrame( |
- test_rvh(), 1, -1, true, url1); |
- EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL()); |
- contents()->DidStartProvisionalLoadForFrame( |
- test_rvh(), 1, -1, true, GURL(kUnreachableWebDataURL)); |
- EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL()); |
- |
- // We should remember if the pending entry will replace the current one. |
- // http://crbug.com/308444. |
- contents()->DidStartProvisionalLoadForFrame( |
- test_rvh(), 1, -1, true, url1); |
- NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> |
- set_should_replace_entry(true); |
- contents()->DidStartProvisionalLoadForFrame( |
- test_rvh(), 1, -1, true, url2); |
- EXPECT_TRUE( |
- NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> |
- should_replace_entry()); |
- test_rvh()->SendNavigate(0, url2); |
- EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL()); |
-} |
- |
-// Tests that the URLs for renderer-initiated navigations are not displayed to |
-// the user until the navigation commits, to prevent URL spoof attacks. |
-// See http://crbug.com/99016. |
-TEST_F(NavigationControllerTest, DontShowRendererURLUntilCommit) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url0("http://foo/0"); |
- const GURL url1("http://foo/1"); |
- |
- // For typed navigations (browser-initiated), both pending and visible entries |
- // should update before commit. |
- controller.LoadURL(url0, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_EQ(url0, controller.GetPendingEntry()->GetURL()); |
- EXPECT_EQ(url0, controller.GetVisibleEntry()->GetURL()); |
- test_rvh()->SendNavigate(0, url0); |
- |
- // For link clicks (renderer-initiated navigations), the pending entry should |
- // update before commit but the visible should not. |
- NavigationController::LoadURLParams load_url_params(url1); |
- load_url_params.is_renderer_initiated = true; |
- controller.LoadURLWithParams(load_url_params); |
- EXPECT_EQ(url0, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL()); |
- EXPECT_TRUE( |
- NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> |
- is_renderer_initiated()); |
- |
- // After commit, both visible should be updated, there should be no pending |
- // entry, and we should no longer treat the entry as renderer-initiated. |
- test_rvh()->SendNavigate(1, url1); |
- EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_FALSE( |
- NavigationEntryImpl::FromNavigationEntry( |
- controller.GetLastCommittedEntry())->is_renderer_initiated()); |
- |
- notifications.Reset(); |
-} |
- |
-// Tests that the URLs for renderer-initiated navigations in new tabs are |
-// displayed to the user before commit, as long as the initial about:blank |
-// page has not been modified. If so, we must revert to showing about:blank. |
-// See http://crbug.com/9682. |
-TEST_F(NavigationControllerTest, ShowRendererURLInNewTabUntilModified) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url("http://foo"); |
- |
- // For renderer-initiated navigations in new tabs (with no committed entries), |
- // we show the pending entry's URL as long as the about:blank page is not |
- // modified. |
- NavigationController::LoadURLParams load_url_params(url); |
- load_url_params.transition_type = PAGE_TRANSITION_LINK; |
- load_url_params.is_renderer_initiated = true; |
- controller.LoadURLWithParams(load_url_params); |
- EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_EQ(url, controller.GetPendingEntry()->GetURL()); |
- EXPECT_TRUE( |
- NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> |
- is_renderer_initiated()); |
- EXPECT_TRUE(controller.IsInitialNavigation()); |
- EXPECT_FALSE(test_rvh()->has_accessed_initial_document()); |
- |
- // There should be no title yet. |
- EXPECT_TRUE(contents()->GetTitle().empty()); |
- |
- // If something else modifies the contents of the about:blank page, then |
- // we must revert to showing about:blank to avoid a URL spoof. |
- test_rvh()->OnMessageReceived( |
- ViewHostMsg_DidAccessInitialDocument(0)); |
- EXPECT_TRUE(test_rvh()->has_accessed_initial_document()); |
- EXPECT_FALSE(controller.GetVisibleEntry()); |
- EXPECT_EQ(url, controller.GetPendingEntry()->GetURL()); |
- |
- notifications.Reset(); |
-} |
- |
-TEST_F(NavigationControllerTest, DontShowRendererURLInNewTabAfterCommit) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- const GURL url1("http://foo/eh"); |
- const GURL url2("http://foo/bee"); |
- |
- // For renderer-initiated navigations in new tabs (with no committed entries), |
- // we show the pending entry's URL as long as the about:blank page is not |
- // modified. |
- NavigationController::LoadURLParams load_url_params(url1); |
- load_url_params.transition_type = PAGE_TRANSITION_LINK; |
- load_url_params.is_renderer_initiated = true; |
- controller.LoadURLWithParams(load_url_params); |
- EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); |
- EXPECT_TRUE( |
- NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> |
- is_renderer_initiated()); |
- EXPECT_TRUE(controller.IsInitialNavigation()); |
- EXPECT_FALSE(test_rvh()->has_accessed_initial_document()); |
- |
- // Simulate a commit and then starting a new pending navigation. |
- test_rvh()->SendNavigate(0, url1); |
- NavigationController::LoadURLParams load_url2_params(url2); |
- load_url2_params.transition_type = PAGE_TRANSITION_LINK; |
- load_url2_params.is_renderer_initiated = true; |
- controller.LoadURLWithParams(load_url2_params); |
- |
- // We should not consider this an initial navigation, and thus should |
- // not show the pending URL. |
- EXPECT_FALSE(test_rvh()->has_accessed_initial_document()); |
- EXPECT_FALSE(controller.IsInitialNavigation()); |
- EXPECT_TRUE(controller.GetVisibleEntry()); |
- EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); |
- |
- notifications.Reset(); |
-} |
- |
-// Tests that IsInPageNavigation returns appropriate results. Prevents |
-// regression for bug 1126349. |
-TEST_F(NavigationControllerTest, IsInPageNavigation) { |
- NavigationControllerImpl& controller = controller_impl(); |
- // Navigate to URL with no refs. |
- const GURL url("http://www.google.com/home.html"); |
- test_rvh()->SendNavigate(0, url); |
- |
- // Reloading the page is not an in-page navigation. |
- EXPECT_FALSE(controller.IsURLInPageNavigation(url)); |
- const GURL other_url("http://www.google.com/add.html"); |
- EXPECT_FALSE(controller.IsURLInPageNavigation(other_url)); |
- const GURL url_with_ref("http://www.google.com/home.html#my_ref"); |
- EXPECT_TRUE(controller.IsURLInPageNavigation(url_with_ref)); |
- |
- // Navigate to URL with refs. |
- test_rvh()->SendNavigate(1, url_with_ref); |
- |
- // Reloading the page is not an in-page navigation. |
- EXPECT_FALSE(controller.IsURLInPageNavigation(url_with_ref)); |
- EXPECT_FALSE(controller.IsURLInPageNavigation(url)); |
- EXPECT_FALSE(controller.IsURLInPageNavigation(other_url)); |
- const GURL other_url_with_ref("http://www.google.com/home.html#my_other_ref"); |
- EXPECT_TRUE(controller.IsURLInPageNavigation(other_url_with_ref)); |
- |
- // Going to the same url again will be considered in-page |
- // if the renderer says it is even if the navigation type isn't IN_PAGE. |
- EXPECT_TRUE(controller.IsURLInPageNavigation(url_with_ref, true, |
- NAVIGATION_TYPE_UNKNOWN)); |
- |
- // Going back to the non ref url will be considered in-page if the navigation |
- // type is IN_PAGE. |
- EXPECT_TRUE(controller.IsURLInPageNavigation(url, true, |
- NAVIGATION_TYPE_IN_PAGE)); |
-} |
- |
-// Some pages can have subframes with the same base URL (minus the reference) as |
-// the main page. Even though this is hard, it can happen, and we don't want |
-// these subframe navigations to affect the toplevel document. They should |
-// instead be ignored. http://crbug.com/5585 |
-TEST_F(NavigationControllerTest, SameSubframe) { |
- NavigationControllerImpl& controller = controller_impl(); |
- // Navigate the main frame. |
- const GURL url("http://www.google.com/"); |
- test_rvh()->SendNavigate(0, url); |
- |
- // We should be at the first navigation entry. |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
- |
- // Navigate a subframe that would normally count as in-page. |
- const GURL subframe("http://www.google.com/#"); |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = 0; |
- params.url = subframe; |
- params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; |
- params.should_update_history = false; |
- params.gesture = NavigationGestureAuto; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(subframe); |
- LoadCommittedDetails details; |
- EXPECT_FALSE(controller.RendererDidNavigate(params, &details)); |
- |
- // Nothing should have changed. |
- EXPECT_EQ(controller.GetEntryCount(), 1); |
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); |
-} |
- |
-// Make sure that on cloning a WebContentsImpl and going back needs_reload is |
-// false. |
-TEST_F(NavigationControllerTest, CloneAndGoBack) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- const string16 title(ASCIIToUTF16("Title")); |
- |
- NavigateAndCommit(url1); |
- controller.GetVisibleEntry()->SetTitle(title); |
- NavigateAndCommit(url2); |
- |
- scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone()); |
- |
- ASSERT_EQ(2, clone->GetController().GetEntryCount()); |
- EXPECT_TRUE(clone->GetController().NeedsReload()); |
- clone->GetController().GoBack(); |
- // Navigating back should have triggered needs_reload_ to go false. |
- EXPECT_FALSE(clone->GetController().NeedsReload()); |
- |
- // Ensure that the pending URL and its title are visible. |
- EXPECT_EQ(url1, clone->GetController().GetVisibleEntry()->GetURL()); |
- EXPECT_EQ(title, clone->GetTitle()); |
-} |
- |
-// Make sure that reloading a cloned tab doesn't change its pending entry index. |
-// See http://crbug.com/234491. |
-TEST_F(NavigationControllerTest, CloneAndReload) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- const string16 title(ASCIIToUTF16("Title")); |
- |
- NavigateAndCommit(url1); |
- controller.GetVisibleEntry()->SetTitle(title); |
- NavigateAndCommit(url2); |
- |
- scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone()); |
- clone->GetController().LoadIfNecessary(); |
- |
- ASSERT_EQ(2, clone->GetController().GetEntryCount()); |
- EXPECT_EQ(1, clone->GetController().GetPendingEntryIndex()); |
- |
- clone->GetController().Reload(true); |
- EXPECT_EQ(1, clone->GetController().GetPendingEntryIndex()); |
-} |
- |
-// Make sure that cloning a WebContentsImpl doesn't copy interstitials. |
-TEST_F(NavigationControllerTest, CloneOmitsInterstitials) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- |
- // Add an interstitial entry. Should be deleted with controller. |
- NavigationEntryImpl* interstitial_entry = new NavigationEntryImpl(); |
- interstitial_entry->set_page_type(PAGE_TYPE_INTERSTITIAL); |
- controller.SetTransientEntry(interstitial_entry); |
- |
- scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone()); |
- |
- ASSERT_EQ(2, clone->GetController().GetEntryCount()); |
-} |
- |
-// Test requesting and triggering a lazy reload. |
-TEST_F(NavigationControllerTest, LazyReload) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url("http://foo"); |
- NavigateAndCommit(url); |
- ASSERT_FALSE(controller.NeedsReload()); |
- |
- // Request a reload to happen when the controller becomes active (e.g. after |
- // the renderer gets killed in background on Android). |
- controller.SetNeedsReload(); |
- ASSERT_TRUE(controller.NeedsReload()); |
- |
- // Set the controller as active, triggering the requested reload. |
- controller.SetActive(true); |
- ASSERT_FALSE(controller.NeedsReload()); |
-} |
- |
-// Tests a subframe navigation while a toplevel navigation is pending. |
-// http://crbug.com/43967 |
-TEST_F(NavigationControllerTest, SubframeWhilePending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- // Load the first page. |
- const GURL url1("http://foo/"); |
- NavigateAndCommit(url1); |
- |
- // Now start a pending load to a totally different page, but don't commit it. |
- const GURL url2("http://bar/"); |
- controller.LoadURL( |
- url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- |
- // Send a subframe update from the first page, as if one had just |
- // automatically loaded. Auto subframes don't increment the page ID. |
- const GURL url1_sub("http://foo/subframe"); |
- ViewHostMsg_FrameNavigate_Params params; |
- params.page_id = controller.GetLastCommittedEntry()->GetPageID(); |
- params.url = url1_sub; |
- params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; |
- params.should_update_history = false; |
- params.gesture = NavigationGestureAuto; |
- params.is_post = false; |
- params.page_state = PageState::CreateFromURL(url1_sub); |
- LoadCommittedDetails details; |
- |
- // This should return false meaning that nothing was actually updated. |
- EXPECT_FALSE(controller.RendererDidNavigate(params, &details)); |
- |
- // The notification should have updated the last committed one, and not |
- // the pending load. |
- EXPECT_EQ(url1, controller.GetLastCommittedEntry()->GetURL()); |
- |
- // The active entry should be unchanged by the subframe load. |
- EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); |
-} |
- |
-// Test CopyStateFrom with 2 urls, the first selected and nothing in the target. |
-TEST_F(NavigationControllerTest, CopyStateFrom) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- controller.GoBack(); |
- contents()->CommitPendingNavigation(); |
- |
- scoped_ptr<TestWebContents> other_contents( |
- static_cast<TestWebContents*>(CreateTestWebContents())); |
- NavigationControllerImpl& other_controller = other_contents->GetController(); |
- other_controller.CopyStateFrom(controller); |
- |
- // other_controller should now contain 2 urls. |
- ASSERT_EQ(2, other_controller.GetEntryCount()); |
- // We should be looking at the first one. |
- ASSERT_EQ(0, other_controller.GetCurrentEntryIndex()); |
- |
- EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL()); |
- EXPECT_EQ(0, other_controller.GetEntryAtIndex(0)->GetPageID()); |
- EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL()); |
- // This is a different site than url1, so the IDs start again at 0. |
- EXPECT_EQ(0, other_controller.GetEntryAtIndex(1)->GetPageID()); |
- |
- // The max page ID map should be copied over and updated with the max page ID |
- // from the current tab. |
- SiteInstance* instance1 = |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)); |
- EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1)); |
- |
- // Ensure the SessionStorageNamespaceMaps are the same size and have |
- // the same partitons loaded. |
- // |
- // TODO(ajwong): We should load a url from a different partition earlier |
- // to make sure this map has more than one entry. |
- const SessionStorageNamespaceMap& session_storage_namespace_map = |
- controller.GetSessionStorageNamespaceMap(); |
- const SessionStorageNamespaceMap& other_session_storage_namespace_map = |
- other_controller.GetSessionStorageNamespaceMap(); |
- EXPECT_EQ(session_storage_namespace_map.size(), |
- other_session_storage_namespace_map.size()); |
- for (SessionStorageNamespaceMap::const_iterator it = |
- session_storage_namespace_map.begin(); |
- it != session_storage_namespace_map.end(); |
- ++it) { |
- SessionStorageNamespaceMap::const_iterator other = |
- other_session_storage_namespace_map.find(it->first); |
- EXPECT_TRUE(other != other_session_storage_namespace_map.end()); |
- } |
-} |
- |
-// Tests CopyStateFromAndPrune with 2 urls in source, 1 in dest. |
-TEST_F(NavigationControllerTest, CopyStateFromAndPrune) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo/1"); |
- const GURL url2("http://foo/2"); |
- const GURL url3("http://foo/3"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- |
- // First two entries should have the same SiteInstance. |
- SiteInstance* instance1 = |
- GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0)); |
- SiteInstance* instance2 = |
- GetSiteInstanceFromEntry(controller.GetEntryAtIndex(1)); |
- EXPECT_EQ(instance1, instance2); |
- EXPECT_EQ(0, controller.GetEntryAtIndex(0)->GetPageID()); |
- EXPECT_EQ(1, controller.GetEntryAtIndex(1)->GetPageID()); |
- EXPECT_EQ(1, contents()->GetMaxPageIDForSiteInstance(instance1)); |
- |
- scoped_ptr<TestWebContents> other_contents( |
- static_cast<TestWebContents*>(CreateTestWebContents())); |
- NavigationControllerImpl& other_controller = other_contents->GetController(); |
- other_contents->NavigateAndCommit(url3); |
- other_contents->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2, |
- other_controller.GetEntryAtIndex(0)->GetPageID()); |
- other_controller.CopyStateFromAndPrune(&controller); |
- |
- // other_controller should now contain the 3 urls: url1, url2 and url3. |
- |
- ASSERT_EQ(3, other_controller.GetEntryCount()); |
- |
- ASSERT_EQ(2, other_controller.GetCurrentEntryIndex()); |
- |
- EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL()); |
- EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL()); |
- EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->GetURL()); |
- EXPECT_EQ(0, other_controller.GetEntryAtIndex(0)->GetPageID()); |
- EXPECT_EQ(1, other_controller.GetEntryAtIndex(1)->GetPageID()); |
- EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID()); |
- |
- // A new SiteInstance should be used for the new tab. |
- SiteInstance* instance3 = |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2)); |
- EXPECT_NE(instance3, instance1); |
- |
- // The max page ID map should be copied over and updated with the max page ID |
- // from the current tab. |
- EXPECT_EQ(1, other_contents->GetMaxPageIDForSiteInstance(instance1)); |
- EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance3)); |
-} |
- |
-// Test CopyStateFromAndPrune with 2 urls, the first selected and 1 entry in |
-// the target. |
-TEST_F(NavigationControllerTest, CopyStateFromAndPrune2) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- const GURL url3("http://foo3"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- controller.GoBack(); |
- contents()->CommitPendingNavigation(); |
- |
- scoped_ptr<TestWebContents> other_contents( |
- static_cast<TestWebContents*>(CreateTestWebContents())); |
- NavigationControllerImpl& other_controller = other_contents->GetController(); |
- other_contents->NavigateAndCommit(url3); |
- other_contents->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1, |
- other_controller.GetEntryAtIndex(0)->GetPageID()); |
- other_controller.CopyStateFromAndPrune(&controller); |
- |
- // other_controller should now contain: url1, url3 |
- |
- ASSERT_EQ(2, other_controller.GetEntryCount()); |
- ASSERT_EQ(1, other_controller.GetCurrentEntryIndex()); |
- |
- EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL()); |
- EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL()); |
- EXPECT_EQ(0, other_controller.GetEntryAtIndex(1)->GetPageID()); |
- |
- // The max page ID map should be copied over and updated with the max page ID |
- // from the current tab. |
- SiteInstance* instance1 = |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1)); |
- EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1)); |
-} |
- |
-// Test CopyStateFromAndPrune with 2 urls, the last selected and 2 entries in |
-// the target. |
-TEST_F(NavigationControllerTest, CopyStateFromAndPrune3) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- const GURL url3("http://foo3"); |
- const GURL url4("http://foo4"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- |
- scoped_ptr<TestWebContents> other_contents( |
- static_cast<TestWebContents*>(CreateTestWebContents())); |
- NavigationControllerImpl& other_controller = other_contents->GetController(); |
- other_contents->NavigateAndCommit(url3); |
- other_contents->NavigateAndCommit(url4); |
- other_contents->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1)), 2, |
- other_controller.GetEntryAtIndex(0)->GetPageID()); |
- other_controller.CopyStateFromAndPrune(&controller); |
- |
- // other_controller should now contain: url1, url2, url4 |
- |
- ASSERT_EQ(3, other_controller.GetEntryCount()); |
- ASSERT_EQ(2, other_controller.GetCurrentEntryIndex()); |
- |
- EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL()); |
- EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL()); |
- EXPECT_EQ(url4, other_controller.GetEntryAtIndex(2)->GetURL()); |
- |
- // The max page ID map should be copied over and updated with the max page ID |
- // from the current tab. |
- SiteInstance* instance1 = |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2)); |
- EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1)); |
-} |
- |
-// Test CopyStateFromAndPrune with 2 urls, 2 entries in the target, with |
-// not the last entry selected in the target. |
-TEST_F(NavigationControllerTest, CopyStateFromAndPruneNotLast) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- const GURL url3("http://foo3"); |
- const GURL url4("http://foo4"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- |
- scoped_ptr<TestWebContents> other_contents( |
- static_cast<TestWebContents*>(CreateTestWebContents())); |
- NavigationControllerImpl& other_controller = other_contents->GetController(); |
- other_contents->NavigateAndCommit(url3); |
- other_contents->NavigateAndCommit(url4); |
- other_controller.GoBack(); |
- other_contents->CommitPendingNavigation(); |
- other_contents->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2, |
- other_controller.GetEntryAtIndex(0)->GetPageID()); |
- other_controller.CopyStateFromAndPrune(&controller); |
- |
- // other_controller should now contain: url1, url2, url3 |
- |
- ASSERT_EQ(3, other_controller.GetEntryCount()); |
- ASSERT_EQ(2, other_controller.GetCurrentEntryIndex()); |
- |
- EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL()); |
- EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL()); |
- EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->GetURL()); |
- |
- // The max page ID map should be copied over and updated with the max page ID |
- // from the current tab. |
- SiteInstance* instance1 = |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2)); |
- EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1)); |
-} |
- |
-// Test CopyStateFromAndPrune with 2 urls, the first selected and 1 entry plus |
-// a pending entry in the target. |
-TEST_F(NavigationControllerTest, CopyStateFromAndPruneTargetPending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- const GURL url3("http://foo3"); |
- const GURL url4("http://foo4"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- controller.GoBack(); |
- contents()->CommitPendingNavigation(); |
- |
- scoped_ptr<TestWebContents> other_contents( |
- static_cast<TestWebContents*>(CreateTestWebContents())); |
- NavigationControllerImpl& other_controller = other_contents->GetController(); |
- other_contents->NavigateAndCommit(url3); |
- other_controller.LoadURL( |
- url4, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- other_contents->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1, |
- other_controller.GetEntryAtIndex(0)->GetPageID()); |
- other_controller.CopyStateFromAndPrune(&controller); |
- |
- // other_controller should now contain url1, url3, and a pending entry |
- // for url4. |
- |
- ASSERT_EQ(2, other_controller.GetEntryCount()); |
- EXPECT_EQ(1, other_controller.GetCurrentEntryIndex()); |
- |
- EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL()); |
- EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL()); |
- |
- // And there should be a pending entry for url4. |
- ASSERT_TRUE(other_controller.GetPendingEntry()); |
- EXPECT_EQ(url4, other_controller.GetPendingEntry()->GetURL()); |
- |
- // The max page ID map should be copied over and updated with the max page ID |
- // from the current tab. |
- SiteInstance* instance1 = |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)); |
- EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1)); |
-} |
- |
-// Test CopyStateFromAndPrune with 1 url in the source, 1 entry and a pending |
-// client redirect entry (with the same page ID) in the target. This used to |
-// crash because the last committed entry would be pruned but max_page_id |
-// remembered the page ID (http://crbug.com/234809). |
-TEST_F(NavigationControllerTest, CopyStateFromAndPruneTargetPending2) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- const GURL url2a("http://foo2/a"); |
- const GURL url2b("http://foo2/b"); |
- |
- NavigateAndCommit(url1); |
- |
- scoped_ptr<TestWebContents> other_contents( |
- static_cast<TestWebContents*>(CreateTestWebContents())); |
- NavigationControllerImpl& other_controller = other_contents->GetController(); |
- other_contents->NavigateAndCommit(url2a); |
- // Simulate a client redirect, which has the same page ID as entry 2a. |
- other_controller.LoadURL( |
- url2b, Referrer(), PAGE_TRANSITION_LINK, std::string()); |
- other_controller.GetPendingEntry()->SetPageID( |
- other_controller.GetLastCommittedEntry()->GetPageID()); |
- |
- other_contents->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1, |
- other_controller.GetEntryAtIndex(0)->GetPageID()); |
- other_controller.CopyStateFromAndPrune(&controller); |
- |
- // other_controller should now contain url1, url2a, and a pending entry |
- // for url2b. |
- |
- ASSERT_EQ(2, other_controller.GetEntryCount()); |
- EXPECT_EQ(1, other_controller.GetCurrentEntryIndex()); |
- |
- EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL()); |
- EXPECT_EQ(url2a, other_controller.GetEntryAtIndex(1)->GetURL()); |
- |
- // And there should be a pending entry for url4. |
- ASSERT_TRUE(other_controller.GetPendingEntry()); |
- EXPECT_EQ(url2b, other_controller.GetPendingEntry()->GetURL()); |
- |
- // Let the pending entry commit. |
- other_contents->CommitPendingNavigation(); |
- |
- // The max page ID map should be copied over and updated with the max page ID |
- // from the current tab. |
- SiteInstance* instance1 = |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1)); |
- EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1)); |
-} |
- |
-// Test CopyStateFromAndPrune with 2 urls, a back navigation pending in the |
-// source, and 1 entry in the target. The back pending entry should be ignored. |
-TEST_F(NavigationControllerTest, CopyStateFromAndPruneSourcePending) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- const GURL url3("http://foo3"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- controller.GoBack(); |
- |
- scoped_ptr<TestWebContents> other_contents( |
- static_cast<TestWebContents*>(CreateTestWebContents())); |
- NavigationControllerImpl& other_controller = other_contents->GetController(); |
- other_contents->NavigateAndCommit(url3); |
- other_contents->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2, |
- other_controller.GetEntryAtIndex(0)->GetPageID()); |
- other_controller.CopyStateFromAndPrune(&controller); |
- |
- // other_controller should now contain: url1, url2, url3 |
- |
- ASSERT_EQ(3, other_controller.GetEntryCount()); |
- ASSERT_EQ(2, other_controller.GetCurrentEntryIndex()); |
- |
- EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL()); |
- EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL()); |
- EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->GetURL()); |
- EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID()); |
- |
- // The max page ID map should be copied over and updated with the max page ID |
- // from the current tab. |
- SiteInstance* instance1 = |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2)); |
- EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1)); |
-} |
- |
-// Tests CopyStateFromAndPrune with 3 urls in source, 1 in dest, |
-// when the max entry count is 3. We should prune one entry. |
-TEST_F(NavigationControllerTest, CopyStateFromAndPruneMaxEntries) { |
- NavigationControllerImpl& controller = controller_impl(); |
- size_t original_count = NavigationControllerImpl::max_entry_count(); |
- const int kMaxEntryCount = 3; |
- |
- NavigationControllerImpl::set_max_entry_count_for_testing(kMaxEntryCount); |
- |
- const GURL url1("http://foo/1"); |
- const GURL url2("http://foo/2"); |
- const GURL url3("http://foo/3"); |
- const GURL url4("http://foo/4"); |
- |
- // Create a PrunedListener to observe prune notifications. |
- PrunedListener listener(&controller); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- NavigateAndCommit(url3); |
- |
- scoped_ptr<TestWebContents> other_contents( |
- static_cast<TestWebContents*>(CreateTestWebContents())); |
- NavigationControllerImpl& other_controller = other_contents->GetController(); |
- other_contents->NavigateAndCommit(url4); |
- other_contents->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2, |
- other_controller.GetEntryAtIndex(0)->GetPageID()); |
- other_controller.CopyStateFromAndPrune(&controller); |
- |
- // We should have received a pruned notification. |
- EXPECT_EQ(1, listener.notification_count_); |
- EXPECT_TRUE(listener.details_.from_front); |
- EXPECT_EQ(1, listener.details_.count); |
- |
- // other_controller should now contain only 3 urls: url2, url3 and url4. |
- |
- ASSERT_EQ(3, other_controller.GetEntryCount()); |
- |
- ASSERT_EQ(2, other_controller.GetCurrentEntryIndex()); |
- |
- EXPECT_EQ(url2, other_controller.GetEntryAtIndex(0)->GetURL()); |
- EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL()); |
- EXPECT_EQ(url4, other_controller.GetEntryAtIndex(2)->GetURL()); |
- EXPECT_EQ(1, other_controller.GetEntryAtIndex(0)->GetPageID()); |
- EXPECT_EQ(2, other_controller.GetEntryAtIndex(1)->GetPageID()); |
- EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID()); |
- |
- NavigationControllerImpl::set_max_entry_count_for_testing(original_count); |
-} |
- |
-// Tests that navigations initiated from the page (with the history object) |
-// work as expected without navigation entries. |
-TEST_F(NavigationControllerTest, HistoryNavigate) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo/1"); |
- const GURL url2("http://foo/2"); |
- const GURL url3("http://foo/3"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- NavigateAndCommit(url3); |
- controller.GoBack(); |
- contents()->CommitPendingNavigation(); |
- |
- // Simulate the page calling history.back(), it should not create a pending |
- // entry. |
- contents()->OnGoToEntryAtOffset(-1); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- // The actual cross-navigation is suspended until the current RVH tells us |
- // it unloaded, simulate that. |
- contents()->ProceedWithCrossSiteNavigation(); |
- // Also make sure we told the page to navigate. |
- const IPC::Message* message = |
- process()->sink().GetFirstMessageMatching(ViewMsg_Navigate::ID); |
- ASSERT_TRUE(message != NULL); |
- Tuple1<ViewMsg_Navigate_Params> nav_params; |
- ViewMsg_Navigate::Read(message, &nav_params); |
- EXPECT_EQ(url1, nav_params.a.url); |
- process()->sink().ClearMessages(); |
- |
- // Now test history.forward() |
- contents()->OnGoToEntryAtOffset(1); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- // The actual cross-navigation is suspended until the current RVH tells us |
- // it unloaded, simulate that. |
- contents()->ProceedWithCrossSiteNavigation(); |
- message = process()->sink().GetFirstMessageMatching(ViewMsg_Navigate::ID); |
- ASSERT_TRUE(message != NULL); |
- ViewMsg_Navigate::Read(message, &nav_params); |
- EXPECT_EQ(url3, nav_params.a.url); |
- process()->sink().ClearMessages(); |
- |
- // Make sure an extravagant history.go() doesn't break. |
- contents()->OnGoToEntryAtOffset(120); // Out of bounds. |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- message = process()->sink().GetFirstMessageMatching(ViewMsg_Navigate::ID); |
- EXPECT_TRUE(message == NULL); |
-} |
- |
-// Test call to PruneAllButVisible for the only entry. |
-TEST_F(NavigationControllerTest, PruneAllButVisibleForSingle) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo1"); |
- NavigateAndCommit(url1); |
- |
- contents()->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0)), 0, |
- controller.GetEntryAtIndex(0)->GetPageID()); |
- |
- controller.PruneAllButVisible(); |
- |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url1); |
-} |
- |
-// Test call to PruneAllButVisible for first entry. |
-TEST_F(NavigationControllerTest, PruneAllButVisibleForFirst) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo/1"); |
- const GURL url2("http://foo/2"); |
- const GURL url3("http://foo/3"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- NavigateAndCommit(url3); |
- controller.GoBack(); |
- controller.GoBack(); |
- contents()->CommitPendingNavigation(); |
- |
- contents()->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0)), 0, |
- controller.GetEntryAtIndex(0)->GetPageID()); |
- |
- controller.PruneAllButVisible(); |
- |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url1); |
-} |
- |
-// Test call to PruneAllButVisible for intermediate entry. |
-TEST_F(NavigationControllerTest, PruneAllButVisibleForIntermediate) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo/1"); |
- const GURL url2("http://foo/2"); |
- const GURL url3("http://foo/3"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- NavigateAndCommit(url3); |
- controller.GoBack(); |
- contents()->CommitPendingNavigation(); |
- |
- contents()->ExpectSetHistoryLengthAndPrune( |
- GetSiteInstanceFromEntry(controller.GetEntryAtIndex(1)), 0, |
- controller.GetEntryAtIndex(1)->GetPageID()); |
- |
- controller.PruneAllButVisible(); |
- |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url2); |
-} |
- |
-// Test call to PruneAllButVisible for a pending entry that is not yet in the |
-// list of entries. |
-TEST_F(NavigationControllerTest, PruneAllButVisibleForPendingNotInList) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url1("http://foo/1"); |
- const GURL url2("http://foo/2"); |
- const GURL url3("http://foo/3"); |
- |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- |
- // Create a pending entry that is not in the entry list. |
- controller.LoadURL( |
- url3, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(2, controller.GetEntryCount()); |
- |
- contents()->ExpectSetHistoryLengthAndPrune( |
- NULL, 0, controller.GetPendingEntry()->GetPageID()); |
- controller.PruneAllButVisible(); |
- |
- // We should only have the last committed and pending entries at this point, |
- // and the pending entry should still not be in the entry list. |
- EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_TRUE(controller.GetPendingEntry()); |
- EXPECT_EQ(1, controller.GetEntryCount()); |
- |
- // Try to commit the pending entry. |
- test_rvh()->SendNavigate(2, url3); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_FALSE(controller.GetPendingEntry()); |
- EXPECT_EQ(2, controller.GetEntryCount()); |
- EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); |
-} |
- |
-// Test to ensure that when we do a history navigation back to the current |
-// committed page (e.g., going forward to a slow-loading page, then pressing |
-// the back button), we just stop the navigation to prevent the throbber from |
-// running continuously. Otherwise, the RenderViewHost forces the throbber to |
-// start, but WebKit essentially ignores the navigation and never sends a |
-// message to stop the throbber. |
-TEST_F(NavigationControllerTest, StopOnHistoryNavigationToCurrentPage) { |
- NavigationControllerImpl& controller = controller_impl(); |
- const GURL url0("http://foo/0"); |
- const GURL url1("http://foo/1"); |
- |
- NavigateAndCommit(url0); |
- NavigateAndCommit(url1); |
- |
- // Go back to the original page, then forward to the slow page, then back |
- controller.GoBack(); |
- contents()->CommitPendingNavigation(); |
- |
- controller.GoForward(); |
- EXPECT_EQ(1, controller.GetPendingEntryIndex()); |
- |
- controller.GoBack(); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
-} |
- |
-TEST_F(NavigationControllerTest, IsInitialNavigation) { |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- // Initial state. |
- EXPECT_TRUE(controller.IsInitialNavigation()); |
- |
- // After commit, it stays false. |
- const GURL url1("http://foo1"); |
- test_rvh()->SendNavigate(0, url1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- EXPECT_FALSE(controller.IsInitialNavigation()); |
- |
- // After starting a new navigation, it stays false. |
- const GURL url2("http://foo2"); |
- controller.LoadURL( |
- url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); |
-} |
- |
-// Check that the favicon is not reused across a client redirect. |
-// (crbug.com/28515) |
-TEST_F(NavigationControllerTest, ClearFaviconOnRedirect) { |
- const GURL kPageWithFavicon("http://withfavicon.html"); |
- const GURL kPageWithoutFavicon("http://withoutfavicon.html"); |
- const GURL kIconURL("http://withfavicon.ico"); |
- const gfx::Image kDefaultFavicon = FaviconStatus().image; |
- |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- test_rvh()->SendNavigate(0, kPageWithFavicon); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- NavigationEntry* entry = controller.GetLastCommittedEntry(); |
- EXPECT_TRUE(entry); |
- EXPECT_EQ(kPageWithFavicon, entry->GetURL()); |
- |
- // Simulate Chromium having set the favicon for |kPageWithFavicon|. |
- content::FaviconStatus& favicon_status = entry->GetFavicon(); |
- favicon_status.image = CreateImage(SK_ColorWHITE); |
- favicon_status.url = kIconURL; |
- favicon_status.valid = true; |
- EXPECT_FALSE(DoImagesMatch(kDefaultFavicon, entry->GetFavicon().image)); |
- |
- test_rvh()->SendNavigateWithTransition( |
- 0, // same page ID. |
- kPageWithoutFavicon, |
- PAGE_TRANSITION_CLIENT_REDIRECT); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- entry = controller.GetLastCommittedEntry(); |
- EXPECT_TRUE(entry); |
- EXPECT_EQ(kPageWithoutFavicon, entry->GetURL()); |
- |
- EXPECT_TRUE(DoImagesMatch(kDefaultFavicon, entry->GetFavicon().image)); |
-} |
- |
-// Check that the favicon is not cleared for NavigationEntries which were |
-// previously navigated to. |
-TEST_F(NavigationControllerTest, BackNavigationDoesNotClearFavicon) { |
- const GURL kUrl1("http://www.a.com/1"); |
- const GURL kUrl2("http://www.a.com/2"); |
- const GURL kIconURL("http://www.a.com/1/favicon.ico"); |
- |
- NavigationControllerImpl& controller = controller_impl(); |
- TestNotificationTracker notifications; |
- RegisterForAllNavNotifications(¬ifications, &controller); |
- |
- test_rvh()->SendNavigate(0, kUrl1); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Simulate Chromium having set the favicon for |kUrl1|. |
- gfx::Image favicon_image = CreateImage(SK_ColorWHITE); |
- content::NavigationEntry* entry = controller.GetLastCommittedEntry(); |
- EXPECT_TRUE(entry); |
- content::FaviconStatus& favicon_status = entry->GetFavicon(); |
- favicon_status.image = favicon_image; |
- favicon_status.url = kIconURL; |
- favicon_status.valid = true; |
- |
- // Navigate to another page and go back to the original page. |
- test_rvh()->SendNavigate(1, kUrl2); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- test_rvh()->SendNavigateWithTransition( |
- 0, |
- kUrl1, |
- PAGE_TRANSITION_FORWARD_BACK); |
- EXPECT_EQ(1U, navigation_entry_committed_counter_); |
- navigation_entry_committed_counter_ = 0; |
- |
- // Verify that the favicon for the page at |kUrl1| was not cleared. |
- entry = controller.GetEntryAtIndex(0); |
- EXPECT_TRUE(entry); |
- EXPECT_EQ(kUrl1, entry->GetURL()); |
- EXPECT_TRUE(DoImagesMatch(favicon_image, entry->GetFavicon().image)); |
-} |
- |
-// The test crashes on android: http://crbug.com/170449 |
-#if defined(OS_ANDROID) |
-#define MAYBE_PurgeScreenshot DISABLED_PurgeScreenshot |
-#else |
-#define MAYBE_PurgeScreenshot PurgeScreenshot |
-#endif |
-// Tests that screenshot are purged correctly. |
-TEST_F(NavigationControllerTest, MAYBE_PurgeScreenshot) { |
- NavigationControllerImpl& controller = controller_impl(); |
- |
- NavigationEntryImpl* entry; |
- |
- // Navigate enough times to make sure that some screenshots are purged. |
- for (int i = 0; i < 12; ++i) { |
- const GURL url(base::StringPrintf("http://foo%d/", i)); |
- NavigateAndCommit(url); |
- EXPECT_EQ(i, controller.GetCurrentEntryIndex()); |
- } |
- |
- MockScreenshotManager* screenshot_manager = |
- new MockScreenshotManager(&controller); |
- controller.SetScreenshotManager(screenshot_manager); |
- for (int i = 0; i < controller.GetEntryCount(); ++i) { |
- entry = NavigationEntryImpl::FromNavigationEntry( |
- controller.GetEntryAtIndex(i)); |
- screenshot_manager->TakeScreenshotFor(entry); |
- EXPECT_TRUE(entry->screenshot().get()); |
- } |
- |
- NavigateAndCommit(GURL("https://foo/")); |
- EXPECT_EQ(13, controller.GetEntryCount()); |
- entry = NavigationEntryImpl::FromNavigationEntry( |
- controller.GetEntryAtIndex(11)); |
- screenshot_manager->TakeScreenshotFor(entry); |
- |
- for (int i = 0; i < 2; ++i) { |
- entry = NavigationEntryImpl::FromNavigationEntry( |
- controller.GetEntryAtIndex(i)); |
- EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i |
- << " not purged"; |
- } |
- |
- for (int i = 2; i < controller.GetEntryCount() - 1; ++i) { |
- entry = NavigationEntryImpl::FromNavigationEntry( |
- controller.GetEntryAtIndex(i)); |
- EXPECT_TRUE(entry->screenshot().get()) << "Screenshot not found for " << i; |
- } |
- |
- // Navigate to index 5 and then try to assign screenshot to all entries. |
- controller.GoToIndex(5); |
- contents()->CommitPendingNavigation(); |
- EXPECT_EQ(5, controller.GetCurrentEntryIndex()); |
- for (int i = 0; i < controller.GetEntryCount() - 1; ++i) { |
- entry = NavigationEntryImpl::FromNavigationEntry( |
- controller.GetEntryAtIndex(i)); |
- screenshot_manager->TakeScreenshotFor(entry); |
- } |
- |
- for (int i = 10; i <= 12; ++i) { |
- entry = NavigationEntryImpl::FromNavigationEntry( |
- controller.GetEntryAtIndex(i)); |
- EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i |
- << " not purged"; |
- screenshot_manager->TakeScreenshotFor(entry); |
- } |
- |
- // Navigate to index 7 and assign screenshot to all entries. |
- controller.GoToIndex(7); |
- contents()->CommitPendingNavigation(); |
- EXPECT_EQ(7, controller.GetCurrentEntryIndex()); |
- for (int i = 0; i < controller.GetEntryCount() - 1; ++i) { |
- entry = NavigationEntryImpl::FromNavigationEntry( |
- controller.GetEntryAtIndex(i)); |
- screenshot_manager->TakeScreenshotFor(entry); |
- } |
- |
- for (int i = 0; i < 2; ++i) { |
- entry = NavigationEntryImpl::FromNavigationEntry( |
- controller.GetEntryAtIndex(i)); |
- EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i |
- << " not purged"; |
- } |
- |
- // Clear all screenshots. |
- EXPECT_EQ(13, controller.GetEntryCount()); |
- EXPECT_EQ(10, screenshot_manager->GetScreenshotCount()); |
- controller.ClearAllScreenshots(); |
- EXPECT_EQ(0, screenshot_manager->GetScreenshotCount()); |
- for (int i = 0; i < controller.GetEntryCount(); ++i) { |
- entry = NavigationEntryImpl::FromNavigationEntry( |
- controller.GetEntryAtIndex(i)); |
- EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i |
- << " not cleared"; |
- } |
-} |
- |
-// Test that the navigation controller clears its session history when a |
-// navigation commits with the clear history list flag set. |
-TEST_F(NavigationControllerTest, ClearHistoryList) { |
- const GURL url1("http://foo1"); |
- const GURL url2("http://foo2"); |
- const GURL url3("http://foo3"); |
- const GURL url4("http://foo4"); |
- |
- NavigationControllerImpl& controller = controller_impl(); |
- |
- // Create a session history with three entries, second entry is active. |
- NavigateAndCommit(url1); |
- NavigateAndCommit(url2); |
- NavigateAndCommit(url3); |
- controller.GoBack(); |
- contents()->CommitPendingNavigation(); |
- EXPECT_EQ(3, controller.GetEntryCount()); |
- EXPECT_EQ(1, controller.GetCurrentEntryIndex()); |
- |
- // Create a new pending navigation, and indicate that the session history |
- // should be cleared. |
- NavigationController::LoadURLParams params(url4); |
- params.should_clear_history_list = true; |
- controller.LoadURLWithParams(params); |
- |
- // Verify that the pending entry correctly indicates that the session history |
- // should be cleared. |
- NavigationEntryImpl* entry = |
- NavigationEntryImpl::FromNavigationEntry( |
- controller.GetPendingEntry()); |
- ASSERT_TRUE(entry); |
- EXPECT_TRUE(entry->should_clear_history_list()); |
- |
- // Assume that the RV correctly cleared its history and commit the navigation. |
- static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost())-> |
- set_simulate_history_list_was_cleared(true); |
- contents()->CommitPendingNavigation(); |
- |
- // Verify that the NavigationController's session history was correctly |
- // cleared. |
- EXPECT_EQ(1, controller.GetEntryCount()); |
- EXPECT_EQ(0, controller.GetCurrentEntryIndex()); |
- EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); |
- EXPECT_EQ(-1, controller.GetPendingEntryIndex()); |
- EXPECT_FALSE(controller.CanGoBack()); |
- EXPECT_FALSE(controller.CanGoForward()); |
- EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL()); |
-} |
- |
-} // namespace content |