Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(676)

Side by Side Diff: content/browser/web_contents/navigation_controller_impl_unittest.cc

Issue 13846007: Allow showing pending URL for new tab navigations, but only if safe. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/basictypes.h" 5 #include "base/basictypes.h"
6 #include "base/bind.h" 6 #include "base/bind.h"
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/path_service.h" 9 #include "base/path_service.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 TEST_F(NavigationControllerTest, LoadURL_AbortDoesntCancelPending) { 805 TEST_F(NavigationControllerTest, LoadURL_AbortDoesntCancelPending) {
806 NavigationControllerImpl& controller = controller_impl(); 806 NavigationControllerImpl& controller = controller_impl();
807 TestNotificationTracker notifications; 807 TestNotificationTracker notifications;
808 RegisterForAllNavNotifications(&notifications, &controller); 808 RegisterForAllNavNotifications(&notifications, &controller);
809 809
810 // Set a WebContentsDelegate to listen for state changes. 810 // Set a WebContentsDelegate to listen for state changes.
811 scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate()); 811 scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate());
812 EXPECT_FALSE(contents()->GetDelegate()); 812 EXPECT_FALSE(contents()->GetDelegate());
813 contents()->SetDelegate(delegate.get()); 813 contents()->SetDelegate(delegate.get());
814 814
815 // Without any navigations, the renderer starts at about:blank. 815 // Start with a pending new navigation.
816 const GURL kExistingURL("about:blank");
817
818 // Now make a pending new navigation.
819 const GURL kNewURL("http://eh"); 816 const GURL kNewURL("http://eh");
820 controller.LoadURL( 817 controller.LoadURL(
821 kNewURL, Referrer(), PAGE_TRANSITION_TYPED, std::string()); 818 kNewURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
822 EXPECT_EQ(0U, notifications.size()); 819 EXPECT_EQ(0U, notifications.size());
823 EXPECT_EQ(-1, controller.GetPendingEntryIndex()); 820 EXPECT_EQ(-1, controller.GetPendingEntryIndex());
824 EXPECT_TRUE(controller.GetPendingEntry()); 821 EXPECT_TRUE(controller.GetPendingEntry());
825 EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex()); 822 EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
826 EXPECT_EQ(1, delegate->navigation_state_change_count()); 823 EXPECT_EQ(1, delegate->navigation_state_change_count());
827 824
828 // It may abort before committing, if it's a download or due to a stop or 825 // It may abort before committing, if it's a download or due to a stop or
829 // a new navigation from the user. 826 // a new navigation from the user.
830 ViewHostMsg_DidFailProvisionalLoadWithError_Params params; 827 ViewHostMsg_DidFailProvisionalLoadWithError_Params params;
831 params.frame_id = 1; 828 params.frame_id = 1;
832 params.is_main_frame = true; 829 params.is_main_frame = true;
833 params.error_code = net::ERR_ABORTED; 830 params.error_code = net::ERR_ABORTED;
834 params.error_description = string16(); 831 params.error_description = string16();
835 params.url = kNewURL; 832 params.url = kNewURL;
836 params.showing_repost_interstitial = false; 833 params.showing_repost_interstitial = false;
837 test_rvh()->OnMessageReceived( 834 test_rvh()->OnMessageReceived(
838 ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id 835 ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id
839 params)); 836 params));
840 837
841 // This should not clear the pending entry or notify of a navigation state 838 // This should not clear the pending entry or notify of a navigation state
842 // change, so that we keep displaying kNewURL (until the user clears it). 839 // change, so that we keep displaying kNewURL (until the user clears it).
843 EXPECT_EQ(-1, controller.GetPendingEntryIndex()); 840 EXPECT_EQ(-1, controller.GetPendingEntryIndex());
844 EXPECT_TRUE(controller.GetPendingEntry()); 841 EXPECT_TRUE(controller.GetPendingEntry());
845 EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex()); 842 EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
846 EXPECT_EQ(1, delegate->navigation_state_change_count()); 843 EXPECT_EQ(1, delegate->navigation_state_change_count());
844 NavigationEntry* pending_entry = controller.GetPendingEntry();
845
846 // Ensure that a reload keeps the same pending entry.
847 controller.Reload(true);
848 EXPECT_EQ(-1, controller.GetPendingEntryIndex());
849 EXPECT_TRUE(controller.GetPendingEntry());
850 EXPECT_EQ(pending_entry, controller.GetPendingEntry());
851 EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
847 852
848 contents()->SetDelegate(NULL); 853 contents()->SetDelegate(NULL);
849 } 854 }
850 855
851 // Tests that the pending URL is not visible during a renderer-initiated 856 // Tests that the pending URL is not visible during a renderer-initiated
852 // redirect and abort. See http://crbug.com/83031. 857 // redirect and abort. See http://crbug.com/83031.
853 TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) { 858 TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) {
854 NavigationControllerImpl& controller = controller_impl(); 859 NavigationControllerImpl& controller = controller_impl();
855 TestNotificationTracker notifications; 860 TestNotificationTracker notifications;
856 RegisterForAllNavNotifications(&notifications, &controller); 861 RegisterForAllNavNotifications(&notifications, &controller);
857 862
863 // First make an existing committed entry.
864 const GURL kExistingURL("http://foo/eh");
865 controller.LoadURL(kExistingURL, content::Referrer(),
866 content::PAGE_TRANSITION_TYPED, std::string());
867 test_rvh()->SendNavigate(0, kExistingURL);
868 EXPECT_TRUE(notifications.Check1AndReset(
869 content::NOTIFICATION_NAV_ENTRY_COMMITTED));
870
858 // Set a WebContentsDelegate to listen for state changes. 871 // Set a WebContentsDelegate to listen for state changes.
859 scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate()); 872 scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate());
860 EXPECT_FALSE(contents()->GetDelegate()); 873 EXPECT_FALSE(contents()->GetDelegate());
861 contents()->SetDelegate(delegate.get()); 874 contents()->SetDelegate(delegate.get());
862 875
863 // Without any navigations, the renderer starts at about:blank.
864 const GURL kExistingURL("about:blank");
865
866 // Now make a pending new navigation, initiated by the renderer. 876 // Now make a pending new navigation, initiated by the renderer.
867 const GURL kNewURL("http://eh"); 877 const GURL kNewURL("http://foo/bee");
868 NavigationController::LoadURLParams load_url_params(kNewURL); 878 NavigationController::LoadURLParams load_url_params(kNewURL);
869 load_url_params.transition_type = PAGE_TRANSITION_TYPED; 879 load_url_params.transition_type = PAGE_TRANSITION_TYPED;
870 load_url_params.is_renderer_initiated = true; 880 load_url_params.is_renderer_initiated = true;
871 controller.LoadURLWithParams(load_url_params); 881 controller.LoadURLWithParams(load_url_params);
872 EXPECT_EQ(0U, notifications.size()); 882 EXPECT_EQ(0U, notifications.size());
873 EXPECT_EQ(-1, controller.GetPendingEntryIndex()); 883 EXPECT_EQ(-1, controller.GetPendingEntryIndex());
874 EXPECT_TRUE(controller.GetPendingEntry()); 884 EXPECT_TRUE(controller.GetPendingEntry());
875 EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex()); 885 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
876 EXPECT_EQ(1, delegate->navigation_state_change_count()); 886 EXPECT_EQ(0, delegate->navigation_state_change_count());
877 887
878 // There should be no visible entry (resulting in about:blank in the 888 // The visible entry should be the last committed URL, not the pending one.
879 // omnibox), because it was renderer-initiated and there's no last committed 889 EXPECT_EQ(kExistingURL, controller.GetVisibleEntry()->GetURL());
880 // entry.
881 EXPECT_FALSE(controller.GetVisibleEntry());
882 890
883 // Now the navigation redirects. 891 // Now the navigation redirects.
884 const GURL kRedirectURL("http://bee"); 892 const GURL kRedirectURL("http://foo/see");
885 test_rvh()->OnMessageReceived( 893 test_rvh()->OnMessageReceived(
886 ViewHostMsg_DidRedirectProvisionalLoad(0, // routing_id 894 ViewHostMsg_DidRedirectProvisionalLoad(0, // routing_id
887 -1, // pending page_id 895 -1, // pending page_id
888 kNewURL, // old url 896 kNewURL, // old url
889 kRedirectURL)); // new url 897 kRedirectURL)); // new url
890 898
891 // We don't want to change the NavigationEntry's url, in case it cancels. 899 // We don't want to change the NavigationEntry's url, in case it cancels.
892 // Prevents regression of http://crbug.com/77786. 900 // Prevents regression of http://crbug.com/77786.
893 EXPECT_EQ(kNewURL, controller.GetPendingEntry()->GetURL()); 901 EXPECT_EQ(kNewURL, controller.GetPendingEntry()->GetURL());
894 902
895 // It may abort before committing, if it's a download or due to a stop or 903 // It may abort before committing, if it's a download or due to a stop or
896 // a new navigation from the user. 904 // a new navigation from the user.
897 ViewHostMsg_DidFailProvisionalLoadWithError_Params params; 905 ViewHostMsg_DidFailProvisionalLoadWithError_Params params;
898 params.frame_id = 1; 906 params.frame_id = 1;
899 params.is_main_frame = true; 907 params.is_main_frame = true;
900 params.error_code = net::ERR_ABORTED; 908 params.error_code = net::ERR_ABORTED;
901 params.error_description = string16(); 909 params.error_description = string16();
902 params.url = kRedirectURL; 910 params.url = kRedirectURL;
903 params.showing_repost_interstitial = false; 911 params.showing_repost_interstitial = false;
904 test_rvh()->OnMessageReceived( 912 test_rvh()->OnMessageReceived(
905 ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id 913 ViewHostMsg_DidFailProvisionalLoadWithError(0, // routing_id
906 params)); 914 params));
907 915
908 // This should not clear the pending entry or notify of a navigation state 916 // This should not clear the pending entry or notify of a navigation state
909 // change. 917 // change.
910 EXPECT_EQ(-1, controller.GetPendingEntryIndex()); 918 EXPECT_EQ(-1, controller.GetPendingEntryIndex());
911 EXPECT_TRUE(controller.GetPendingEntry()); 919 EXPECT_TRUE(controller.GetPendingEntry());
912 EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex()); 920 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
913 EXPECT_EQ(1, delegate->navigation_state_change_count()); 921 EXPECT_EQ(0, delegate->navigation_state_change_count());
914 922
915 // There should be no visible entry (resulting in about:blank in the 923 // The visible entry should be the last committed URL, not the pending one,
916 // omnibox), ensuring no spoof is possible. 924 // so that no spoof is possible.
917 EXPECT_FALSE(controller.GetVisibleEntry()); 925 EXPECT_EQ(kExistingURL, controller.GetVisibleEntry()->GetURL());
918 926
919 contents()->SetDelegate(NULL); 927 contents()->SetDelegate(NULL);
920 } 928 }
921 929
922 // Ensure that NavigationEntries track which bindings their RenderViewHost had 930 // Ensure that NavigationEntries track which bindings their RenderViewHost had
923 // at the time they committed. http://crbug.com/173672. 931 // at the time they committed. http://crbug.com/173672.
924 TEST_F(NavigationControllerTest, LoadURL_WithBindings) { 932 TEST_F(NavigationControllerTest, LoadURL_WithBindings) {
925 NavigationControllerImpl& controller = controller_impl(); 933 NavigationControllerImpl& controller = controller_impl();
926 TestNotificationTracker notifications; 934 TestNotificationTracker notifications;
927 RegisterForAllNavNotifications(&notifications, &controller); 935 RegisterForAllNavNotifications(&notifications, &controller);
(...skipping 1556 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 test_rvh()->SendNavigate(1, url1); 2492 test_rvh()->SendNavigate(1, url1);
2485 EXPECT_EQ(url1, controller.GetActiveEntry()->GetURL()); 2493 EXPECT_EQ(url1, controller.GetActiveEntry()->GetURL());
2486 EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL()); 2494 EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
2487 EXPECT_FALSE( 2495 EXPECT_FALSE(
2488 NavigationEntryImpl::FromNavigationEntry( 2496 NavigationEntryImpl::FromNavigationEntry(
2489 controller.GetLastCommittedEntry())->is_renderer_initiated()); 2497 controller.GetLastCommittedEntry())->is_renderer_initiated());
2490 2498
2491 notifications.Reset(); 2499 notifications.Reset();
2492 } 2500 }
2493 2501
2502 // Tests that the URLs for renderer-initiated navigations in new tabs are
2503 // displayed to the user before commit, as long as the initial about:blank
2504 // page has not been modified. If so, we must revert to showing about:blank.
2505 // See http://crbug.com/9682.
2506 TEST_F(NavigationControllerTest, ShowRendererURLInNewTabUntilModified) {
2507 NavigationControllerImpl& controller = controller_impl();
2508 TestNotificationTracker notifications;
2509 RegisterForAllNavNotifications(&notifications, &controller);
2510
2511 const GURL url("http://foo");
2512
2513 // For renderer-initiated navigations in new tabs (with no committed entries),
2514 // we show the pending entry's URL as long as the about:blank page is not
2515 // modified.
2516 NavigationController::LoadURLParams load_url_params(url);
2517 load_url_params.transition_type = PAGE_TRANSITION_LINK;
2518 load_url_params.is_renderer_initiated = true;
2519 controller.LoadURLWithParams(load_url_params);
2520 EXPECT_EQ(url, controller.GetActiveEntry()->GetURL());
2521 EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL());
2522 EXPECT_TRUE(
2523 NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
2524 is_renderer_initiated());
2525 EXPECT_TRUE(controller.IsInitialNavigation());
2526 EXPECT_FALSE(test_rvh()->has_accessed_initial_document());
2527
2528 // There should be no title yet.
2529 EXPECT_TRUE(contents()->GetTitle().empty());
2530
2531 // If something else modifies the contents of the about:blank page, then
2532 // we must revert to showing about:blank to avoid a URL spoof.
2533 test_rvh()->OnMessageReceived(
2534 ViewHostMsg_DidAccessInitialDocument(0));
2535 EXPECT_TRUE(test_rvh()->has_accessed_initial_document());
2536 EXPECT_FALSE(controller.GetVisibleEntry());
2537 EXPECT_EQ(url, controller.GetActiveEntry()->GetURL());
2538
2539 notifications.Reset();
2540 }
2541
2542 TEST_F(NavigationControllerTest, DontShowRendererURLInNewTabAfterCommit) {
2543 NavigationControllerImpl& controller = controller_impl();
2544 TestNotificationTracker notifications;
2545 RegisterForAllNavNotifications(&notifications, &controller);
2546
2547 const GURL url1("http://foo/eh");
2548 const GURL url2("http://foo/bee");
2549
2550 // For renderer-initiated navigations in new tabs (with no committed entries),
2551 // we show the pending entry's URL as long as the about:blank page is not
2552 // modified.
2553 NavigationController::LoadURLParams load_url_params(url1);
2554 load_url_params.transition_type = PAGE_TRANSITION_LINK;
2555 load_url_params.is_renderer_initiated = true;
2556 controller.LoadURLWithParams(load_url_params);
2557 EXPECT_EQ(url1, controller.GetActiveEntry()->GetURL());
2558 EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
2559 EXPECT_TRUE(
2560 NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
2561 is_renderer_initiated());
2562 EXPECT_TRUE(controller.IsInitialNavigation());
2563 EXPECT_FALSE(test_rvh()->has_accessed_initial_document());
2564
2565 // Simulate a commit and then starting a new pending navigation.
2566 test_rvh()->SendNavigate(0, url1);
2567 NavigationController::LoadURLParams load_url2_params(url2);
2568 load_url2_params.transition_type = PAGE_TRANSITION_LINK;
2569 load_url2_params.is_renderer_initiated = true;
2570 controller.LoadURLWithParams(load_url2_params);
2571
2572 // We should not consider this an initial navigation, and thus should
2573 // not show the pending URL.
2574 EXPECT_FALSE(test_rvh()->has_accessed_initial_document());
2575 EXPECT_FALSE(controller.IsInitialNavigation());
2576 EXPECT_TRUE(controller.GetVisibleEntry());
2577 EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
2578
2579 notifications.Reset();
2580 }
2581
2494 // Tests that IsInPageNavigation returns appropriate results. Prevents 2582 // Tests that IsInPageNavigation returns appropriate results. Prevents
2495 // regression for bug 1126349. 2583 // regression for bug 1126349.
2496 TEST_F(NavigationControllerTest, IsInPageNavigation) { 2584 TEST_F(NavigationControllerTest, IsInPageNavigation) {
2497 NavigationControllerImpl& controller = controller_impl(); 2585 NavigationControllerImpl& controller = controller_impl();
2498 // Navigate to URL with no refs. 2586 // Navigate to URL with no refs.
2499 const GURL url("http://www.google.com/home.html"); 2587 const GURL url("http://www.google.com/home.html");
2500 test_rvh()->SendNavigate(0, url); 2588 test_rvh()->SendNavigate(0, url);
2501 2589
2502 // Reloading the page is not an in-page navigation. 2590 // Reloading the page is not an in-page navigation.
2503 EXPECT_FALSE(controller.IsURLInPageNavigation(url)); 2591 EXPECT_FALSE(controller.IsURLInPageNavigation(url));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2549 EXPECT_EQ(controller.GetEntryCount(), 1); 2637 EXPECT_EQ(controller.GetEntryCount(), 1);
2550 EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); 2638 EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
2551 } 2639 }
2552 2640
2553 // Make sure that on cloning a WebContentsImpl and going back needs_reload is 2641 // Make sure that on cloning a WebContentsImpl and going back needs_reload is
2554 // false. 2642 // false.
2555 TEST_F(NavigationControllerTest, CloneAndGoBack) { 2643 TEST_F(NavigationControllerTest, CloneAndGoBack) {
2556 NavigationControllerImpl& controller = controller_impl(); 2644 NavigationControllerImpl& controller = controller_impl();
2557 const GURL url1("http://foo1"); 2645 const GURL url1("http://foo1");
2558 const GURL url2("http://foo2"); 2646 const GURL url2("http://foo2");
2647 const string16 title(ASCIIToUTF16("Title"));
2559 2648
2560 NavigateAndCommit(url1); 2649 NavigateAndCommit(url1);
2650 controller.GetActiveEntry()->SetTitle(title);
2561 NavigateAndCommit(url2); 2651 NavigateAndCommit(url2);
2562 2652
2563 scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone()); 2653 scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone());
2564 2654
2565 ASSERT_EQ(2, clone->GetController().GetEntryCount()); 2655 ASSERT_EQ(2, clone->GetController().GetEntryCount());
2566 EXPECT_TRUE(clone->GetController().NeedsReload()); 2656 EXPECT_TRUE(clone->GetController().NeedsReload());
2567 clone->GetController().GoBack(); 2657 clone->GetController().GoBack();
2568 // Navigating back should have triggered needs_reload_ to go false. 2658 // Navigating back should have triggered needs_reload_ to go false.
2569 EXPECT_FALSE(clone->GetController().NeedsReload()); 2659 EXPECT_FALSE(clone->GetController().NeedsReload());
2660
2661 // Ensure that the pending URL and its title are visible.
2662 EXPECT_EQ(url1, clone->GetController().GetVisibleEntry()->GetURL());
2663 EXPECT_EQ(title, clone->GetTitle());
2570 } 2664 }
2571 2665
2572 // Make sure that cloning a WebContentsImpl doesn't copy interstitials. 2666 // Make sure that cloning a WebContentsImpl doesn't copy interstitials.
2573 TEST_F(NavigationControllerTest, CloneOmitsInterstitials) { 2667 TEST_F(NavigationControllerTest, CloneOmitsInterstitials) {
2574 NavigationControllerImpl& controller = controller_impl(); 2668 NavigationControllerImpl& controller = controller_impl();
2575 const GURL url1("http://foo1"); 2669 const GURL url1("http://foo1");
2576 const GURL url2("http://foo2"); 2670 const GURL url2("http://foo2");
2577 2671
2578 NavigateAndCommit(url1); 2672 NavigateAndCommit(url1);
2579 NavigateAndCommit(url2); 2673 NavigateAndCommit(url2);
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
3446 PAGE_TRANSITION_LINK); 3540 PAGE_TRANSITION_LINK);
3447 session_helper_.AssertNavigationEquals(nav, 3541 session_helper_.AssertNavigationEquals(nav,
3448 windows_[0]->tabs[0]->navigations[0]); 3542 windows_[0]->tabs[0]->navigations[0]);
3449 nav.set_url(url2); 3543 nav.set_url(url2);
3450 session_helper_.AssertNavigationEquals(nav, 3544 session_helper_.AssertNavigationEquals(nav,
3451 windows_[0]->tabs[0]->navigations[1]); 3545 windows_[0]->tabs[0]->navigations[1]);
3452 } 3546 }
3453 */ 3547 */
3454 3548
3455 } // namespace content 3549 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/web_contents/navigation_controller_impl.cc ('k') | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698