diff options
Diffstat (limited to 'chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc')
-rw-r--r-- | chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc | 769 |
1 files changed, 542 insertions, 227 deletions
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc b/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc index 68f753a5e91..956288c33d9 100644 --- a/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc @@ -11,12 +11,14 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "content/browser/frame_host/cross_site_transferring_request.h" #include "content/browser/frame_host/navigation_controller_impl.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/frame_host/navigation_entry_screenshot_manager.h" #include "content/browser/frame_host/navigator.h" #include "content/browser/site_instance_impl.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/common/frame_messages.h" #include "content/common/view_messages.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/notification_registrar.h" @@ -79,7 +81,7 @@ class MockScreenshotManager : public content::NavigationEntryScreenshotManager { SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); bitmap.allocPixels(); - bitmap.eraseRGB(0, 0, 0); + bitmap.eraseARGB(0, 0, 0, 0); encoding_screenshot_in_progress_ = true; OnScreenshotTaken(entry->GetUniqueID(), true, bitmap); WaitUntilScreenshotIsReady(); @@ -233,21 +235,33 @@ SiteInstance* GetSiteInstanceFromEntry(NavigationEntry* entry) { class TestWebContentsDelegate : public WebContentsDelegate { public: explicit TestWebContentsDelegate() : - navigation_state_change_count_(0) {} + navigation_state_change_count_(0), + repost_form_warning_count_(0) {} int navigation_state_change_count() { return navigation_state_change_count_; } + int repost_form_warning_count() { + return repost_form_warning_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_++; } + virtual void ShowRepostFormWarningDialog(WebContents* source) OVERRIDE { + repost_form_warning_count_++; + } + private: // The number of times NavigationStateChanged has been called. int navigation_state_change_count_; + + // The number of times ShowRepostFormWarningDialog() was called. + int repost_form_warning_count_; }; // ----------------------------------------------------------------------------- @@ -276,7 +290,7 @@ TEST_F(NavigationControllerTest, GoToOffset) { urls[i] = GURL(base::StringPrintf("http://www.a.com/%d", i)); } - test_rvh()->SendNavigate(0, urls[0]); + main_test_rfh()->SendNavigate(0, urls[0]); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_EQ(urls[0], controller.GetVisibleEntry()->GetVirtualURL()); @@ -285,7 +299,7 @@ TEST_F(NavigationControllerTest, GoToOffset) { EXPECT_FALSE(controller.CanGoToOffset(1)); for (int i = 1; i <= 4; ++i) { - test_rvh()->SendNavigate(i, urls[i]); + main_test_rfh()->SendNavigate(i, urls[i]); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_EQ(urls[i], controller.GetVisibleEntry()->GetVirtualURL()); @@ -320,7 +334,7 @@ TEST_F(NavigationControllerTest, GoToOffset) { 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]); + main_test_rfh()->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. @@ -363,7 +377,7 @@ TEST_F(NavigationControllerTest, LoadURL) { // We should have gotten no notifications from the preceeding checks. EXPECT_EQ(0U, notifications.size()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -402,7 +416,7 @@ TEST_F(NavigationControllerTest, LoadURL) { // Simulate the beforeunload ack for the cross-site transition, and then the // commit. - test_rvh()->SendShouldCloseACK(true); + test_rvh()->SendBeforeUnloadACK(true); static_cast<TestRenderViewHost*>( contents()->GetPendingRenderViewHost())->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); @@ -444,7 +458,7 @@ TEST_F(NavigationControllerTest, LoadURLSameTime) { controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -453,8 +467,8 @@ TEST_F(NavigationControllerTest, LoadURLSameTime) { // Simulate the beforeunload ack for the cross-site transition, and then the // commit. - test_rvh()->SendShouldCloseACK(true); - test_rvh()->SendNavigate(1, url2); + test_rvh()->SendBeforeUnloadACK(true); + main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -527,7 +541,7 @@ TEST_F(NavigationControllerTest, LoadURLWithExtraParams_Data) { 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.virtual_url_for_data_url = GURL(url::kAboutBlankURL); load_params.override_user_agent = NavigationController::UA_OVERRIDE_FALSE; controller.LoadURLWithParams(load_params); @@ -577,7 +591,7 @@ TEST_F(NavigationControllerTest, LoadURL_SamePage) { controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(0U, notifications.size()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -587,7 +601,7 @@ TEST_F(NavigationControllerTest, LoadURL_SamePage) { controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(0U, notifications.size()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -618,14 +632,14 @@ TEST_F(NavigationControllerTest, LoadURL_SamePage_DifferentMethod) { const GURL url1("http://foo1"); controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 0; params.url = url1; params.transition = PAGE_TRANSITION_TYPED; params.is_post = true; params.post_id = 123; params.page_state = PageState::CreateForTesting(url1, false, 0, 0); - test_rvh()->SendNavigateWithParams(¶ms); + main_test_rfh()->SendNavigateWithParams(¶ms); // The post data should be visible. NavigationEntry* entry = controller.GetVisibleEntry(); @@ -634,7 +648,7 @@ TEST_F(NavigationControllerTest, LoadURL_SamePage_DifferentMethod) { EXPECT_EQ(entry->GetPostID(), 123); controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); // We should not have produced a new session history entry. ASSERT_EQ(controller.GetVisibleEntry(), entry); @@ -655,7 +669,7 @@ TEST_F(NavigationControllerTest, LoadURL_Discarded) { controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(0U, notifications.size()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -692,13 +706,13 @@ TEST_F(NavigationControllerTest, LoadURL_NoPending) { const GURL kExistingURL1("http://eh"); controller.LoadURL( kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, kExistingURL1); + main_test_rfh()->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); + main_test_rfh()->SendNavigate(99, kNewURL); // There should no longer be any pending entry, and the third navigation we // just made should be committed. @@ -722,7 +736,7 @@ TEST_F(NavigationControllerTest, LoadURL_NewPending) { const GURL kExistingURL1("http://eh"); controller.LoadURL( kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, kExistingURL1); + main_test_rfh()->SendNavigate(0, kExistingURL1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -733,7 +747,7 @@ TEST_F(NavigationControllerTest, LoadURL_NewPending) { EXPECT_EQ(0U, notifications.size()); // After the beforeunload but before it commits, do a new navigation. - test_rvh()->SendShouldCloseACK(true); + test_rvh()->SendBeforeUnloadACK(true); const GURL kNewURL("http://see"); static_cast<TestRenderViewHost*>( contents()->GetPendingRenderViewHost())->SendNavigate(3, kNewURL); @@ -759,14 +773,14 @@ TEST_F(NavigationControllerTest, LoadURL_ExistingPending) { const GURL kExistingURL1("http://foo/eh"); controller.LoadURL( kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, kExistingURL1); + main_test_rfh()->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); + main_test_rfh()->SendNavigate(1, kExistingURL2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -780,7 +794,7 @@ TEST_F(NavigationControllerTest, LoadURL_ExistingPending) { // Before that commits, do a new navigation. const GURL kNewURL("http://foo/see"); LoadCommittedDetails details; - test_rvh()->SendNavigate(3, kNewURL); + main_test_rfh()->SendNavigate(3, kNewURL); // There should no longer be any pending entry, and the third navigation we // just made should be committed. @@ -805,7 +819,7 @@ TEST_F(NavigationControllerTest, LoadURL_PrivilegedPending) { 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); + main_test_rfh()->SendNavigate(0, kExistingURL1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -813,7 +827,7 @@ TEST_F(NavigationControllerTest, LoadURL_PrivilegedPending) { const GURL kExistingURL2("http://foo/eh"); controller.LoadURL( kExistingURL2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendShouldCloseACK(true); + test_rvh()->SendBeforeUnloadACK(true); TestRenderViewHost* foo_rvh = static_cast<TestRenderViewHost*>( contents()->GetPendingRenderViewHost()); foo_rvh->SendNavigate(1, kExistingURL2); @@ -823,7 +837,7 @@ TEST_F(NavigationControllerTest, LoadURL_PrivilegedPending) { // Now make a pending back/forward navigation to a privileged entry. // The zeroth entry should be pending. controller.GoBack(); - foo_rvh->SendShouldCloseACK(true); + foo_rvh->SendBeforeUnloadACK(true); EXPECT_EQ(0U, notifications.size()); EXPECT_EQ(0, controller.GetPendingEntryIndex()); EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); @@ -858,14 +872,14 @@ TEST_F(NavigationControllerTest, LoadURL_BackPreemptsPending) { const GURL kExistingURL1("http://foo/eh"); controller.LoadURL( kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, kExistingURL1); + main_test_rfh()->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); + main_test_rfh()->SendNavigate(1, kExistingURL2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -878,7 +892,7 @@ TEST_F(NavigationControllerTest, LoadURL_BackPreemptsPending) { EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); // Before that commits, a back navigation from the renderer commits. - test_rvh()->SendNavigate(0, kExistingURL1); + main_test_rfh()->SendNavigate(0, kExistingURL1); // There should no longer be any pending entry, and the back navigation we // just made should be committed. @@ -903,7 +917,7 @@ TEST_F(NavigationControllerTest, LoadURL_IgnorePreemptsPending) { contents()->SetDelegate(delegate.get()); // Without any navigations, the renderer starts at about:blank. - const GURL kExistingURL(kAboutBlankURL); + const GURL kExistingURL(url::kAboutBlankURL); // Now make a pending new navigation. const GURL kNewURL("http://eh"); @@ -917,7 +931,7 @@ TEST_F(NavigationControllerTest, LoadURL_IgnorePreemptsPending) { // 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); + main_test_rfh()->SendNavigate(-1, kExistingURL); // This should clear the pending entry and notify of a navigation state // change, so that we do not keep displaying kNewURL. @@ -954,16 +968,14 @@ TEST_F(NavigationControllerTest, LoadURL_AbortDoesntCancelPending) { // 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; + FrameHostMsg_DidFailProvisionalLoadWithError_Params params; params.error_code = net::ERR_ABORTED; params.error_description = base::string16(); params.url = kNewURL; params.showing_repost_interstitial = false; - test_rvh()->OnMessageReceived( - ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id - params)); + main_test_rfh()->OnMessageReceived( + FrameHostMsg_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). @@ -994,7 +1006,7 @@ TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) { const GURL kExistingURL("http://foo/eh"); controller.LoadURL(kExistingURL, content::Referrer(), content::PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, kExistingURL); + main_test_rfh()->SendNavigate(0, kExistingURL); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1020,11 +1032,11 @@ TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) { // 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 + main_test_rfh()->OnMessageReceived( + FrameHostMsg_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. @@ -1032,23 +1044,21 @@ TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) { // 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; + FrameHostMsg_DidFailProvisionalLoadWithError_Params params; params.error_code = net::ERR_ABORTED; params.error_description = base::string16(); params.url = kRedirectURL; params.showing_repost_interstitial = false; - test_rvh()->OnMessageReceived( - ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id - params)); + main_test_rfh()->OnMessageReceived( + FrameHostMsg_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()); + EXPECT_EQ(1, delegate->navigation_state_change_count()); // The visible entry should be the last committed URL, not the pending one, // so that no spoof is possible. @@ -1063,6 +1073,7 @@ TEST_F(NavigationControllerTest, LoadURL_WithBindings) { NavigationControllerImpl& controller = controller_impl(); TestNotificationTracker notifications; RegisterForAllNavNotifications(¬ifications, &controller); + std::vector<GURL> url_chain; const GURL url1("http://foo1"); const GURL url2("http://foo2"); @@ -1089,13 +1100,18 @@ TEST_F(NavigationControllerTest, LoadURL_WithBindings) { 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. + // transition, run the unload handler, 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); + orig_rvh->SendBeforeUnloadACK(true); + contents()->GetRenderManagerForTesting()->OnCrossSiteResponse( + contents()->GetRenderManagerForTesting()->pending_frame_host(), + GlobalRequestID(0, 0), scoped_ptr<CrossSiteTransferringRequest>(), + url_chain, Referrer(), PAGE_TRANSITION_TYPED, false); + TestRenderViewHost* new_rvh = + static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost()); + new_rvh->AllowBindings(1); + new_rvh->SendNavigate(1, url2); // The second load should be committed, and bindings should be remembered. EXPECT_EQ(controller.GetEntryCount(), 2); @@ -1106,6 +1122,11 @@ TEST_F(NavigationControllerTest, LoadURL_WithBindings) { // Going back, the first entry should still appear unprivileged. controller.GoBack(); + new_rvh->SendBeforeUnloadACK(true); + contents()->GetRenderManagerForTesting()->OnCrossSiteResponse( + contents()->GetRenderManagerForTesting()->pending_frame_host(), + GlobalRequestID(0, 0), scoped_ptr<CrossSiteTransferringRequest>(), + url_chain, Referrer(), PAGE_TRANSITION_TYPED, false); orig_rvh->SendNavigate(0, url1); EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry( @@ -1121,11 +1142,11 @@ TEST_F(NavigationControllerTest, Reload) { controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(0U, notifications.size()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->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.GetVisibleEntry()->SetTitle(base::ASCIIToUTF16("Title")); controller.Reload(true); EXPECT_EQ(0U, notifications.size()); @@ -1145,7 +1166,7 @@ TEST_F(NavigationControllerTest, Reload) { // See http://crbug.com/96041. EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1173,14 +1194,14 @@ TEST_F(NavigationControllerTest, Reload_GeneratesNewPage) { const GURL url2("http://foo2"); controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->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); + main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1202,14 +1223,14 @@ TEST_F(NavigationControllerTest, ReloadWithGuest) { const GURL url1("http://foo1"); controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); ASSERT_TRUE(controller.GetVisibleEntry()); // Make the entry believe its RenderProcessHost is a guest. NavigationEntryImpl* entry1 = NavigationEntryImpl::FromNavigationEntry(controller.GetVisibleEntry()); reinterpret_cast<MockRenderProcessHost*>( - entry1->site_instance()->GetProcess())->SetIsGuest(true); + entry1->site_instance()->GetProcess())->set_is_isolated_guest(true); // And reload. controller.Reload(true); @@ -1238,7 +1259,8 @@ TEST_F(NavigationControllerTest, ReloadOriginalRequestURL) { controller.LoadURL( original_url, Referrer(), PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(0U, notifications.size()); - test_rvh()->SendNavigateWithOriginalRequestURL(0, final_url, original_url); + main_test_rfh()->SendNavigateWithOriginalRequestURL( + 0, final_url, original_url); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1249,7 +1271,7 @@ TEST_F(NavigationControllerTest, ReloadOriginalRequestURL) { EXPECT_EQ(final_url, controller.GetVisibleEntry()->GetURL()); // Reload using the original URL. - controller.GetVisibleEntry()->SetTitle(ASCIIToUTF16("Title")); + controller.GetVisibleEntry()->SetTitle(base::ASCIIToUTF16("Title")); controller.ReloadOriginalRequestURL(false); EXPECT_EQ(0U, notifications.size()); @@ -1269,7 +1291,7 @@ TEST_F(NavigationControllerTest, ReloadOriginalRequestURL) { EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty()); // Send that the navigation has proceeded; say it got redirected again. - test_rvh()->SendNavigate(0, final_url); + main_test_rfh()->SendNavigate(0, final_url); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1310,16 +1332,14 @@ TEST_F(NavigationControllerTest, ResetEntryValuesAfterCommit) { pending_entry->set_is_renderer_initiated(true); pending_entry->set_transferred_global_request_id(transfer_id); pending_entry->set_should_replace_entry(true); - pending_entry->set_redirect_chain(redirects); pending_entry->set_should_clear_history_list(true); EXPECT_EQ(post_data.get(), pending_entry->GetBrowserInitiatedPostData()); EXPECT_TRUE(pending_entry->is_renderer_initiated()); EXPECT_EQ(transfer_id, pending_entry->transferred_global_request_id()); EXPECT_TRUE(pending_entry->should_replace_entry()); - EXPECT_EQ(1U, pending_entry->redirect_chain().size()); EXPECT_TRUE(pending_entry->should_clear_history_list()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); // Certain values that are only used for pending entries get reset after // commit. @@ -1331,10 +1351,35 @@ TEST_F(NavigationControllerTest, ResetEntryValuesAfterCommit) { EXPECT_EQ(GlobalRequestID(-1, -1), committed_entry->transferred_global_request_id()); EXPECT_FALSE(committed_entry->should_replace_entry()); - EXPECT_EQ(0U, committed_entry->redirect_chain().size()); EXPECT_FALSE(committed_entry->should_clear_history_list()); } +// Test that Redirects are preserved after a commit. +TEST_F(NavigationControllerTest, RedirectsAreNotResetByCommit) { + NavigationControllerImpl& controller = controller_impl(); + const GURL url1("http://foo1"); + controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); + + // Set up some redirect values. + std::vector<GURL> redirects; + redirects.push_back(GURL("http://foo2")); + + // Set redirects on the pending entry. + NavigationEntryImpl* pending_entry = + NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry()); + pending_entry->SetRedirectChain(redirects); + EXPECT_EQ(1U, pending_entry->GetRedirectChain().size()); + EXPECT_EQ(GURL("http://foo2"), pending_entry->GetRedirectChain()[0]); + + // Normal navigation will preserve redirects in the committed entry. + main_test_rfh()->SendNavigateWithRedirects(0, url1, redirects); + NavigationEntryImpl* committed_entry = + NavigationEntryImpl::FromNavigationEntry( + controller.GetLastCommittedEntry()); + ASSERT_EQ(1U, committed_entry->GetRedirectChain().size()); + EXPECT_EQ(GURL("http://foo2"), committed_entry->GetRedirectChain()[0]); +} + // Tests what happens when we navigate back successfully TEST_F(NavigationControllerTest, Back) { NavigationControllerImpl& controller = controller_impl(); @@ -1342,12 +1387,12 @@ TEST_F(NavigationControllerTest, Back) { RegisterForAllNavNotifications(¬ifications, &controller); const GURL url1("http://foo1"); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->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); + main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1371,7 +1416,7 @@ TEST_F(NavigationControllerTest, Back) { EXPECT_GE(controller.GetEntryAtIndex(1)->GetTimestamp(), controller.GetEntryAtIndex(0)->GetTimestamp()); - test_rvh()->SendNavigate(0, url2); + main_test_rfh()->SendNavigate(0, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1405,12 +1450,12 @@ TEST_F(NavigationControllerTest, Back_GeneratesNewPage) { controller.LoadURL( url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->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); + main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1426,7 +1471,7 @@ TEST_F(NavigationControllerTest, Back_GeneratesNewPage) { EXPECT_FALSE(controller.CanGoBack()); EXPECT_TRUE(controller.CanGoForward()); - test_rvh()->SendNavigate(2, url3); + main_test_rfh()->SendNavigate(2, url3); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1452,12 +1497,12 @@ TEST_F(NavigationControllerTest, Back_NewPending) { const GURL kUrl3("http://foo3"); // First navigate two places so we have some back history. - test_rvh()->SendNavigate(0, kUrl1); + main_test_rfh()->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); + main_test_rfh()->SendNavigate(1, kUrl2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1482,12 +1527,12 @@ TEST_F(NavigationControllerTest, Back_OtherBackPending) { 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); + main_test_rfh()->SendNavigate(0, kUrl1); + main_test_rfh()->SendNavigate(1, kUrl2); + main_test_rfh()->SendNavigate(2, kUrl3); // With nothing pending, say we get a navigation to the second entry. - test_rvh()->SendNavigate(1, kUrl2); + main_test_rfh()->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. @@ -1503,7 +1548,7 @@ TEST_F(NavigationControllerTest, Back_OtherBackPending) { // Now go forward to the last item again and say it was committed. controller.GoForward(); - test_rvh()->SendNavigate(2, kUrl3); + main_test_rfh()->SendNavigate(2, kUrl3); // Now start going back one to the second page. It will be pending. controller.GoBack(); @@ -1512,7 +1557,7 @@ TEST_F(NavigationControllerTest, Back_OtherBackPending) { // Not synthesize a totally new back event to the first page. This will not // match the pending one. - test_rvh()->SendNavigate(0, kUrl1); + main_test_rfh()->SendNavigate(0, kUrl1); // The committed navigation should clear the pending entry. EXPECT_EQ(-1, controller.GetPendingEntryIndex()); @@ -1531,16 +1576,16 @@ TEST_F(NavigationControllerTest, Forward) { const GURL url1("http://foo1"); const GURL url2("http://foo2"); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; - test_rvh()->SendNavigate(1, url2); + main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; controller.GoBack(); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1564,7 +1609,7 @@ TEST_F(NavigationControllerTest, Forward) { EXPECT_GE(controller.GetEntryAtIndex(0)->GetTimestamp(), controller.GetEntryAtIndex(1)->GetTimestamp()); - test_rvh()->SendNavigate(1, url2); + main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1596,15 +1641,15 @@ TEST_F(NavigationControllerTest, Forward_GeneratesNewPage) { const GURL url2("http://foo2"); const GURL url3("http://foo3"); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; - test_rvh()->SendNavigate(1, url2); + main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; controller.GoBack(); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1620,7 +1665,7 @@ TEST_F(NavigationControllerTest, Forward_GeneratesNewPage) { EXPECT_TRUE(controller.CanGoBack()); EXPECT_FALSE(controller.CanGoForward()); - test_rvh()->SendNavigate(2, url3); + main_test_rfh()->SendNavigate(2, url3); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_TRUE(notifications.Check1AndReset(NOTIFICATION_NAV_LIST_PRUNED)); @@ -1648,7 +1693,7 @@ TEST_F(NavigationControllerTest, Redirect) { controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); EXPECT_EQ(0U, notifications.size()); - test_rvh()->SendNavigate(0, url2); + main_test_rfh()->SendNavigate(0, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1659,7 +1704,7 @@ TEST_F(NavigationControllerTest, Redirect) { EXPECT_EQ(controller.GetPendingEntryIndex(), -1); EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 0; params.url = url2; params.transition = PAGE_TRANSITION_SERVER_REDIRECT; @@ -1673,7 +1718,8 @@ TEST_F(NavigationControllerTest, Redirect) { LoadCommittedDetails details; EXPECT_EQ(0U, notifications.size()); - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1705,7 +1751,7 @@ TEST_F(NavigationControllerTest, PostThenRedirect) { controller.GetVisibleEntry()->SetHasPostData(true); EXPECT_EQ(0U, notifications.size()); - test_rvh()->SendNavigate(0, url2); + main_test_rfh()->SendNavigate(0, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1716,7 +1762,7 @@ TEST_F(NavigationControllerTest, PostThenRedirect) { EXPECT_EQ(controller.GetPendingEntryIndex(), -1); EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 0; params.url = url2; params.transition = PAGE_TRANSITION_SERVER_REDIRECT; @@ -1730,7 +1776,8 @@ TEST_F(NavigationControllerTest, PostThenRedirect) { LoadCommittedDetails details; EXPECT_EQ(0U, notifications.size()); - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1763,7 +1810,7 @@ TEST_F(NavigationControllerTest, ImmediateRedirect) { EXPECT_EQ(controller.GetPendingEntryIndex(), -1); EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 0; params.url = url2; params.transition = PAGE_TRANSITION_SERVER_REDIRECT; @@ -1777,7 +1824,8 @@ TEST_F(NavigationControllerTest, ImmediateRedirect) { LoadCommittedDetails details; EXPECT_EQ(0U, notifications.size()); - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1801,12 +1849,12 @@ TEST_F(NavigationControllerTest, NewSubframe) { RegisterForAllNavNotifications(¬ifications, &controller); const GURL url1("http://foo1"); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; const GURL url2("http://foo2"); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 1; params.url = url2; params.transition = PAGE_TRANSITION_MANUAL_SUBFRAME; @@ -1816,7 +1864,8 @@ TEST_F(NavigationControllerTest, NewSubframe) { params.page_state = PageState::CreateFromURL(url2); LoadCommittedDetails details; - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_EQ(url1, details.previous_url); @@ -1842,7 +1891,7 @@ TEST_F(NavigationControllerTest, SubframeOnEmptyPage) { // Navigation controller currently has no entries. const GURL url("http://foo2"); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 1; params.url = url; params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; @@ -1852,7 +1901,8 @@ TEST_F(NavigationControllerTest, SubframeOnEmptyPage) { params.page_state = PageState::CreateFromURL(url); LoadCommittedDetails details; - EXPECT_FALSE(controller.RendererDidNavigate(params, &details)); + EXPECT_FALSE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(0U, notifications.size()); } @@ -1864,12 +1914,12 @@ TEST_F(NavigationControllerTest, AutoSubframe) { RegisterForAllNavNotifications(¬ifications, &controller); const GURL url1("http://foo1"); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; const GURL url2("http://foo2"); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 0; params.url = url2; params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; @@ -1880,7 +1930,8 @@ TEST_F(NavigationControllerTest, AutoSubframe) { // Navigating should do nothing. LoadCommittedDetails details; - EXPECT_FALSE(controller.RendererDidNavigate(params, &details)); + EXPECT_FALSE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(0U, notifications.size()); // There should still be only one entry. @@ -1895,13 +1946,13 @@ TEST_F(NavigationControllerTest, BackSubframe) { // Main page. const GURL url1("http://foo1"); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->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; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 1; params.url = url2; params.transition = PAGE_TRANSITION_MANUAL_SUBFRAME; @@ -1912,7 +1963,8 @@ TEST_F(NavigationControllerTest, BackSubframe) { // This should generate a new entry. LoadCommittedDetails details; - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_EQ(2, controller.GetEntryCount()); @@ -1921,7 +1973,8 @@ TEST_F(NavigationControllerTest, BackSubframe) { const GURL url3("http://foo3"); params.page_id = 2; params.url = url3; - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_EQ(3, controller.GetEntryCount()); @@ -1931,7 +1984,8 @@ TEST_F(NavigationControllerTest, BackSubframe) { controller.GoBack(); params.url = url2; params.page_id = 1; - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_EQ(3, controller.GetEntryCount()); @@ -1943,7 +1997,8 @@ TEST_F(NavigationControllerTest, BackSubframe) { controller.GoBack(); params.url = url1; params.page_id = 0; - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_EQ(3, controller.GetEntryCount()); @@ -1960,11 +2015,11 @@ TEST_F(NavigationControllerTest, LinkClick) { const GURL url1("http://foo1"); const GURL url2("http://foo2"); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; - test_rvh()->SendNavigate(1, url2); + main_test_rfh()->SendNavigate(1, url2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -1985,13 +2040,13 @@ TEST_F(NavigationControllerTest, InPage) { // Main page. const GURL url1("http://foo"); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->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; + FrameHostMsg_DidCommitProvisionalLoad_Params self_params; self_params.page_id = 0; self_params.url = url1; self_params.transition = PAGE_TRANSITION_LINK; @@ -2002,7 +2057,8 @@ TEST_F(NavigationControllerTest, InPage) { self_params.was_within_same_page = true; LoadCommittedDetails details; - EXPECT_TRUE(controller.RendererDidNavigate(self_params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), self_params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_TRUE(details.is_in_page); @@ -2011,7 +2067,7 @@ TEST_F(NavigationControllerTest, InPage) { // Fragment navigation to a new page_id. const GURL url2("http://foo#a"); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 1; params.url = url2; params.transition = PAGE_TRANSITION_LINK; @@ -2022,7 +2078,8 @@ TEST_F(NavigationControllerTest, InPage) { params.was_within_same_page = true; // This should generate a new entry. - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_TRUE(details.is_in_page); @@ -2030,11 +2087,12 @@ TEST_F(NavigationControllerTest, InPage) { EXPECT_EQ(2, controller.GetEntryCount()); // Go back one. - ViewHostMsg_FrameNavigate_Params back_params(params); + FrameHostMsg_DidCommitProvisionalLoad_Params back_params(params); controller.GoBack(); back_params.url = url1; back_params.page_id = 0; - EXPECT_TRUE(controller.RendererDidNavigate(back_params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), back_params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_TRUE(details.is_in_page); @@ -2043,11 +2101,12 @@ TEST_F(NavigationControllerTest, InPage) { EXPECT_EQ(back_params.url, controller.GetVisibleEntry()->GetURL()); // Go forward - ViewHostMsg_FrameNavigate_Params forward_params(params); + FrameHostMsg_DidCommitProvisionalLoad_Params forward_params(params); controller.GoForward(); forward_params.url = url2; forward_params.page_id = 1; - EXPECT_TRUE(controller.RendererDidNavigate(forward_params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), forward_params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_TRUE(details.is_in_page); @@ -2061,9 +2120,11 @@ TEST_F(NavigationControllerTest, InPage) { // 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)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), back_params, + &details)); controller.GoForward(); - EXPECT_TRUE(controller.RendererDidNavigate(forward_params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), forward_params, + &details)); EXPECT_EQ(forward_params.url, controller.GetVisibleEntry()->GetURL()); @@ -2072,7 +2133,8 @@ TEST_F(NavigationControllerTest, InPage) { params.page_id = 2; params.url = url3; navigation_entry_committed_counter_ = 0; - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_FALSE(details.is_in_page); @@ -2087,13 +2149,13 @@ TEST_F(NavigationControllerTest, InPage_Replace) { // Main page. const GURL url1("http://foo"); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->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; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 0; // Same page_id params.url = url2; params.transition = PAGE_TRANSITION_LINK; @@ -2101,10 +2163,12 @@ TEST_F(NavigationControllerTest, InPage_Replace) { params.gesture = NavigationGestureUser; params.is_post = false; params.page_state = PageState::CreateFromURL(url2); + params.was_within_same_page = true; // This should NOT generate a new entry, nor prune the list. LoadCommittedDetails details; - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_TRUE(details.is_in_page); @@ -2126,7 +2190,7 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { // Load an initial page. { const GURL url("http://foo/"); - test_rvh()->SendNavigate(0, url); + main_test_rfh()->SendNavigate(0, url); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; } @@ -2134,7 +2198,7 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { // Navigate to a new page. { const GURL url("http://foo2/"); - test_rvh()->SendNavigate(1, url); + main_test_rfh()->SendNavigate(1, url); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; } @@ -2142,7 +2206,7 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { // Navigate within the page. { const GURL url("http://foo2/#a"); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 1; // Same page_id params.url = url; params.transition = PAGE_TRANSITION_LINK; @@ -2151,10 +2215,12 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { params.gesture = NavigationGestureUnknown; params.is_post = false; params.page_state = PageState::CreateFromURL(url); + params.was_within_same_page = true; // This should NOT generate a new entry, nor prune the list. LoadCommittedDetails details; - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_TRUE(details.is_in_page); @@ -2165,7 +2231,7 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { // Perform a client redirect to a new page. { const GURL url("http://foo3/"); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 2; // New page_id params.url = url; params.transition = PAGE_TRANSITION_CLIENT_REDIRECT; @@ -2178,7 +2244,8 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { // This SHOULD generate a new entry. LoadCommittedDetails details; - EXPECT_TRUE(controller.RendererDidNavigate(params, &details)); + EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_FALSE(details.is_in_page); @@ -2189,13 +2256,26 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) { { const GURL url("http://foo2/"); controller.GoBack(); - test_rvh()->SendNavigate(1, url); + main_test_rfh()->SendNavigate(1, url); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL()); } } +TEST_F(NavigationControllerTest, PushStateWithoutPreviousEntry) +{ + ASSERT_FALSE(controller_impl().GetLastCommittedEntry()); + FrameHostMsg_DidCommitProvisionalLoad_Params params; + GURL url("http://foo"); + params.page_id = 1; + params.url = url; + params.page_state = PageState::CreateFromURL(url); + params.was_within_same_page = true; + test_rvh()->SendNavigateWithParams(¶ms); + // We pass if we don't crash. +} + // NotificationObserver implementation used in verifying we've received the // NOTIFICATION_NAV_LIST_PRUNED method. class PrunedListener : public NotificationObserver { @@ -2241,7 +2321,7 @@ TEST_F(NavigationControllerTest, EnforceMaxNavigationCount) { 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); + main_test_rfh()->SendNavigate(url_index, url); } EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount); @@ -2253,7 +2333,7 @@ TEST_F(NavigationControllerTest, EnforceMaxNavigationCount) { 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); + main_test_rfh()->SendNavigate(url_index, url); url_index++; // We should have got a pruned navigation. @@ -2271,7 +2351,7 @@ TEST_F(NavigationControllerTest, EnforceMaxNavigationCount) { 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); + main_test_rfh()->SendNavigate(url_index, url); url_index++; } EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount); @@ -2292,7 +2372,7 @@ TEST_F(NavigationControllerTest, RestoreNavigate) { url, Referrer(), PAGE_TRANSITION_RELOAD, false, std::string(), browser_context()); entry->SetPageID(0); - entry->SetTitle(ASCIIToUTF16("Title")); + entry->SetTitle(base::ASCIIToUTF16("Title")); entry->SetPageState(PageState::CreateFromEncodedData("state")); const base::Time timestamp = base::Time::Now(); entry->SetTimestamp(timestamp); @@ -2332,7 +2412,7 @@ TEST_F(NavigationControllerTest, RestoreNavigate) { EXPECT_EQ(timestamp, our_controller.GetEntryAtIndex(0)->GetTimestamp()); // Say we navigated to that entry. - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 0; params.url = url; params.transition = PAGE_TRANSITION_LINK; @@ -2341,7 +2421,8 @@ TEST_F(NavigationControllerTest, RestoreNavigate) { params.is_post = false; params.page_state = PageState::CreateFromURL(url); LoadCommittedDetails details; - our_controller.RendererDidNavigate(params, &details); + our_controller.RendererDidNavigate(our_contents->GetMainFrame(), 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 @@ -2371,7 +2452,7 @@ TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) { url, Referrer(), PAGE_TRANSITION_RELOAD, false, std::string(), browser_context()); entry->SetPageID(0); - entry->SetTitle(ASCIIToUTF16("Title")); + entry->SetTitle(base::ASCIIToUTF16("Title")); entry->SetPageState(PageState::CreateFromEncodedData("state")); entries.push_back(entry); scoped_ptr<WebContentsImpl> our_contents(static_cast<WebContentsImpl*>( @@ -2404,21 +2485,17 @@ TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) { // 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; + FrameHostMsg_DidFailProvisionalLoadWithError_Params fail_load_params; fail_load_params.error_code = net::ERR_ABORTED; fail_load_params.error_description = base::string16(); fail_load_params.url = url; fail_load_params.showing_repost_interstitial = false; - rvh->OnMessageReceived( - ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id + main_test_rfh()->OnMessageReceived( + FrameHostMsg_DidFailProvisionalLoadWithError(0, // routing_id fail_load_params)); // Now the pending restored entry commits. - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 0; params.url = url; params.transition = PAGE_TRANSITION_LINK; @@ -2427,7 +2504,8 @@ TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) { params.is_post = false; params.page_state = PageState::CreateFromURL(url); LoadCommittedDetails details; - our_controller.RendererDidNavigate(params, &details); + our_controller.RendererDidNavigate(our_contents->GetMainFrame(), params, + &details); // There should be no pending entry and one committed one. EXPECT_EQ(1, our_controller.GetEntryCount()); @@ -2449,7 +2527,7 @@ TEST_F(NavigationControllerTest, Interstitial) { const GURL url1("http://foo"); controller.LoadURL( url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); // Now navigate somewhere with an interstitial. const GURL url2("http://bar"); @@ -2460,7 +2538,7 @@ TEST_F(NavigationControllerTest, 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); + main_test_rfh()->SendNavigate(1, url2); // The page should be a normal page again. EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL()); @@ -2480,19 +2558,19 @@ TEST_F(NavigationControllerTest, RemoveEntry) { controller.LoadURL( url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); controller.LoadURL( url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(1, url2); + main_test_rfh()->SendNavigate(1, url2); controller.LoadURL( url3, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(2, url3); + main_test_rfh()->SendNavigate(2, url3); controller.LoadURL( url4, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(3, url4); + main_test_rfh()->SendNavigate(3, url4); controller.LoadURL( url5, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(4, url5); + main_test_rfh()->SendNavigate(4, url5); // Try to remove the last entry. Will fail because it is the current entry. EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1)); @@ -2506,7 +2584,7 @@ TEST_F(NavigationControllerTest, RemoveEntry) { EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 2)); // Now commit and delete the last entry. - test_rvh()->SendNavigate(3, url4); + main_test_rfh()->SendNavigate(3, url4); EXPECT_TRUE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1)); EXPECT_EQ(4, controller.GetEntryCount()); EXPECT_EQ(3, controller.GetLastCommittedEntryIndex()); @@ -2543,10 +2621,10 @@ TEST_F(NavigationControllerTest, TransientEntry) { controller.LoadURL( url0, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, url0); + main_test_rfh()->SendNavigate(0, url0); controller.LoadURL( url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(1, url1); + main_test_rfh()->SendNavigate(1, url1); notifications.Reset(); @@ -2572,7 +2650,7 @@ TEST_F(NavigationControllerTest, TransientEntry) { // Navigate. controller.LoadURL( url2, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(2, url2); + main_test_rfh()->SendNavigate(2, url2); // We should have navigated, transient entry should be gone. EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); @@ -2583,7 +2661,7 @@ TEST_F(NavigationControllerTest, TransientEntry) { transient_entry->SetURL(transient_url); controller.SetTransientEntry(transient_entry); EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); - test_rvh()->SendNavigate(3, url3); + main_test_rfh()->SendNavigate(3, url3); // Transient entry should be gone. EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL()); EXPECT_EQ(controller.GetEntryCount(), 4); @@ -2595,7 +2673,7 @@ TEST_F(NavigationControllerTest, TransientEntry) { transient_entry->SetURL(transient_url); controller.SetTransientEntry(transient_entry); EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); - test_rvh()->SendNavigate(4, url4); + main_test_rfh()->SendNavigate(4, url4); EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL()); EXPECT_EQ(controller.GetEntryCount(), 5); @@ -2610,7 +2688,7 @@ TEST_F(NavigationControllerTest, TransientEntry) { // Transient entry should be gone. EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL()); EXPECT_EQ(controller.GetEntryCount(), 5); - test_rvh()->SendNavigate(3, url3); + main_test_rfh()->SendNavigate(3, url3); // Add a transient and go to an entry before the current one. transient_entry = new NavigationEntryImpl; @@ -2623,7 +2701,7 @@ TEST_F(NavigationControllerTest, TransientEntry) { 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); + main_test_rfh()->SendNavigate(1, url1); EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); // Add a transient and go to an entry after the current one. @@ -2637,7 +2715,7 @@ TEST_F(NavigationControllerTest, TransientEntry) { // 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); + main_test_rfh()->SendNavigate(2, url2); EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); // Add a transient and go forward. @@ -2651,7 +2729,7 @@ TEST_F(NavigationControllerTest, TransientEntry) { EXPECT_FALSE(controller.GetTransientEntry()); EXPECT_EQ(url3, controller.GetPendingEntry()->GetURL()); EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL()); - test_rvh()->SendNavigate(3, url3); + main_test_rfh()->SendNavigate(3, url3); EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL()); // Add a transient and do an in-page navigation, replacing the current entry. @@ -2659,7 +2737,7 @@ TEST_F(NavigationControllerTest, TransientEntry) { transient_entry->SetURL(transient_url); controller.SetTransientEntry(transient_entry); EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL()); - test_rvh()->SendNavigate(3, url3_ref); + main_test_rfh()->SendNavigate(3, url3_ref); // Transient entry should be gone. EXPECT_FALSE(controller.GetTransientEntry()); EXPECT_EQ(url3_ref, controller.GetVisibleEntry()->GetURL()); @@ -2683,7 +2761,7 @@ TEST_F(NavigationControllerTest, ReloadTransient) { // Load |url0|, and start a pending navigation to |url1|. controller.LoadURL( url0, Referrer(), PAGE_TRANSITION_TYPED, std::string()); - test_rvh()->SendNavigate(0, url0); + main_test_rfh()->SendNavigate(0, url0); controller.LoadURL( url1, Referrer(), PAGE_TRANSITION_TYPED, std::string()); @@ -2705,7 +2783,7 @@ TEST_F(NavigationControllerTest, ReloadTransient) { EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0); // Load of |transient_url| completes. - test_rvh()->SendNavigate(1, transient_url); + main_test_rfh()->SendNavigate(1, transient_url); ASSERT_EQ(controller.GetEntryCount(), 2); EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0); EXPECT_EQ(controller.GetEntryAtIndex(1)->GetURL(), transient_url); @@ -2725,7 +2803,7 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) { // We create pending entries for renderer-initiated navigations so that we // can show them in new tabs when it is safe. - navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url1); + navigator->DidStartProvisionalLoad(main_test_rfh(), -1, url1); // Simulate what happens if a BrowserURLHandler rewrites the URL, causing // the virtual URL to differ from the URL. @@ -2739,35 +2817,35 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) { is_renderer_initiated()); // If the user clicks another link, we should replace the pending entry. - navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url2); + navigator->DidStartProvisionalLoad(main_test_rfh(), -1, 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); + main_test_rfh()->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. - navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url1); + navigator->DidStartProvisionalLoad(main_test_rfh(), -1, url1); EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL()); navigator->DidStartProvisionalLoad( - main_test_rfh(), 1, -1, true, GURL(kUnreachableWebDataURL)); + main_test_rfh(), -1, GURL(kUnreachableWebDataURL)); EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL()); // We should remember if the pending entry will replace the current one. // http://crbug.com/308444. - navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url1); + navigator->DidStartProvisionalLoad(main_test_rfh(), -1, url1); NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> set_should_replace_entry(true); - navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url2); + navigator->DidStartProvisionalLoad(main_test_rfh(), -1, url2); EXPECT_TRUE( NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> should_replace_entry()); // TODO(nasko): Until OnNavigate is moved to RenderFrameHost, we need // to go through the RenderViewHost. The TestRenderViewHost routes navigations // to the main frame. - test_rvh()->SendNavigate(0, url2); + main_test_rfh()->SendNavigate(0, url2); EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL()); } @@ -2787,7 +2865,7 @@ TEST_F(NavigationControllerTest, DontShowRendererURLUntilCommit) { 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); + main_test_rfh()->SendNavigate(0, url0); // For link clicks (renderer-initiated navigations), the pending entry should // update before commit but the visible should not. @@ -2802,7 +2880,7 @@ TEST_F(NavigationControllerTest, DontShowRendererURLUntilCommit) { // 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); + main_test_rfh()->SendNavigate(1, url1); EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); EXPECT_FALSE(controller.GetPendingEntry()); EXPECT_FALSE( @@ -2836,16 +2914,117 @@ TEST_F(NavigationControllerTest, ShowRendererURLInNewTabUntilModified) { NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> is_renderer_initiated()); EXPECT_TRUE(controller.IsInitialNavigation()); - EXPECT_FALSE(test_rvh()->has_accessed_initial_document()); + EXPECT_FALSE(contents()->HasAccessedInitialDocument()); // 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()); + main_test_rfh()->OnMessageReceived(FrameHostMsg_DidAccessInitialDocument(0)); + EXPECT_TRUE(contents()->HasAccessedInitialDocument()); + EXPECT_FALSE(controller.GetVisibleEntry()); + EXPECT_EQ(url, controller.GetPendingEntry()->GetURL()); + + notifications.Reset(); +} + +// Tests that the URLs for browser-initiated navigations in new tabs are +// displayed to the user even after they fail, 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/355537. +TEST_F(NavigationControllerTest, ShowBrowserURLAfterFailUntilModified) { + NavigationControllerImpl& controller = controller_impl(); + TestNotificationTracker notifications; + RegisterForAllNavNotifications(¬ifications, &controller); + + const GURL url("http://foo"); + + // For browser-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. This is possible in cases that the user types a URL into a popup + // tab created with a slow URL. + NavigationController::LoadURLParams load_url_params(url); + load_url_params.transition_type = PAGE_TRANSITION_TYPED; + load_url_params.is_renderer_initiated = false; + controller.LoadURLWithParams(load_url_params); + EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL()); + EXPECT_EQ(url, controller.GetPendingEntry()->GetURL()); + EXPECT_FALSE( + NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> + is_renderer_initiated()); + EXPECT_TRUE(controller.IsInitialNavigation()); + EXPECT_FALSE(contents()->HasAccessedInitialDocument()); + + // There should be no title yet. + EXPECT_TRUE(contents()->GetTitle().empty()); + + // Suppose it aborts before committing, if it's a 204 or download or due to a + // stop or a new navigation from the user. The URL should remain visible. + FrameHostMsg_DidFailProvisionalLoadWithError_Params params; + params.error_code = net::ERR_ABORTED; + params.error_description = base::string16(); + params.url = url; + params.showing_repost_interstitial = false; + main_test_rfh()->OnMessageReceived( + FrameHostMsg_DidFailProvisionalLoadWithError(0, params)); + contents()->SetIsLoading(test_rvh(), false, true, NULL); + EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL()); + + // If something else later modifies the contents of the about:blank page, then + // we must revert to showing about:blank to avoid a URL spoof. + main_test_rfh()->OnMessageReceived(FrameHostMsg_DidAccessInitialDocument(0)); + EXPECT_TRUE(contents()->HasAccessedInitialDocument()); + EXPECT_FALSE(controller.GetVisibleEntry()); + EXPECT_FALSE(controller.GetPendingEntry()); + + notifications.Reset(); +} + +// Tests that the URLs for renderer-initiated navigations in new tabs are +// displayed to the user even after they fail, 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/355537. +TEST_F(NavigationControllerTest, ShowRendererURLAfterFailUntilModified) { + 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(contents()->HasAccessedInitialDocument()); + + // There should be no title yet. + EXPECT_TRUE(contents()->GetTitle().empty()); + + // Suppose it aborts before committing, if it's a 204 or download or due to a + // stop or a new navigation from the user. The URL should remain visible. + FrameHostMsg_DidFailProvisionalLoadWithError_Params params; + params.error_code = net::ERR_ABORTED; + params.error_description = base::string16(); + params.url = url; + params.showing_repost_interstitial = false; + main_test_rfh()->OnMessageReceived( + FrameHostMsg_DidFailProvisionalLoadWithError(0, params)); + EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL()); + + // If something else later modifies the contents of the about:blank page, then + // we must revert to showing about:blank to avoid a URL spoof. + main_test_rfh()->OnMessageReceived(FrameHostMsg_DidAccessInitialDocument(0)); + EXPECT_TRUE(contents()->HasAccessedInitialDocument()); EXPECT_FALSE(controller.GetVisibleEntry()); EXPECT_EQ(url, controller.GetPendingEntry()->GetURL()); @@ -2872,10 +3051,10 @@ TEST_F(NavigationControllerTest, DontShowRendererURLInNewTabAfterCommit) { NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())-> is_renderer_initiated()); EXPECT_TRUE(controller.IsInitialNavigation()); - EXPECT_FALSE(test_rvh()->has_accessed_initial_document()); + EXPECT_FALSE(contents()->HasAccessedInitialDocument()); // Simulate a commit and then starting a new pending navigation. - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); NavigationController::LoadURLParams load_url2_params(url2); load_url2_params.transition_type = PAGE_TRANSITION_LINK; load_url2_params.is_renderer_initiated = true; @@ -2883,7 +3062,7 @@ TEST_F(NavigationControllerTest, DontShowRendererURLInNewTabAfterCommit) { // 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(contents()->HasAccessedInitialDocument()); EXPECT_FALSE(controller.IsInitialNavigation()); EXPECT_TRUE(controller.GetVisibleEntry()); EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); @@ -2897,24 +3076,31 @@ 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); + main_test_rfh()->SendNavigate(0, url); // Reloading the page is not an in-page navigation. - EXPECT_FALSE(controller.IsURLInPageNavigation(url)); + EXPECT_FALSE(controller.IsURLInPageNavigation(url, false, + NAVIGATION_TYPE_UNKNOWN)); const GURL other_url("http://www.google.com/add.html"); - EXPECT_FALSE(controller.IsURLInPageNavigation(other_url)); + EXPECT_FALSE(controller.IsURLInPageNavigation(other_url, false, + NAVIGATION_TYPE_UNKNOWN)); const GURL url_with_ref("http://www.google.com/home.html#my_ref"); - EXPECT_TRUE(controller.IsURLInPageNavigation(url_with_ref)); + EXPECT_TRUE(controller.IsURLInPageNavigation(url_with_ref, true, + NAVIGATION_TYPE_UNKNOWN)); // Navigate to URL with refs. - test_rvh()->SendNavigate(1, url_with_ref); + main_test_rfh()->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)); + EXPECT_FALSE(controller.IsURLInPageNavigation(url_with_ref, false, + NAVIGATION_TYPE_UNKNOWN)); + EXPECT_FALSE(controller.IsURLInPageNavigation(url, false, + NAVIGATION_TYPE_UNKNOWN)); + EXPECT_FALSE(controller.IsURLInPageNavigation(other_url, false, + NAVIGATION_TYPE_UNKNOWN)); const GURL other_url_with_ref("http://www.google.com/home.html#my_other_ref"); - EXPECT_TRUE(controller.IsURLInPageNavigation(other_url_with_ref)); + EXPECT_TRUE(controller.IsURLInPageNavigation(other_url_with_ref, true, + NAVIGATION_TYPE_UNKNOWN)); // 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. @@ -2925,6 +3111,17 @@ TEST_F(NavigationControllerTest, IsInPageNavigation) { // type is IN_PAGE. EXPECT_TRUE(controller.IsURLInPageNavigation(url, true, NAVIGATION_TYPE_IN_PAGE)); + + // If the renderer says this is a same-origin in-page navigation, believe it. + // This is the pushState/replaceState case. + EXPECT_TRUE(controller.IsURLInPageNavigation(other_url, true, + NAVIGATION_TYPE_UNKNOWN)); + + // Don't believe the renderer if it claims a cross-origin navigation is + // in-page. + const GURL different_origin_url("http://www.example.com"); + EXPECT_FALSE(controller.IsURLInPageNavigation(different_origin_url, true, + NAVIGATION_TYPE_UNKNOWN)); } // Some pages can have subframes with the same base URL (minus the reference) as @@ -2935,7 +3132,7 @@ TEST_F(NavigationControllerTest, SameSubframe) { NavigationControllerImpl& controller = controller_impl(); // Navigate the main frame. const GURL url("http://www.google.com/"); - test_rvh()->SendNavigate(0, url); + main_test_rfh()->SendNavigate(0, url); // We should be at the first navigation entry. EXPECT_EQ(controller.GetEntryCount(), 1); @@ -2943,7 +3140,7 @@ TEST_F(NavigationControllerTest, SameSubframe) { // Navigate a subframe that would normally count as in-page. const GURL subframe("http://www.google.com/#"); - ViewHostMsg_FrameNavigate_Params params; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = 0; params.url = subframe; params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; @@ -2952,7 +3149,8 @@ TEST_F(NavigationControllerTest, SameSubframe) { params.is_post = false; params.page_state = PageState::CreateFromURL(subframe); LoadCommittedDetails details; - EXPECT_FALSE(controller.RendererDidNavigate(params, &details)); + EXPECT_FALSE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); // Nothing should have changed. EXPECT_EQ(controller.GetEntryCount(), 1); @@ -2965,7 +3163,7 @@ TEST_F(NavigationControllerTest, CloneAndGoBack) { NavigationControllerImpl& controller = controller_impl(); const GURL url1("http://foo1"); const GURL url2("http://foo2"); - const base::string16 title(ASCIIToUTF16("Title")); + const base::string16 title(base::ASCIIToUTF16("Title")); NavigateAndCommit(url1); controller.GetVisibleEntry()->SetTitle(title); @@ -2990,7 +3188,7 @@ TEST_F(NavigationControllerTest, CloneAndReload) { NavigationControllerImpl& controller = controller_impl(); const GURL url1("http://foo1"); const GURL url2("http://foo2"); - const base::string16 title(ASCIIToUTF16("Title")); + const base::string16 title(base::ASCIIToUTF16("Title")); NavigateAndCommit(url1); controller.GetVisibleEntry()->SetTitle(title); @@ -3058,7 +3256,7 @@ TEST_F(NavigationControllerTest, SubframeWhilePending) { // 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; + FrameHostMsg_DidCommitProvisionalLoad_Params params; params.page_id = controller.GetLastCommittedEntry()->GetPageID(); params.url = url1_sub; params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; @@ -3069,7 +3267,8 @@ TEST_F(NavigationControllerTest, SubframeWhilePending) { LoadCommittedDetails details; // This should return false meaning that nothing was actually updated. - EXPECT_FALSE(controller.RendererDidNavigate(params, &details)); + EXPECT_FALSE(controller.RendererDidNavigate(main_test_rfh(), params, + &details)); // The notification should have updated the last committed one, and not // the pending load. @@ -3591,8 +3790,63 @@ TEST_F(NavigationControllerTest, CopyStateFromAndPruneMaxEntriesReplaceEntry) { NavigationControllerImpl::set_max_entry_count_for_testing(original_count); } +// Tests that we can navigate to the restored entries +// imported by CopyStateFromAndPrune. +TEST_F(NavigationControllerTest, CopyRestoredStateAndNavigate) { + const GURL kRestoredUrls[] = { + GURL("http://site1.com"), + GURL("http://site2.com"), + }; + const GURL kInitialUrl("http://site3.com"); + + std::vector<NavigationEntry*> entries; + for (size_t i = 0; i < arraysize(kRestoredUrls); ++i) { + NavigationEntry* entry = NavigationControllerImpl::CreateNavigationEntry( + kRestoredUrls[i], Referrer(), PAGE_TRANSITION_RELOAD, false, + std::string(), browser_context()); + entry->SetPageID(static_cast<int>(i)); + entries.push_back(entry); + } + + // Create a WebContents with restored entries. + scoped_ptr<TestWebContents> source_contents( + static_cast<TestWebContents*>(CreateTestWebContents())); + NavigationControllerImpl& source_controller = + source_contents->GetController(); + source_controller.Restore( + entries.size() - 1, + NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, + &entries); + ASSERT_EQ(0u, entries.size()); + source_controller.LoadIfNecessary(); + source_contents->CommitPendingNavigation(); + + // Load a page, then copy state from |source_contents|. + NavigateAndCommit(kInitialUrl); + contents()->ExpectSetHistoryLengthAndPrune( + GetSiteInstanceFromEntry(controller_impl().GetEntryAtIndex(0)), 2, + controller_impl().GetEntryAtIndex(0)->GetPageID()); + controller_impl().CopyStateFromAndPrune(&source_controller, false); + ASSERT_EQ(3, controller_impl().GetEntryCount()); + + // Go back to the first entry one at a time and + // verify that it works as expected. + EXPECT_EQ(2, controller_impl().GetCurrentEntryIndex()); + EXPECT_EQ(kInitialUrl, controller_impl().GetActiveEntry()->GetURL()); + + controller_impl().GoBack(); + contents()->CommitPendingNavigation(); + EXPECT_EQ(1, controller_impl().GetCurrentEntryIndex()); + EXPECT_EQ(kRestoredUrls[1], controller_impl().GetActiveEntry()->GetURL()); + + controller_impl().GoBack(); + contents()->CommitPendingNavigation(); + EXPECT_EQ(0, controller_impl().GetCurrentEntryIndex()); + EXPECT_EQ(kRestoredUrls[0], controller_impl().GetActiveEntry()->GetURL()); +} + // Tests that navigations initiated from the page (with the history object) -// work as expected without navigation entries. +// work as expected, creating pending entries. TEST_F(NavigationControllerTest, HistoryNavigate) { NavigationControllerImpl& controller = controller_impl(); const GURL url1("http://foo/1"); @@ -3605,38 +3859,39 @@ TEST_F(NavigationControllerTest, HistoryNavigate) { controller.GoBack(); contents()->CommitPendingNavigation(); - // Simulate the page calling history.back(), it should not create a pending - // entry. + // Simulate the page calling history.back(). It should create a pending entry. contents()->OnGoToEntryAtOffset(-1); - EXPECT_EQ(-1, controller.GetPendingEntryIndex()); + EXPECT_EQ(0, 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); + process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID); ASSERT_TRUE(message != NULL); - Tuple1<ViewMsg_Navigate_Params> nav_params; - ViewMsg_Navigate::Read(message, &nav_params); + Tuple1<FrameMsg_Navigate_Params> nav_params; + FrameMsg_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()); + contents()->OnGoToEntryAtOffset(2); + EXPECT_EQ(2, 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); + message = process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID); ASSERT_TRUE(message != NULL); - ViewMsg_Navigate::Read(message, &nav_params); + FrameMsg_Navigate::Read(message, &nav_params); EXPECT_EQ(url3, nav_params.a.url); process()->sink().ClearMessages(); + controller.DiscardNonCommittedEntries(); + // 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); + message = process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID); EXPECT_TRUE(message == NULL); } @@ -3733,7 +3988,7 @@ TEST_F(NavigationControllerTest, PruneAllButLastCommittedForPendingNotInList) { EXPECT_EQ(1, controller.GetEntryCount()); // Try to commit the pending entry. - test_rvh()->SendNavigate(2, url3); + main_test_rfh()->SendNavigate(2, url3); EXPECT_EQ(-1, controller.GetPendingEntryIndex()); EXPECT_FALSE(controller.GetPendingEntry()); EXPECT_EQ(2, controller.GetEntryCount()); @@ -3775,7 +4030,7 @@ TEST_F(NavigationControllerTest, IsInitialNavigation) { // After commit, it stays false. const GURL url1("http://foo1"); - test_rvh()->SendNavigate(0, url1); + main_test_rfh()->SendNavigate(0, url1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; EXPECT_FALSE(controller.IsInitialNavigation()); @@ -3798,7 +4053,7 @@ TEST_F(NavigationControllerTest, ClearFaviconOnRedirect) { TestNotificationTracker notifications; RegisterForAllNavNotifications(¬ifications, &controller); - test_rvh()->SendNavigate(0, kPageWithFavicon); + main_test_rfh()->SendNavigate(0, kPageWithFavicon); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -3813,7 +4068,7 @@ TEST_F(NavigationControllerTest, ClearFaviconOnRedirect) { favicon_status.valid = true; EXPECT_FALSE(DoImagesMatch(kDefaultFavicon, entry->GetFavicon().image)); - test_rvh()->SendNavigateWithTransition( + main_test_rfh()->SendNavigateWithTransition( 0, // same page ID. kPageWithoutFavicon, PAGE_TRANSITION_CLIENT_REDIRECT); @@ -3838,7 +4093,7 @@ TEST_F(NavigationControllerTest, BackNavigationDoesNotClearFavicon) { TestNotificationTracker notifications; RegisterForAllNavNotifications(¬ifications, &controller); - test_rvh()->SendNavigate(0, kUrl1); + main_test_rfh()->SendNavigate(0, kUrl1); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; @@ -3852,10 +4107,10 @@ TEST_F(NavigationControllerTest, BackNavigationDoesNotClearFavicon) { favicon_status.valid = true; // Navigate to another page and go back to the original page. - test_rvh()->SendNavigate(1, kUrl2); + main_test_rfh()->SendNavigate(1, kUrl2); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; - test_rvh()->SendNavigateWithTransition( + main_test_rfh()->SendNavigateWithTransition( 0, kUrl1, PAGE_TRANSITION_FORWARD_BACK); @@ -3965,6 +4220,30 @@ TEST_F(NavigationControllerTest, MAYBE_PurgeScreenshot) { } } +TEST_F(NavigationControllerTest, PushStateUpdatesTitle) { + + // Navigate + test_rvh()->SendNavigate(1, GURL("http://foo")); + + // Set title + base::string16 title(base::ASCIIToUTF16("Title")); + controller().GetLastCommittedEntry()->SetTitle(title); + + // history.pushState() is called. + FrameHostMsg_DidCommitProvisionalLoad_Params params; + GURL url("http://foo#foo"); + params.page_id = 2; + params.url = url; + params.page_state = PageState::CreateFromURL(url); + params.was_within_same_page = true; + test_rvh()->SendNavigateWithParams(¶ms); + + // The title should immediately be visible on the new NavigationEntry. + base::string16 new_title = + controller().GetLastCommittedEntry()->GetTitleForDisplay(std::string()); + EXPECT_EQ(title, new_title); +} + // Test that the navigation controller clears its session history when a // navigation commits with the clear history list flag set. TEST_F(NavigationControllerTest, ClearHistoryList) { @@ -4014,4 +4293,40 @@ TEST_F(NavigationControllerTest, ClearHistoryList) { EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL()); } +TEST_F(NavigationControllerTest, PostThenReplaceStateThenReload) { + scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate()); + EXPECT_FALSE(contents()->GetDelegate()); + contents()->SetDelegate(delegate.get()); + + // Submit a form. + GURL url("http://foo"); + FrameHostMsg_DidCommitProvisionalLoad_Params params; + params.page_id = 1; + params.url = url; + params.transition = PAGE_TRANSITION_FORM_SUBMIT; + params.gesture = NavigationGestureUser; + params.page_state = PageState::CreateFromURL(url); + params.was_within_same_page = false; + params.is_post = true; + params.post_id = 2; + test_rvh()->SendNavigateWithParams(¶ms); + + // history.replaceState() is called. + GURL replace_url("http://foo#foo"); + params.page_id = 1; + params.url = replace_url; + params.transition = PAGE_TRANSITION_LINK; + params.gesture = NavigationGestureUser; + params.page_state = PageState::CreateFromURL(replace_url); + params.was_within_same_page = true; + params.is_post = false; + params.post_id = -1; + test_rvh()->SendNavigateWithParams(¶ms); + + // Now reload. replaceState overrides the POST, so we should not show a + // repost warning dialog. + controller_impl().Reload(true); + EXPECT_EQ(0, delegate->repost_form_warning_count()); +} + } // namespace content |