1 // Copyright (c) 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/test/scoped_feature_list.h"
6 #include "content/browser/web_contents/web_contents_impl.h"
7 #include "content/common/content_navigation_policy.h"
8 #include "content/public/browser/render_frame_host.h"
9 #include "content/public/browser/web_contents_delegate.h"
10 #include "content/public/common/content_features.h"
11 #include "content/public/test/navigation_simulator.h"
12 #include "content/test/test_render_frame_host.h"
13 #include "content/test/test_render_view_host.h"
14 #include "content/test/test_web_contents.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16
17 namespace content {
18
19 namespace {
20
21 // Mock content::ColorChooser to test whether End() is called.
22 class MockColorChooser : public content::ColorChooser {
23 public:
24 MockColorChooser() = default;
25 ~MockColorChooser() override = default;
26
27 MOCK_METHOD0(End, void());
28 MOCK_METHOD1(SetSelectedColor, void(SkColor color));
29
30 private:
31 DISALLOW_COPY_AND_ASSIGN(MockColorChooser);
32 };
33
34 // Delegate to override OpenColorChooser.
35 class OpenColorChooserDelegate : public WebContentsDelegate {
36 public:
OpenColorChooserDelegate(std::unique_ptr<MockColorChooser> mock_color_chooser)37 explicit OpenColorChooserDelegate(
38 std::unique_ptr<MockColorChooser> mock_color_chooser)
39 : mock_color_chooser_(std::move(mock_color_chooser)) {}
40
41 ~OpenColorChooserDelegate() override = default;
42
43 // WebContentsDelegate:
OpenColorChooser(WebContents * web_contents,SkColor color,const std::vector<blink::mojom::ColorSuggestionPtr> & suggestions)44 ColorChooser* OpenColorChooser(
45 WebContents* web_contents,
46 SkColor color,
47 const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions)
48 override {
49 return std::move(mock_color_chooser_).release();
50 }
51
52 private:
53 std::unique_ptr<MockColorChooser> mock_color_chooser_;
54
55 DISALLOW_COPY_AND_ASSIGN(OpenColorChooserDelegate);
56 };
57
58 } // namespace
59
60 class ColorChooserUnitTest : public RenderViewHostImplTestHarness {};
61
TEST_F(ColorChooserUnitTest,ColorChooserCallsEndOnNavigatingAway)62 TEST_F(ColorChooserUnitTest, ColorChooserCallsEndOnNavigatingAway) {
63 GURL kUrl1("https://foo.com");
64 GURL kUrl2("https://bar.com");
65
66 // Navigate to A.
67 NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kUrl1);
68
69 // End should be called at least once on navigating to a new URL.
70 std::unique_ptr<MockColorChooser> mock_color_chooser =
71 std::make_unique<MockColorChooser>();
72 EXPECT_CALL(*mock_color_chooser.get(), End()).Times(testing::AtLeast(1));
73
74 // Set OpenColorChooserDelegate as the new WebContentsDelegate.
75 std::unique_ptr<OpenColorChooserDelegate> delegate =
76 std::make_unique<OpenColorChooserDelegate>(std::move(mock_color_chooser));
77 contents()->SetDelegate(delegate.get());
78
79 mojo::PendingRemote<blink::mojom::ColorChooserClient> pending_client;
80 mojo::Remote<blink::mojom::ColorChooser> pending_remote;
81 mojo::PendingReceiver<blink::mojom::ColorChooser> pending_receiver =
82 pending_remote.BindNewPipeAndPassReceiver();
83
84 // Call WebContentsImpl::OpenColorChooser.
85 static_cast<WebContentsImpl*>(contents())
86 ->OpenColorChooser(std::move(pending_receiver), std::move(pending_client),
87 SkColorSetRGB(0, 0, 1), {});
88
89 // Navigate to B.
90 NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kUrl2);
91
92 contents()->SetDelegate(nullptr);
93 }
94
95 // Run tests with BackForwardCache.
96 class ColorChooserTestWithBackForwardCache : public ColorChooserUnitTest {
97 public:
ColorChooserTestWithBackForwardCache()98 ColorChooserTestWithBackForwardCache() {
99 scoped_feature_list_.InitWithFeaturesAndParameters(
100 {{features::kBackForwardCache, {GetFeatureParams()}}},
101 /*disabled_features=*/{});
102 }
103
104 protected:
GetFeatureParams()105 base::FieldTrialParams GetFeatureParams() {
106 return {{"TimeToLiveInBackForwardCacheInSeconds", "3600"},
107 {"service_worker_supported", "true"}};
108 }
109
110 private:
111 base::test::ScopedFeatureList scoped_feature_list_;
112 };
113
TEST_F(ColorChooserTestWithBackForwardCache,ColorChooserCallsEndOnEnteringBackForwardCache)114 TEST_F(ColorChooserTestWithBackForwardCache,
115 ColorChooserCallsEndOnEnteringBackForwardCache) {
116 ASSERT_TRUE(IsBackForwardCacheEnabled());
117 GURL kUrl1("https://foo.com");
118 GURL kUrl2("https://bar.com");
119
120 // Navigate to A.
121 NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kUrl1);
122 RenderFrameHost* rfh_a = contents()->GetMainFrame();
123
124 // End should be called at least once on navigating to a new URL.
125 std::unique_ptr<MockColorChooser> mock_color_chooser =
126 std::make_unique<MockColorChooser>();
127 EXPECT_CALL(*mock_color_chooser.get(), End()).Times(testing::AtLeast(1));
128
129 // Set OpenColorChooserDelegate as the new WebContentsDelegate.
130 std::unique_ptr<OpenColorChooserDelegate> delegate =
131 std::make_unique<OpenColorChooserDelegate>(std::move(mock_color_chooser));
132 contents()->SetDelegate(delegate.get());
133
134 mojo::PendingRemote<blink::mojom::ColorChooserClient> pending_client;
135 mojo::Remote<blink::mojom::ColorChooser> pending_remote;
136 mojo::PendingReceiver<blink::mojom::ColorChooser> pending_receiver =
137 pending_remote.BindNewPipeAndPassReceiver();
138
139 // Call WebContentsImpl::OpenColorChooser.
140 static_cast<WebContentsImpl*>(contents())
141 ->OpenColorChooser(std::move(pending_receiver), std::move(pending_client),
142 SkColorSetRGB(0, 0, 1), {});
143
144 // Navigate to B, A enters BackForwardCache.
145 NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kUrl2);
146 EXPECT_TRUE(rfh_a->IsInBackForwardCache());
147
148 contents()->SetDelegate(nullptr);
149 }
150
151 } // namespace content
152