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

Unified Diff: content/browser/frame_host/render_frame_host_manager_unittest.cc

Issue 1472703004: Reland #2 of: Move WebUI ownership from the RenderFrameHostManager to the RenderFrameHost. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Test shared code now uses lambda functions. More comments. Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/frame_host/render_frame_host_manager_unittest.cc
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index 1ac1b088f2b653cfb57d5bdb268ab8d7b6ba5b2a..8c157958e09a419cd9cc30454cbc74fee1cfe436 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -38,6 +38,7 @@
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_notification_tracker.h"
#include "content/public/test/test_utils.h"
+#include "content/test/browser_side_navigation_test_utils.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
#include "content/test/test_render_frame_host.h"
@@ -70,7 +71,8 @@ class RenderFrameHostManagerTestWebUIControllerFactory
: public WebUIControllerFactory {
public:
RenderFrameHostManagerTestWebUIControllerFactory()
- : should_create_webui_(false) {
+ : should_create_webui_(false), type_(1) {
+ CHECK_NE(reinterpret_cast<WebUI::TypeID>(type_), WebUI::kNoWebUI);
}
~RenderFrameHostManagerTestWebUIControllerFactory() override {}
@@ -78,16 +80,34 @@ class RenderFrameHostManagerTestWebUIControllerFactory
should_create_webui_ = should_create_webui;
}
+ // This method simulates the expectation that different WebUI instance types
+ // would be created. The |type| value will be returned by GetWebUIType casted
+ // to WebUI::TypeID.
+ // As WebUI::TypeID is a typedef to void pointer, factory implementations
+ // return values that they know to be unique to their respective cases. So
+ // values set here should be safe if kept very low (just above zero).
+ void set_webui_type(uintptr_t type) {
+ CHECK_NE(reinterpret_cast<WebUI::TypeID>(type), WebUI::kNoWebUI);
+ type_ = type;
+ }
+
// WebUIFactory implementation.
WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
const GURL& url) const override {
- if (!(should_create_webui_ && HasWebUIScheme(url)))
- return NULL;
- return new WebUIController(web_ui);
+ // If WebUI creation is enabled for the test and this is a WebUI URL,
+ // returns a new instance.
+ if (should_create_webui_ && HasWebUIScheme(url))
+ return new WebUIController(web_ui);
+ return nullptr;
}
WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
const GURL& url) const override {
+ // If WebUI creation is enabled for the test and this is a WebUI URL,
+ // returns a mock WebUI type.
+ if (should_create_webui_ && HasWebUIScheme(url)) {
+ return reinterpret_cast<WebUI::TypeID>(type_);
+ }
return WebUI::kNoWebUI;
}
@@ -103,6 +123,7 @@ class RenderFrameHostManagerTestWebUIControllerFactory
private:
bool should_create_webui_;
+ uintptr_t type_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameHostManagerTestWebUIControllerFactory);
};
@@ -280,6 +301,8 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
factory_.set_should_create_webui(should_create_webui);
}
+ void set_webui_type(int type) { factory_.set_webui_type(type); }
+
void NavigateActiveAndCommit(const GURL& url) {
// Note: we navigate the active RenderFrameHost because previous navigations
// won't have committed yet, so NavigateAndCommit does the wrong thing
@@ -411,12 +434,28 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get();
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBrowserSideNavigation)) {
+ NavigationControllerImpl* controller =
+ static_cast<NavigationControllerImpl*>(manager->current_frame_host()
+ ->frame_tree_node()
+ ->navigator()
+ ->GetController());
+ // TODO(carlosk): This implementation below will not work with restore
+ // navigations. Method GetNavigationType should be exposed from
+ // navigator_impl.cc and used here to determine FrameMsg_Navigate_Type.
+ CHECK(entry.restore_type() == NavigationEntryImpl::RESTORE_NONE);
scoped_ptr<NavigationRequest> navigation_request =
NavigationRequest::CreateBrowserInitiated(
manager->frame_tree_node_, frame_entry->url(),
frame_entry->referrer(), *frame_entry, entry,
FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(),
- static_cast<NavigationControllerImpl*>(&controller()));
+ controller);
+
+ // Simulates request creation that triggers the 1st internal call to
+ // GetFrameHostForNavigation.
+ manager->DidCreateNavigationRequest(*navigation_request);
+
+ // And also simulates the 2nd and final call to GetFrameHostForNavigation
+ // that determines the final frame that will commit the navigation.
TestRenderFrameHost* frame_host = static_cast<TestRenderFrameHost*>(
manager->GetFrameHostForNavigation(*navigation_request));
CHECK(frame_host);
@@ -447,6 +486,19 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
nodes_with_back_links);
}
+ void BaseSimultaneousNavigationWithOneWebUI(
+ const std::function<void(RenderFrameHostImpl*,
+ RenderFrameHostImpl*,
+ WebUIImpl*,
+ RenderFrameHostManager*)>& commit_lambda);
+
+ void BaseSimultaneousNavigationWithTwoWebUIs(
+ const std::function<void(RenderFrameHostImpl*,
+ RenderFrameHostImpl*,
+ WebUIImpl*,
+ WebUIImpl*,
+ RenderFrameHostManager*)>& commit_lambda);
+
private:
RenderFrameHostManagerTestWebUIControllerFactory factory_;
};
@@ -1089,7 +1141,7 @@ TEST_F(RenderFrameHostManagerTest, WebUI) {
RenderFrameHostImpl* initial_rfh = manager->current_frame_host();
EXPECT_FALSE(manager->current_host()->IsRenderViewLive());
- EXPECT_FALSE(manager->web_ui());
+ EXPECT_FALSE(manager->current_frame_host()->web_ui());
EXPECT_TRUE(initial_rfh);
const GURL kUrl("chrome://foo");
@@ -1118,11 +1170,17 @@ TEST_F(RenderFrameHostManagerTest, WebUI) {
// used yet. UpdateStateForNavigate() took the short cut path.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBrowserSideNavigation)) {
- EXPECT_FALSE(manager->speculative_web_ui());
+ // In PlzNavigate, there will be a navigating WebUI because
+ // GetFrameHostForNavigation was already called twice and the committed
+ // WebUI should be set to be reused.
+ EXPECT_TRUE(manager->GetNavigatingWebUI());
+ EXPECT_EQ(host->web_ui(), manager->GetNavigatingWebUI());
+ EXPECT_EQ(host->web_ui(), host->pending_web_ui());
} else {
- EXPECT_FALSE(manager->pending_web_ui());
+ // The WebUI was immediately committed and there should be none navigating.
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
}
- EXPECT_TRUE(manager->web_ui());
+ EXPECT_TRUE(manager->current_frame_host()->web_ui());
// Commit.
manager->DidNavigateFrame(host, true);
@@ -1191,12 +1249,8 @@ TEST_F(RenderFrameHostManagerTest, WebUIInNewTab) {
// No cross-process transition happens because we are already in the right
// SiteInstance. We should grant bindings immediately.
EXPECT_EQ(host2, manager2->current_frame_host());
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
- EXPECT_TRUE(manager2->speculative_web_ui());
- } else {
- EXPECT_TRUE(manager2->pending_web_ui());
- }
+ EXPECT_TRUE(manager2->GetNavigatingWebUI());
+ EXPECT_FALSE(host2->web_ui());
EXPECT_TRUE(
host2->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
@@ -1210,16 +1264,14 @@ TEST_F(RenderFrameHostManagerTest, WebUIWasReused) {
// Navigate to a WebUI page.
const GURL kUrl1("chrome://foo");
contents()->NavigateAndCommit(kUrl1);
- RenderFrameHostManager* manager =
- main_test_rfh()->frame_tree_node()->render_manager();
- WebUIImpl* web_ui = manager->web_ui();
+ WebUIImpl* web_ui = main_test_rfh()->web_ui();
EXPECT_TRUE(web_ui);
// Navigate to another WebUI page which should be same-site and keep the
// current WebUI.
const GURL kUrl2("chrome://foo/bar");
contents()->NavigateAndCommit(kUrl2);
- EXPECT_EQ(web_ui, manager->web_ui());
+ EXPECT_EQ(web_ui, main_test_rfh()->web_ui());
}
// Tests that a WebUI is correctly cleaned up when navigating from a chrome://
@@ -1230,12 +1282,12 @@ TEST_F(RenderFrameHostManagerTest, WebUIWasCleared) {
// Navigate to a WebUI page.
const GURL kUrl1("chrome://foo");
contents()->NavigateAndCommit(kUrl1);
- EXPECT_TRUE(main_test_rfh()->frame_tree_node()->render_manager()->web_ui());
+ EXPECT_TRUE(main_test_rfh()->web_ui());
// Navigate to a non-WebUI page.
const GURL kUrl2("http://www.google.com");
contents()->NavigateAndCommit(kUrl2);
- EXPECT_FALSE(main_test_rfh()->frame_tree_node()->render_manager()->web_ui());
+ EXPECT_FALSE(main_test_rfh()->web_ui());
}
// Tests that we don't end up in an inconsistent state if a page does a back and
@@ -2662,4 +2714,433 @@ TEST_F(RenderFrameHostManagerTest,
VerifyPageFocusMessage(hostC->GetProcess(), true, proxy->GetRoutingID());
}
+// Checks that a restore navigation to a WebUI works.
+TEST_F(RenderFrameHostManagerTest, RestoreNavigationToWebUI) {
+ set_should_create_webui(true);
+
+ const GURL kInitUrl("chrome://foo/");
+ SiteInstanceImpl* initial_instance =
+ static_cast<SiteInstanceImpl*>(SiteInstance::Create(browser_context()));
+ initial_instance->SetSite(kInitUrl);
+ scoped_ptr<TestWebContents> web_contents(
+ TestWebContents::Create(browser_context(), initial_instance));
+ RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
+ NavigationControllerImpl& controller = web_contents->GetController();
+
+ // Setup a restored entry.
+ std::vector<scoped_ptr<NavigationEntry>> entries;
+ scoped_ptr<NavigationEntry> new_entry =
+ NavigationControllerImpl::CreateNavigationEntry(
+ kInitUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, false, std::string(),
+ browser_context());
+ new_entry->SetPageID(0);
+ entries.push_back(new_entry.Pass());
+ controller.Restore(
+ 0, NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries);
+ ASSERT_EQ(0u, entries.size());
+ ASSERT_EQ(1, controller.GetEntryCount());
+
+ RenderFrameHostImpl* initial_host = manager->current_frame_host();
+ ASSERT_TRUE(initial_host);
+ EXPECT_FALSE(initial_host->IsRenderFrameLive());
+ EXPECT_FALSE(initial_host->web_ui());
+
+ // Navigation request to an entry from a previous browsing session.
+ NavigationEntryImpl entry(nullptr /* instance */, 0 /* page_id */, kInitUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_RELOAD,
+ false /* is_renderer_init */);
+ entry.set_restore_type(
+ NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY);
+ NavigateToEntry(manager, entry);
+
+ // As the initial renderer was not live, the new RenderFrameHost should be
+ // made immediately active at request time.
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ TestRenderFrameHost* current_host =
+ static_cast<TestRenderFrameHost*>(manager->current_frame_host());
+ ASSERT_TRUE(current_host);
+ EXPECT_EQ(current_host, initial_host);
+ EXPECT_TRUE(current_host->IsRenderFrameLive());
+ WebUIImpl* web_ui = manager->GetNavigatingWebUI();
+ EXPECT_TRUE(web_ui);
+ EXPECT_EQ(web_ui, current_host->pending_web_ui());
+ EXPECT_FALSE(current_host->web_ui());
+
+ // The RenderFrameHost committed.
+ manager->DidNavigateFrame(current_host, true);
+ EXPECT_EQ(current_host, manager->current_frame_host());
+ EXPECT_EQ(web_ui, current_host->web_ui());
+ EXPECT_FALSE(current_host->pending_web_ui());
+}
+
+// Shared code until before commit for the SimultaneousNavigationWithOneWebUI*
+// tests, accepting a lambda to execute the commit step.
+void RenderFrameHostManagerTest::BaseSimultaneousNavigationWithOneWebUI(
+ const std::function<void(RenderFrameHostImpl*,
+ RenderFrameHostImpl*,
+ WebUIImpl*,
+ RenderFrameHostManager*)>& commit_lambda) {
+ set_should_create_webui(true);
+ NavigateActiveAndCommit(GURL("chrome://foo/"));
+
+ RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
+ RenderFrameHostImpl* host1 = manager->current_frame_host();
+ EXPECT_TRUE(host1->IsRenderFrameLive());
+ WebUIImpl* web_ui = host1->web_ui();
+ EXPECT_TRUE(web_ui);
+
+ // Starts a reload of the WebUI page.
+ contents()->GetController().Reload(true);
+
+ // It should be a same-site navigation reusing the same WebUI.
+ EXPECT_EQ(web_ui, manager->GetNavigatingWebUI());
+ EXPECT_EQ(web_ui, host1->web_ui());
+ EXPECT_EQ(web_ui, host1->pending_web_ui());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // Navigation request to a non-WebUI page.
+ const GURL kUrl("http://google.com");
+ NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ RenderFrameHostImpl* host2 = NavigateToEntry(manager, entry);
+ ASSERT_TRUE(host2);
+
+ // The previous navigation should still be ongoing along with the new,
+ // cross-site one.
+ // Note: Simultaneous navigations are weird: there are two ongoing
+ // navigations, a same-site using a WebUI and a cross-site not using one. So
+ // it's unclear what GetNavigatingWebUI should return in this case. As it
+ // currently favors the cross-site navigation it returns null.
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_EQ(web_ui, host1->web_ui());
+ EXPECT_EQ(web_ui, host1->pending_web_ui());
+
+ EXPECT_NE(host2, host1);
+ EXPECT_EQ(host2, GetPendingFrameHost(manager));
+ EXPECT_FALSE(host2->web_ui());
+ EXPECT_FALSE(host2->pending_web_ui());
+ EXPECT_NE(web_ui, host2->web_ui());
+
+ commit_lambda(host1, host2, web_ui, manager);
+}
+
+// Simulates two simultaneous navigations involving one WebUI where the current
+// RenderFrameHost commits.
+TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithOneWebUI1) {
+ auto commit_current_frame_host = [this](
+ RenderFrameHostImpl* host1, RenderFrameHostImpl* host2, WebUIImpl* web_ui,
+ RenderFrameHostManager* manager) {
+ // The current RenderFrameHost commits; its WebUI should still be in place.
+ manager->DidNavigateFrame(host1, true);
+ EXPECT_EQ(host1, manager->current_frame_host());
+ EXPECT_EQ(web_ui, host1->web_ui());
+ EXPECT_FALSE(host1->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ };
+
+ BaseSimultaneousNavigationWithOneWebUI(commit_current_frame_host);
+}
+
+// Simulates two simultaneous navigations involving one WebUI where the new,
+// cross-site RenderFrameHost commits.
+TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithOneWebUI2) {
+ auto commit_new_frame_host = [this](
+ RenderFrameHostImpl* host1, RenderFrameHostImpl* host2, WebUIImpl* web_ui,
+ RenderFrameHostManager* manager) {
+ // The new RenderFrameHost commits; there should be no active WebUI.
+ manager->DidNavigateFrame(host2, true);
+ EXPECT_EQ(host2, manager->current_frame_host());
+ EXPECT_FALSE(host2->web_ui());
+ EXPECT_FALSE(host2->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ };
+
+ BaseSimultaneousNavigationWithOneWebUI(commit_new_frame_host);
+}
+
+// Shared code until before commit for the SimultaneousNavigationWithTwoWebUIs*
+// tests, accepting a lambda to execute the commit step.
+void RenderFrameHostManagerTest::BaseSimultaneousNavigationWithTwoWebUIs(
+ const std::function<void(RenderFrameHostImpl*,
+ RenderFrameHostImpl*,
+ WebUIImpl*,
+ WebUIImpl*,
+ RenderFrameHostManager*)>& commit_lambda) {
+ set_should_create_webui(true);
+ set_webui_type(1);
+ NavigateActiveAndCommit(GURL("chrome://foo/"));
+
+ RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
+ RenderFrameHostImpl* host1 = manager->current_frame_host();
+ EXPECT_TRUE(host1->IsRenderFrameLive());
+ WebUIImpl* web_ui1 = host1->web_ui();
+ EXPECT_TRUE(web_ui1);
+
+ // Starts a reload of the WebUI page.
+ contents()->GetController().Reload(true);
+
+ // It should be a same-site navigation reusing the same WebUI.
+ EXPECT_EQ(web_ui1, manager->GetNavigatingWebUI());
+ EXPECT_EQ(web_ui1, host1->web_ui());
+ EXPECT_EQ(web_ui1, host1->pending_web_ui());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // Navigation another WebUI page, with a different type.
+ set_webui_type(2);
+ const GURL kUrl("chrome://bar/");
+ NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ RenderFrameHostImpl* host2 = NavigateToEntry(manager, entry);
+ ASSERT_TRUE(host2);
+
+ // The previous navigation should still be ongoing along with the new,
+ // cross-site one.
+ // Note: simultaneous navigations are weird: there are two ongoing
+ // navigations, a same-site and a cross-site both going to WebUIs. So it's
+ // unclear what GetNavigatingWebUI should return in this case. As it currently
+ // favors the cross-site navigation it returns the speculative/pending
+ // RenderFrameHost's WebUI instance.
+ EXPECT_EQ(web_ui1, host1->web_ui());
+ EXPECT_EQ(web_ui1, host1->pending_web_ui());
+ WebUIImpl* web_ui2 = manager->GetNavigatingWebUI();
+ EXPECT_TRUE(web_ui2);
+ EXPECT_NE(web_ui2, web_ui1);
+
+ EXPECT_NE(host2, host1);
+ EXPECT_EQ(host2, GetPendingFrameHost(manager));
+ EXPECT_EQ(web_ui2, host2->web_ui());
+ EXPECT_FALSE(host2->pending_web_ui());
+
+ commit_lambda(host1, host2, web_ui1, web_ui2, manager);
+}
+
+// Simulates two simultaneous navigations involving two WebUIs where the current
+// RenderFrameHost commits.
+TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithTwoWebUIs1) {
+ auto commit_current_frame_host = [this](
+ RenderFrameHostImpl* host1, RenderFrameHostImpl* host2,
+ WebUIImpl* web_ui1, WebUIImpl* web_ui2, RenderFrameHostManager* manager) {
+ // The current RenderFrameHost commits; its WebUI should still be active.
+ manager->DidNavigateFrame(host1, true);
+ EXPECT_EQ(host1, manager->current_frame_host());
+ EXPECT_EQ(web_ui1, host1->web_ui());
+ EXPECT_FALSE(host1->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ };
+
+ BaseSimultaneousNavigationWithTwoWebUIs(commit_current_frame_host);
+}
+
+// Simulates two simultaneous navigations involving two WebUIs where the new,
+// cross-site RenderFrameHost commits.
+TEST_F(RenderFrameHostManagerTest, SimultaneousNavigationWithTwoWebUIs2) {
+ auto commit_new_frame_host = [this](
+ RenderFrameHostImpl* host1, RenderFrameHostImpl* host2,
+ WebUIImpl* web_ui1, WebUIImpl* web_ui2, RenderFrameHostManager* manager) {
+ // The new RenderFrameHost commits; its WebUI should now be active.
+ manager->DidNavigateFrame(host2, true);
+ EXPECT_EQ(host2, manager->current_frame_host());
+ EXPECT_EQ(web_ui2, host2->web_ui());
+ EXPECT_FALSE(host2->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ };
+
+ BaseSimultaneousNavigationWithTwoWebUIs(commit_new_frame_host);
+}
+
+// RenderFrameHostManagerTest extension for PlzNavigate enabled tests.
+class RenderFrameHostManagerTestWithBrowserSideNavigation
+ : public RenderFrameHostManagerTest {
+ public:
+ void SetUp() override {
+ EnableBrowserSideNavigation();
+ RenderFrameHostManagerTest::SetUp();
+ }
+};
+
+// PlzNavigate: Tests that the correct intermediary and final navigation states
+// are reached when navigating from a renderer that is not live to a WebUI URL.
+TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation,
+ NavigateFromDeadRendererToWebUI) {
+ set_should_create_webui(true);
+ RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
+
+ RenderFrameHostImpl* initial_host = manager->current_frame_host();
+ ASSERT_TRUE(initial_host);
+ EXPECT_FALSE(initial_host->IsRenderFrameLive());
+
+ // Navigation request.
+ const GURL kUrl("chrome://foo");
+ NavigationEntryImpl entry(nullptr /* instance */, -1 /* page_id */, kUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get();
+ scoped_ptr<NavigationRequest> navigation_request =
+ NavigationRequest::CreateBrowserInitiated(
+ contents()->GetFrameTree()->root(), frame_entry->url(),
+ frame_entry->referrer(), *frame_entry, entry,
+ FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(),
+ static_cast<NavigationControllerImpl*>(&controller()));
+ manager->DidCreateNavigationRequest(*navigation_request);
+
+ // As the initial RenderFrame was not live, the new RenderFrameHost should be
+ // made as active/current immediately along with its WebUI at request time.
+ RenderFrameHostImpl* host = manager->current_frame_host();
+ ASSERT_TRUE(host);
+ EXPECT_NE(host, initial_host);
+ EXPECT_TRUE(host->IsRenderFrameLive());
+ WebUIImpl* web_ui = host->web_ui();
+ EXPECT_TRUE(web_ui);
+ EXPECT_FALSE(host->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // Prepare to commit, update the navigating RenderFrameHost.
+ EXPECT_EQ(host, manager->GetFrameHostForNavigation(*navigation_request));
+
+ // There should be a pending WebUI set to reuse the current one.
+ EXPECT_EQ(web_ui, host->web_ui());
+ EXPECT_EQ(web_ui, host->pending_web_ui());
+ EXPECT_EQ(web_ui, manager->GetNavigatingWebUI());
+
+ // No pending RenderFrameHost as the current one should be reused.
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // The RenderFrameHost committed.
+ manager->DidNavigateFrame(host, true);
+ EXPECT_EQ(host, manager->current_frame_host());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ EXPECT_EQ(web_ui, host->web_ui());
+ EXPECT_FALSE(host->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+}
+
+// PlzNavigate: Tests that the correct intermediary and final navigation states
+// are reached when navigating same-site between two WebUIs of the same type.
+TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation,
+ NavigateSameSiteBetweenWebUIs) {
+ set_should_create_webui(true);
+ NavigateActiveAndCommit(GURL("chrome://foo"));
+
+ RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
+ RenderFrameHostImpl* host = manager->current_frame_host();
+ EXPECT_TRUE(host->IsRenderFrameLive());
+ WebUIImpl* web_ui = host->web_ui();
+ EXPECT_TRUE(web_ui);
+
+ // Navigation request. No change in the returned WebUI type.
+ const GURL kUrl("chrome://foo/bar");
+ NavigationEntryImpl entry(nullptr /* instance */, -1 /* page_id */, kUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get();
+ scoped_ptr<NavigationRequest> navigation_request =
+ NavigationRequest::CreateBrowserInitiated(
+ contents()->GetFrameTree()->root(), frame_entry->url(),
+ frame_entry->referrer(), *frame_entry, entry,
+ FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(),
+ static_cast<NavigationControllerImpl*>(&controller()));
+ manager->DidCreateNavigationRequest(*navigation_request);
+
+ // The current WebUI should still be in place and the pending WebUI should be
+ // set to reuse it.
+ EXPECT_EQ(web_ui, manager->GetNavigatingWebUI());
+ EXPECT_EQ(web_ui, host->web_ui());
+ EXPECT_EQ(web_ui, host->pending_web_ui());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+
+ // Prepare to commit, update the navigating RenderFrameHost.
+ EXPECT_EQ(host, manager->GetFrameHostForNavigation(*navigation_request));
+
+ EXPECT_EQ(web_ui, manager->GetNavigatingWebUI());
+ EXPECT_EQ(web_ui, host->web_ui());
+ EXPECT_EQ(web_ui, host->pending_web_ui());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
nasko 2015/11/30 16:57:49 Why do we have no speculative RFH before we've com
carlosk 2015/11/30 19:54:16 We never have one in this navigation as it is a sa
nasko 2015/12/01 00:52:14 D'oh! Yes indeed!
+
+ // The RenderFrameHost committed.
+ manager->DidNavigateFrame(host, true);
+ EXPECT_EQ(web_ui, host->web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+ EXPECT_FALSE(host->pending_web_ui());
+}
+
+// PlzNavigate: Tests that the correct intermediary and final navigation states
+// are reached when navigating cross-site between two different WebUI types.
+TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation,
+ NavigateCrossSiteBetweenWebUIs) {
+ // Cross-site navigations will always cause the change of the WebUI instance
+ // but for consistency sake different types will be set for each navigation.
+ set_should_create_webui(true);
+ set_webui_type(1);
+ NavigateActiveAndCommit(GURL("chrome://foo"));
+
+ RenderFrameHostManager* manager = contents()->GetRenderManagerForTesting();
+ RenderFrameHostImpl* host = manager->current_frame_host();
+ EXPECT_TRUE(host->IsRenderFrameLive());
+ EXPECT_TRUE(host->web_ui());
+
+ // Set the WebUI controller to return a different WebUIType value. This will
+ // cause the next navigation to "chrome://bar" to require a different WebUI
+ // than the current one, forcing it to be treated as cross-site.
+ set_webui_type(2);
+
+ // Navigation request.
+ const GURL kUrl("chrome://bar");
+ NavigationEntryImpl entry(nullptr /* instance */, -1 /* page_id */, kUrl,
+ Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED,
+ false /* is_renderer_init */);
+ FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get();
+ scoped_ptr<NavigationRequest> navigation_request =
+ NavigationRequest::CreateBrowserInitiated(
+ contents()->GetFrameTree()->root(), frame_entry->url(),
+ frame_entry->referrer(), *frame_entry, entry,
+ FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(),
+ static_cast<NavigationControllerImpl*>(&controller()));
+ manager->DidCreateNavigationRequest(*navigation_request);
+
+ // The current WebUI should still be in place and there should be a new
+ // active WebUI instance in the speculative RenderFrameHost.
+ EXPECT_TRUE(manager->current_frame_host()->web_ui());
+ EXPECT_FALSE(manager->current_frame_host()->pending_web_ui());
+ RenderFrameHostImpl* speculative_host = GetPendingFrameHost(manager);
+ EXPECT_TRUE(speculative_host);
+ WebUIImpl* next_web_ui = manager->GetNavigatingWebUI();
+ EXPECT_TRUE(next_web_ui);
+ EXPECT_EQ(next_web_ui, speculative_host->web_ui());
+ EXPECT_NE(next_web_ui, manager->current_frame_host()->web_ui());
+ EXPECT_FALSE(speculative_host->pending_web_ui());
+
+ // Prepare to commit, update the navigating RenderFrameHost.
+ EXPECT_EQ(speculative_host,
+ manager->GetFrameHostForNavigation(*navigation_request));
+
+ EXPECT_TRUE(manager->current_frame_host()->web_ui());
+ EXPECT_FALSE(manager->current_frame_host()->pending_web_ui());
+ EXPECT_EQ(speculative_host, GetPendingFrameHost(manager));
+ EXPECT_NE(next_web_ui, manager->current_frame_host()->web_ui());
+ EXPECT_EQ(next_web_ui, speculative_host->web_ui());
+ EXPECT_EQ(next_web_ui, manager->GetNavigatingWebUI());
+ EXPECT_FALSE(speculative_host->pending_web_ui());
+
+ // The RenderFrameHost committed.
+ manager->DidNavigateFrame(speculative_host, true);
+ EXPECT_EQ(speculative_host, manager->current_frame_host());
+ EXPECT_EQ(next_web_ui, manager->current_frame_host()->web_ui());
+ EXPECT_FALSE(GetPendingFrameHost(manager));
+ EXPECT_FALSE(speculative_host->pending_web_ui());
+ EXPECT_FALSE(manager->GetNavigatingWebUI());
+}
+
} // namespace content
« no previous file with comments | « content/browser/frame_host/render_frame_host_manager_browsertest.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