Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / frame_host / navigation_controller_impl_unittest.cc
index 70f447e..1a8c8a9 100644 (file)
@@ -81,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();
@@ -1046,7 +1046,7 @@ TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) {
   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.
@@ -1320,13 +1320,11 @@ 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());
 
   main_test_rfh()->SendNavigate(0, url1);
@@ -1341,10 +1339,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();
@@ -2864,16 +2887,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(&notifications, &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(&notifications, &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());
 
@@ -2900,7 +3024,7 @@ 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.
   main_test_rfh()->SendNavigate(0, url1);
@@ -2911,7 +3035,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());
@@ -3621,6 +3745,61 @@ 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, creating pending entries.
 TEST_F(NavigationControllerTest, HistoryNavigate) {