blob: 2063c93bb721061b581845fbb8ad2608c4ae03e1 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2017 The Chromium Authors
Xiaohan Wang15303d0c2017-10-06 05:22:442// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Daniel Cheng9fb887ff2021-10-01 20:27:385#include "content/public/browser/document_service.h"
Xiaohan Wang15303d0c2017-10-06 05:22:446
Avi Drissmanadac21992023-01-11 23:46:397#include "base/functional/bind.h"
Keishi Hattori0e45c022021-11-27 09:25:528#include "base/memory/raw_ptr.h"
Xiaohan Wang15303d0c2017-10-06 05:22:449#include "base/run_loop.h"
Daniel Cheng9fb887ff2021-10-01 20:27:3810#include "content/browser/renderer_host/document_service_echo_impl.h"
Fergal Daly3a62eb52019-10-31 23:43:4211#include "content/public/browser/back_forward_cache.h"
Xiaohan Wang15303d0c2017-10-06 05:22:4412#include "content/public/browser/render_frame_host.h"
13#include "content/public/browser/web_contents.h"
14#include "content/public/test/navigation_simulator.h"
15#include "content/public/test/test_renderer_host.h"
Ken Rockot9652fa62020-11-05 05:30:2216#include "content/test/echo.test-mojom.h"
Xiaohan Wang15303d0c2017-10-06 05:22:4417#include "content/test/test_render_frame_host.h"
Mario Sanchez Prada9d38e352019-09-10 08:07:5918#include "mojo/public/cpp/bindings/remote.h"
Xiaohan Wang15303d0c2017-10-06 05:22:4419#include "url/gurl.h"
20
Daniel Cheng9fb887ff2021-10-01 20:27:3821// Unit test for DocumentService in content/public/browser.
Xiaohan Wang15303d0c2017-10-06 05:22:4422
23namespace content {
24
25namespace {
26
27const char kFooOrigin[] = "https://foo.com";
28const char kBarOrigin[] = "https://bar.com";
29
Xiaohan Wang15303d0c2017-10-06 05:22:4430// Help functions to manipulate RenderFrameHosts.
31
32// Simulates navigation and returns the final RenderFrameHost.
33RenderFrameHost* SimulateNavigation(RenderFrameHost* rfh, const GURL& url) {
34 auto navigation_simulator =
35 NavigationSimulator::CreateRendererInitiated(url, rfh);
36 navigation_simulator->Commit();
37 return navigation_simulator->GetFinalRenderFrameHost();
38}
39
40RenderFrameHost* AddChildFrame(RenderFrameHost* rfh, const GURL& url) {
41 RenderFrameHost* child_rfh = RenderFrameHostTester::For(rfh)->AppendChild("");
42 RenderFrameHostTester::For(child_rfh)->InitializeRenderFrameIfNeeded();
43 return SimulateNavigation(child_rfh, url);
44}
45
46void DetachFrame(RenderFrameHost* rfh) {
47 RenderFrameHostTester::For(rfh)->Detach();
48}
49
50} // namespace
51
Daniel Cheng9fb887ff2021-10-01 20:27:3852class DocumentServiceTest : public RenderViewHostTestHarness {
Xiaohan Wang15303d0c2017-10-06 05:22:4453 protected:
54 void SetUp() final {
55 RenderViewHostTestHarness::SetUp();
56 Initialize();
57 }
58
59 void Initialize() {
Dave Tapuska327c06c92022-06-13 20:31:5160 RenderFrameHost* main_rfh = web_contents()->GetPrimaryMainFrame();
Xiaohan Wang15303d0c2017-10-06 05:22:4461 RenderFrameHostTester::For(main_rfh)->InitializeRenderFrameIfNeeded();
Sam Fortinerfb39c1e2023-12-08 03:03:1262 SimulateNavigation(main_rfh, GURL(kFooOrigin));
Xiaohan Wang15303d0c2017-10-06 05:22:4463 }
64
danakjc70aec1f2022-07-07 15:48:1965 void CreateEchoImpl(RenderFrameHost& rfh) {
Xiaohan Wang15303d0c2017-10-06 05:22:4466 DCHECK(!is_echo_impl_alive_);
Daniel Cheng9fb887ff2021-10-01 20:27:3867 new DocumentServiceEchoImpl(
Julie Jeongeun Kim5a66adb42021-08-11 07:14:1068 rfh, echo_remote_.BindNewPipeAndPassReceiver(),
Daniel Cheng9fb887ff2021-10-01 20:27:3869 base::BindOnce(&DocumentServiceTest::OnEchoImplDestructed,
Julie Jeongeun Kim5a66adb42021-08-11 07:14:1070 base::Unretained(this)));
Xiaohan Wang15303d0c2017-10-06 05:22:4471 is_echo_impl_alive_ = true;
72 }
73
74 void OnEchoImplDestructed() {
75 DCHECK(is_echo_impl_alive_);
76 is_echo_impl_alive_ = false;
77 }
78
79 void ResetConnection() {
Mario Sanchez Prada9d38e352019-09-10 08:07:5980 echo_remote_.reset();
Xiaohan Wang15303d0c2017-10-06 05:22:4481 base::RunLoop().RunUntilIdle();
82 }
83
Sam Fortinerfb39c1e2023-12-08 03:03:1284 RenderFrameHost* main_rfh() const {
85 return web_contents()->GetPrimaryMainFrame();
86 }
87
Mario Sanchez Prada9d38e352019-09-10 08:07:5988 mojo::Remote<mojom::Echo> echo_remote_;
Xiaohan Wang15303d0c2017-10-06 05:22:4489 bool is_echo_impl_alive_ = false;
90};
91
Daniel Cheng9fb887ff2021-10-01 20:27:3892TEST_F(DocumentServiceTest, ConnectionError) {
Sam Fortinerfb39c1e2023-12-08 03:03:1293 CreateEchoImpl(*main_rfh());
Xiaohan Wang15303d0c2017-10-06 05:22:4494 ResetConnection();
95 EXPECT_FALSE(is_echo_impl_alive_);
96}
97
Daniel Cheng9fb887ff2021-10-01 20:27:3898TEST_F(DocumentServiceTest, RenderFrameDeleted) {
Xiaohan Wang15303d0c2017-10-06 05:22:4499 // Needs to create a child frame so we can delete it using DetachFrame()
100 // because it is not allowed to detach the main frame.
Sam Fortinerfb39c1e2023-12-08 03:03:12101 RenderFrameHost* child_rfh = AddChildFrame(main_rfh(), GURL(kBarOrigin));
danakjc70aec1f2022-07-07 15:48:19102 CreateEchoImpl(*child_rfh);
Xiaohan Wang15303d0c2017-10-06 05:22:44103 DetachFrame(child_rfh);
104 EXPECT_FALSE(is_echo_impl_alive_);
105}
106
Daniel Cheng9fb887ff2021-10-01 20:27:38107TEST_F(DocumentServiceTest, DidFinishNavigation) {
Fergal Daly3a62eb52019-10-31 23:43:42108 // When a page enters the BackForwardCache, the RenderFrameHost is not
109 // deleted.
110 web_contents()->GetController().GetBackForwardCache().DisableForTesting(
Rakina Zata Amni30af7062022-01-19 23:46:36111 BackForwardCache::TEST_REQUIRES_NO_CACHING);
Sam Fortinerfb39c1e2023-12-08 03:03:12112 CreateEchoImpl(*main_rfh());
113 SimulateNavigation(main_rfh(), GURL(kBarOrigin));
Xiaohan Wang15303d0c2017-10-06 05:22:44114 EXPECT_FALSE(is_echo_impl_alive_);
115}
116
Daniel Cheng9fb887ff2021-10-01 20:27:38117TEST_F(DocumentServiceTest, SameDocumentNavigation) {
Sam Fortinerfb39c1e2023-12-08 03:03:12118 CreateEchoImpl(*main_rfh());
Xiaohan Wang15303d0c2017-10-06 05:22:44119
Sam Fortinerfb39c1e2023-12-08 03:03:12120 RenderFrameHost* previous_main_rfh = main_rfh();
Xiaohan Wang15303d0c2017-10-06 05:22:44121 // Must use the same origin to simulate same document navigation.
Sam Fortinerfb39c1e2023-12-08 03:03:12122 auto navigation_simulator = NavigationSimulator::CreateRendererInitiated(
123 GURL(kFooOrigin), main_rfh());
Xiaohan Wang15303d0c2017-10-06 05:22:44124 navigation_simulator->CommitSameDocument();
Sam Fortinerfb39c1e2023-12-08 03:03:12125 DCHECK_EQ(previous_main_rfh, navigation_simulator->GetFinalRenderFrameHost());
Xiaohan Wang15303d0c2017-10-06 05:22:44126
127 EXPECT_TRUE(is_echo_impl_alive_);
128}
129
Daniel Cheng9fb887ff2021-10-01 20:27:38130TEST_F(DocumentServiceTest, FailedNavigation) {
Sam Fortinerfb39c1e2023-12-08 03:03:12131 CreateEchoImpl(*main_rfh());
Xiaohan Wang15303d0c2017-10-06 05:22:44132
Sam Fortinerfb39c1e2023-12-08 03:03:12133 auto navigation_simulator = NavigationSimulator::CreateRendererInitiated(
134 GURL(kFooOrigin), main_rfh());
Xiaohan Wang15303d0c2017-10-06 05:22:44135 navigation_simulator->Fail(net::ERR_TIMED_OUT);
136 navigation_simulator->CommitErrorPage();
137
138 EXPECT_FALSE(is_echo_impl_alive_);
139}
140
Daniel Cheng9fb887ff2021-10-01 20:27:38141TEST_F(DocumentServiceTest, DeleteContents) {
Sam Fortinerfb39c1e2023-12-08 03:03:12142 CreateEchoImpl(*main_rfh());
Xiaohan Wang15303d0c2017-10-06 05:22:44143 DeleteContents();
144 EXPECT_FALSE(is_echo_impl_alive_);
145}
146
147} // namespace content