1 // Copyright 2014 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.
5 #include "chrome/browser/content_settings/permission_context_base.h"
8 #include "base/command_line.h"
9 #include "chrome/browser/content_settings/permission_queue_controller.h"
10 #include "chrome/browser/infobars/infobar_service.h"
11 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "components/content_settings/core/browser/host_content_settings_map.h"
16 #include "components/content_settings/core/common/content_settings.h"
17 #include "components/content_settings/core/common/content_settings_types.h"
18 #include "components/content_settings/core/common/permission_request_id.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/test/mock_render_process_host.h"
21 #include "content/public/test/web_contents_tester.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 class TestPermissionContext
: public PermissionContextBase
{
26 TestPermissionContext(Profile
* profile
,
27 const ContentSettingsType permission_type
)
28 : PermissionContextBase(profile
, permission_type
),
29 permission_set_(false),
30 permission_granted_(false),
31 tab_context_updated_(false) {}
33 ~TestPermissionContext() override
{}
35 PermissionQueueController
* GetInfoBarController() {
36 return GetQueueController();
39 bool permission_granted() {
40 return permission_granted_
;
43 bool permission_set() {
44 return permission_set_
;
47 bool tab_context_updated() {
48 return tab_context_updated_
;
51 void TrackPermissionDecision(ContentSetting content_setting
) {
52 permission_set_
= true;
53 permission_granted_
= content_setting
== CONTENT_SETTING_ALLOW
;
57 void UpdateTabContext(const PermissionRequestID
& id
,
58 const GURL
& requesting_origin
,
59 bool allowed
) override
{
60 tab_context_updated_
= true;
65 bool permission_granted_
;
66 bool tab_context_updated_
;
69 class PermissionContextBaseTests
: public ChromeRenderViewHostTestHarness
{
71 PermissionContextBaseTests() {}
73 // Accept or dismiss the permission bubble or infobar.
74 void RespondToPermission(TestPermissionContext
* context
,
75 const PermissionRequestID
& id
,
78 if (!PermissionBubbleManager::Enabled()) {
79 context
->GetInfoBarController()->OnPermissionSet(
80 id
, url
, url
, accept
, accept
);
84 PermissionBubbleManager
* manager
=
85 PermissionBubbleManager::FromWebContents(web_contents());
92 // Use either the bubble or the infobar.
93 void StartUsingPermissionBubble() {
94 base::CommandLine::ForCurrentProcess()->AppendSwitch(
95 switches::kEnablePermissionsBubbles
);
96 EXPECT_TRUE(PermissionBubbleManager::Enabled());
99 void TestAskAndGrant_TestContent() {
100 TestPermissionContext
permission_context(
101 profile(), CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
102 GURL
url("http://www.google.com");
103 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
105 const PermissionRequestID
id(
106 web_contents()->GetRenderProcessHost()->GetID(),
107 web_contents()->GetRenderViewHost()->GetRoutingID(),
109 permission_context
.RequestPermission(
112 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
113 base::Unretained(&permission_context
)));
115 RespondToPermission(&permission_context
, id
, url
, true);
116 EXPECT_TRUE(permission_context
.permission_set());
117 EXPECT_TRUE(permission_context
.permission_granted());
118 EXPECT_TRUE(permission_context
.tab_context_updated());
120 ContentSetting setting
=
121 profile()->GetHostContentSettingsMap()->GetContentSetting(
122 url
.GetOrigin(), url
.GetOrigin(),
123 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
, std::string());
124 EXPECT_EQ(CONTENT_SETTING_ALLOW
, setting
);
127 void TestAskAndDismiss_TestContent() {
128 TestPermissionContext
permission_context(
129 profile(), CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
130 GURL
url("http://www.google.es");
131 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
133 const PermissionRequestID
id(
134 web_contents()->GetRenderProcessHost()->GetID(),
135 web_contents()->GetRenderViewHost()->GetRoutingID(),
137 permission_context
.RequestPermission(
140 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
141 base::Unretained(&permission_context
)));
143 RespondToPermission(&permission_context
, id
, url
, false);
144 EXPECT_TRUE(permission_context
.permission_set());
145 EXPECT_FALSE(permission_context
.permission_granted());
146 EXPECT_TRUE(permission_context
.tab_context_updated());
148 ContentSetting setting
=
149 profile()->GetHostContentSettingsMap()->GetContentSetting(
150 url
.GetOrigin(), url
.GetOrigin(),
151 CONTENT_SETTINGS_TYPE_MIDI_SYSEX
, std::string());
152 EXPECT_EQ(CONTENT_SETTING_ASK
, setting
);
155 void TestRequestPermissionInvalidUrl(ContentSettingsType type
) {
156 TestPermissionContext
permission_context(profile(), type
);
158 ASSERT_FALSE(url
.is_valid());
159 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
161 const PermissionRequestID
id(
162 web_contents()->GetRenderProcessHost()->GetID(),
163 web_contents()->GetRenderViewHost()->GetRoutingID(),
165 permission_context
.RequestPermission(
168 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
169 base::Unretained(&permission_context
)));
171 EXPECT_TRUE(permission_context
.permission_set());
172 EXPECT_FALSE(permission_context
.permission_granted());
173 EXPECT_TRUE(permission_context
.tab_context_updated());
175 ContentSetting setting
=
176 profile()->GetHostContentSettingsMap()->GetContentSetting(
177 url
.GetOrigin(), url
.GetOrigin(), type
, std::string());
178 EXPECT_EQ(CONTENT_SETTING_ASK
, setting
);
181 void TestGrantAndRevoke_TestContent(ContentSettingsType type
,
182 ContentSetting expected_default
) {
183 TestPermissionContext
permission_context(profile(), type
);
184 GURL
url("http://www.google.com");
185 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
187 const PermissionRequestID
id(
188 web_contents()->GetRenderProcessHost()->GetID(),
189 web_contents()->GetRenderViewHost()->GetRoutingID(),
191 permission_context
.RequestPermission(
194 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
195 base::Unretained(&permission_context
)));
197 RespondToPermission(&permission_context
, id
, url
, true);
198 EXPECT_TRUE(permission_context
.permission_set());
199 EXPECT_TRUE(permission_context
.permission_granted());
200 EXPECT_TRUE(permission_context
.tab_context_updated());
202 ContentSetting setting
=
203 profile()->GetHostContentSettingsMap()->GetContentSetting(
204 url
.GetOrigin(), url
.GetOrigin(),
205 type
, std::string());
206 EXPECT_EQ(CONTENT_SETTING_ALLOW
, setting
);
208 // Try to reset permission.
209 permission_context
.ResetPermission(url
.GetOrigin(), url
.GetOrigin());
210 ContentSetting setting_after_reset
=
211 profile()->GetHostContentSettingsMap()->GetContentSetting(
212 url
.GetOrigin(), url
.GetOrigin(),
213 type
, std::string());
214 ContentSetting default_setting
=
215 profile()->GetHostContentSettingsMap()->GetDefaultContentSetting(
217 EXPECT_EQ(default_setting
, setting_after_reset
);
221 // ChromeRenderViewHostTestHarness:
222 void SetUp() override
{
223 ChromeRenderViewHostTestHarness::SetUp();
224 InfoBarService::CreateForWebContents(web_contents());
225 PermissionBubbleManager::CreateForWebContents(web_contents());
228 DISALLOW_COPY_AND_ASSIGN(PermissionContextBaseTests
);
231 // Simulates clicking Accept. The permission should be granted and
232 // saved for future use.
233 TEST_F(PermissionContextBaseTests
, TestAskAndGrant
) {
234 TestAskAndGrant_TestContent();
235 StartUsingPermissionBubble();
236 TestAskAndGrant_TestContent();
239 // Simulates clicking Dismiss (X) in the infobar/bubble.
240 // The permission should be denied but not saved for future use.
241 TEST_F(PermissionContextBaseTests
, TestAskAndDismiss
) {
242 TestAskAndDismiss_TestContent();
243 StartUsingPermissionBubble();
244 TestAskAndDismiss_TestContent();
247 // Simulates non-valid requesting URL.
248 // The permission should be denied but not saved for future use.
249 TEST_F(PermissionContextBaseTests
, TestNonValidRequestingUrl
) {
250 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_GEOLOCATION
);
251 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
252 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
253 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
);
254 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
255 TestRequestPermissionInvalidUrl(
256 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
);
260 // Simulates granting and revoking of permissions.
261 TEST_F(PermissionContextBaseTests
, TestGrantAndRevoke
) {
262 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION
,
263 CONTENT_SETTING_ASK
);
264 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
,
265 CONTENT_SETTING_ASK
);
266 #if defined(OS_ANDROID)
267 TestGrantAndRevoke_TestContent(
268 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
, CONTENT_SETTING_ASK
);
270 // TODO(timvolodine): currently no test for
271 // CONTENT_SETTINGS_TYPE_NOTIFICATIONS because notification permissions work
272 // differently with infobars as compared to bubbles (crbug.com/453784).
273 // TODO(timvolodine): currently no test for
274 // CONTENT_SETTINGS_TYPE_PUSH_MESSAGING because infobars do not implement push
275 // messaging permissions (crbug.com/453788).
278 // Simulates granting and revoking of permissions using permission bubbles.
279 TEST_F(PermissionContextBaseTests
, TestGrantAndRevokeWithBubbles
) {
280 StartUsingPermissionBubble();
281 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION
,
282 CONTENT_SETTING_ASK
);
283 #if defined(ENABLE_NOTIFICATIONS)
284 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
285 CONTENT_SETTING_ASK
);
287 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
,
288 CONTENT_SETTING_ASK
);
289 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
,
290 CONTENT_SETTING_ASK
);
291 #if defined(OS_ANDROID)
292 TestGrantAndRevoke_TestContent(
293 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
, CONTENT_SETTING_ASK
);