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
3 // found in the LICENSE file.
5 #include "components/content_settings/core/common/content_settings.h"
6 #include "chrome/common/render_messages.h"
7 #include "chrome/renderer/content_settings_observer.h"
8 #include "chrome/test/base/chrome_render_view_test.h"
9 #include "components/content_settings/content/common/content_settings_messages.h"
10 #include "content/public/renderer/render_view.h"
11 #include "ipc/ipc_message_macros.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/WebKit/public/web/WebView.h"
17 using testing::DeleteArg
;
21 class MockContentSettingsObserver
: public ContentSettingsObserver
{
23 explicit MockContentSettingsObserver(content::RenderFrame
* render_frame
);
25 virtual bool Send(IPC::Message
* message
);
27 MOCK_METHOD2(OnContentBlocked
,
28 void(ContentSettingsType
, const base::string16
&));
30 MOCK_METHOD5(OnAllowDOMStorage
,
31 void(int, const GURL
&, const GURL
&, bool, IPC::Message
*));
33 std::string image_origin_
;
36 MockContentSettingsObserver::MockContentSettingsObserver(
37 content::RenderFrame
* render_frame
)
38 : ContentSettingsObserver(render_frame
, NULL
, false),
39 image_url_("http://www.foo.com/image.jpg"),
40 image_origin_("http://www.foo.com") {
43 bool MockContentSettingsObserver::Send(IPC::Message
* message
) {
44 IPC_BEGIN_MESSAGE_MAP(MockContentSettingsObserver
, *message
)
45 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked
, OnContentBlocked
)
46 IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_AllowDOMStorage
,
48 IPC_MESSAGE_UNHANDLED(ADD_FAILURE())
51 // Our super class deletes the message.
52 return RenderFrameObserver::Send(message
);
57 TEST_F(ChromeRenderViewTest
, DidBlockContentType
) {
58 MockContentSettingsObserver
observer(view_
->GetMainRenderFrame());
59 EXPECT_CALL(observer
, OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
,
61 observer
.DidBlockContentType(CONTENT_SETTINGS_TYPE_COOKIES
);
63 // Blocking the same content type a second time shouldn't send a notification.
64 observer
.DidBlockContentType(CONTENT_SETTINGS_TYPE_COOKIES
);
65 ::testing::Mock::VerifyAndClearExpectations(&observer
);
68 // Tests that multiple invokations of AllowDOMStorage result in a single IPC.
69 // Fails due to http://crbug.com/104300
70 TEST_F(ChromeRenderViewTest
, DISABLED_AllowDOMStorage
) {
71 // Load some HTML, so we have a valid security origin.
72 LoadHTML("<html></html>");
73 MockContentSettingsObserver
observer(view_
->GetMainRenderFrame());
75 OnAllowDOMStorage(_
, _
, _
, _
, _
)).WillByDefault(DeleteArg
<4>());
77 OnAllowDOMStorage(_
, _
, _
, _
, _
));
78 observer
.allowStorage(true);
80 // Accessing localStorage from the same origin again shouldn't result in a
82 observer
.allowStorage(true);
83 ::testing::Mock::VerifyAndClearExpectations(&observer
);
86 // Regression test for http://crbug.com/35011
87 TEST_F(ChromeRenderViewTest
, JSBlockSentAfterPageLoad
) {
88 // 1. Load page with JS.
89 std::string html
= "<html>"
91 "<script>document.createElement('div');</script>"
96 render_thread_
->sink().ClearMessages();
97 LoadHTML(html
.c_str());
99 // 2. Block JavaScript.
100 RendererContentSettingRules content_setting_rules
;
101 ContentSettingsForOneType
& script_setting_rules
=
102 content_setting_rules
.script_rules
;
103 script_setting_rules
.push_back(
104 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
105 ContentSettingsPattern::Wildcard(),
106 CONTENT_SETTING_BLOCK
,
109 ContentSettingsObserver
* observer
= ContentSettingsObserver::Get(
110 view_
->GetMainRenderFrame());
111 observer
->SetContentSettingRules(&content_setting_rules
);
113 // Make sure no pending messages are in the queue.
114 ProcessPendingMessages();
115 render_thread_
->sink().ClearMessages();
118 std::string url_str
= "data:text/html;charset=utf-8,";
119 url_str
.append(html
);
122 ProcessPendingMessages();
124 // 4. Verify that the notification that javascript was blocked is sent after
125 // the navigation notification is sent.
126 int navigation_index
= -1;
127 int block_index
= -1;
128 for (size_t i
= 0; i
< render_thread_
->sink().message_count(); ++i
) {
129 const IPC::Message
* msg
= render_thread_
->sink().GetMessageAt(i
);
130 if (msg
->type() == GetNavigationIPCType())
131 navigation_index
= i
;
132 if (msg
->type() == ChromeViewHostMsg_ContentBlocked::ID
)
135 EXPECT_NE(-1, navigation_index
);
136 EXPECT_NE(-1, block_index
);
137 EXPECT_LT(navigation_index
, block_index
);
140 TEST_F(ChromeRenderViewTest
, PluginsTemporarilyAllowed
) {
142 LoadHTML("<html>Foo</html>");
144 std::string foo_plugin
= "foo";
145 std::string bar_plugin
= "bar";
147 ContentSettingsObserver
* observer
=
148 ContentSettingsObserver::Get(view_
->GetMainRenderFrame());
149 EXPECT_FALSE(observer
->IsPluginTemporarilyAllowed(foo_plugin
));
151 // Temporarily allow the "foo" plugin.
152 observer
->OnLoadBlockedPlugins(foo_plugin
);
153 EXPECT_TRUE(observer
->IsPluginTemporarilyAllowed(foo_plugin
));
154 EXPECT_FALSE(observer
->IsPluginTemporarilyAllowed(bar_plugin
));
156 // Simulate a navigation within the page.
157 DidNavigateWithinPage(GetMainFrame(), true);
158 EXPECT_TRUE(observer
->IsPluginTemporarilyAllowed(foo_plugin
));
159 EXPECT_FALSE(observer
->IsPluginTemporarilyAllowed(bar_plugin
));
161 // Navigate to a different page.
162 LoadHTML("<html>Bar</html>");
163 EXPECT_FALSE(observer
->IsPluginTemporarilyAllowed(foo_plugin
));
164 EXPECT_FALSE(observer
->IsPluginTemporarilyAllowed(bar_plugin
));
166 // Temporarily allow all plugins.
167 observer
->OnLoadBlockedPlugins(std::string());
168 EXPECT_TRUE(observer
->IsPluginTemporarilyAllowed(foo_plugin
));
169 EXPECT_TRUE(observer
->IsPluginTemporarilyAllowed(bar_plugin
));
172 TEST_F(ChromeRenderViewTest
, ImagesBlockedByDefault
) {
173 MockContentSettingsObserver
mock_observer(view_
->GetMainRenderFrame());
176 LoadHTML("<html>Foo</html>");
178 // Set the default image blocking setting.
179 RendererContentSettingRules content_setting_rules
;
180 ContentSettingsForOneType
& image_setting_rules
=
181 content_setting_rules
.image_rules
;
182 image_setting_rules
.push_back(
183 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
184 ContentSettingsPattern::Wildcard(),
185 CONTENT_SETTING_BLOCK
,
189 ContentSettingsObserver
* observer
= ContentSettingsObserver::Get(
190 view_
->GetMainRenderFrame());
191 observer
->SetContentSettingRules(&content_setting_rules
);
192 EXPECT_CALL(mock_observer
,
193 OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
, base::string16()));
194 EXPECT_FALSE(observer
->allowImage(true, mock_observer
.image_url_
));
195 ::testing::Mock::VerifyAndClearExpectations(&observer
);
197 // Create an exception which allows the image.
198 image_setting_rules
.insert(
199 image_setting_rules
.begin(),
200 ContentSettingPatternSource(
201 ContentSettingsPattern::Wildcard(),
202 ContentSettingsPattern::FromString(mock_observer
.image_origin_
),
203 CONTENT_SETTING_ALLOW
,
207 EXPECT_CALL(mock_observer
, OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
,
208 base::string16())).Times(0);
209 EXPECT_TRUE(observer
->allowImage(true, mock_observer
.image_url_
));
210 ::testing::Mock::VerifyAndClearExpectations(&observer
);
213 TEST_F(ChromeRenderViewTest
, ImagesAllowedByDefault
) {
214 MockContentSettingsObserver
mock_observer(view_
->GetMainRenderFrame());
217 LoadHTML("<html>Foo</html>");
219 // Set the default image blocking setting.
220 RendererContentSettingRules content_setting_rules
;
221 ContentSettingsForOneType
& image_setting_rules
=
222 content_setting_rules
.image_rules
;
223 image_setting_rules
.push_back(
224 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
225 ContentSettingsPattern::Wildcard(),
226 CONTENT_SETTING_ALLOW
,
230 ContentSettingsObserver
* observer
=
231 ContentSettingsObserver::Get(view_
->GetMainRenderFrame());
232 observer
->SetContentSettingRules(&content_setting_rules
);
233 EXPECT_CALL(mock_observer
, OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
,
234 base::string16())).Times(0);
235 EXPECT_TRUE(observer
->allowImage(true, mock_observer
.image_url_
));
236 ::testing::Mock::VerifyAndClearExpectations(&observer
);
238 // Create an exception which blocks the image.
239 image_setting_rules
.insert(
240 image_setting_rules
.begin(),
241 ContentSettingPatternSource(
242 ContentSettingsPattern::Wildcard(),
243 ContentSettingsPattern::FromString(mock_observer
.image_origin_
),
244 CONTENT_SETTING_BLOCK
,
247 EXPECT_CALL(mock_observer
,
248 OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
, base::string16()));
249 EXPECT_FALSE(observer
->allowImage(true, mock_observer
.image_url_
));
250 ::testing::Mock::VerifyAndClearExpectations(&observer
);
253 TEST_F(ChromeRenderViewTest
, ContentSettingsBlockScripts
) {
254 // Set the content settings for scripts.
255 RendererContentSettingRules content_setting_rules
;
256 ContentSettingsForOneType
& script_setting_rules
=
257 content_setting_rules
.script_rules
;
258 script_setting_rules
.push_back(
259 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
260 ContentSettingsPattern::Wildcard(),
261 CONTENT_SETTING_BLOCK
,
265 ContentSettingsObserver
* observer
=
266 ContentSettingsObserver::Get(view_
->GetMainRenderFrame());
267 observer
->SetContentSettingRules(&content_setting_rules
);
269 // Load a page which contains a script.
270 std::string html
= "<html>"
272 "<script src='data:foo'></script>"
277 LoadHTML(html
.c_str());
279 // Verify that the script was blocked.
280 bool was_blocked
= false;
281 for (size_t i
= 0; i
< render_thread_
->sink().message_count(); ++i
) {
282 const IPC::Message
* msg
= render_thread_
->sink().GetMessageAt(i
);
283 if (msg
->type() == ChromeViewHostMsg_ContentBlocked::ID
)
286 EXPECT_TRUE(was_blocked
);
289 TEST_F(ChromeRenderViewTest
, ContentSettingsAllowScripts
) {
290 // Set the content settings for scripts.
291 RendererContentSettingRules content_setting_rules
;
292 ContentSettingsForOneType
& script_setting_rules
=
293 content_setting_rules
.script_rules
;
294 script_setting_rules
.push_back(
295 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
296 ContentSettingsPattern::Wildcard(),
297 CONTENT_SETTING_ALLOW
,
301 ContentSettingsObserver
* observer
=
302 ContentSettingsObserver::Get(view_
->GetMainRenderFrame());
303 observer
->SetContentSettingRules(&content_setting_rules
);
305 // Load a page which contains a script.
306 std::string html
= "<html>"
308 "<script src='data:foo'></script>"
313 LoadHTML(html
.c_str());
315 // Verify that the script was not blocked.
316 bool was_blocked
= false;
317 for (size_t i
= 0; i
< render_thread_
->sink().message_count(); ++i
) {
318 const IPC::Message
* msg
= render_thread_
->sink().GetMessageAt(i
);
319 if (msg
->type() == ChromeViewHostMsg_ContentBlocked::ID
)
322 EXPECT_FALSE(was_blocked
);
325 TEST_F(ChromeRenderViewTest
, ContentSettingsInterstitialPages
) {
326 MockContentSettingsObserver
mock_observer(view_
->GetMainRenderFrame());
328 RendererContentSettingRules content_setting_rules
;
329 ContentSettingsForOneType
& script_setting_rules
=
330 content_setting_rules
.script_rules
;
331 script_setting_rules
.push_back(
332 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
333 ContentSettingsPattern::Wildcard(),
334 CONTENT_SETTING_BLOCK
,
338 ContentSettingsForOneType
& image_setting_rules
=
339 content_setting_rules
.image_rules
;
340 image_setting_rules
.push_back(
341 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
342 ContentSettingsPattern::Wildcard(),
343 CONTENT_SETTING_BLOCK
,
347 ContentSettingsObserver
* observer
=
348 ContentSettingsObserver::Get(view_
->GetMainRenderFrame());
349 observer
->SetContentSettingRules(&content_setting_rules
);
350 observer
->OnSetAsInterstitial();
352 // Load a page which contains a script.
353 std::string html
= "<html>"
355 "<script src='data:foo'></script>"
360 LoadHTML(html
.c_str());
362 // Verify that the script was allowed.
363 bool was_blocked
= false;
364 for (size_t i
= 0; i
< render_thread_
->sink().message_count(); ++i
) {
365 const IPC::Message
* msg
= render_thread_
->sink().GetMessageAt(i
);
366 if (msg
->type() == ChromeViewHostMsg_ContentBlocked::ID
)
369 EXPECT_FALSE(was_blocked
);
371 // Verify that images are allowed.
372 EXPECT_CALL(mock_observer
, OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
,
373 base::string16())).Times(0);
374 EXPECT_TRUE(observer
->allowImage(true, mock_observer
.image_url_
));
375 ::testing::Mock::VerifyAndClearExpectations(&observer
);