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 "content/public/renderer/render_view.h"
10 #include "ipc/ipc_message_macros.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/WebKit/public/web/WebView.h"
16 using testing::DeleteArg
;
20 class MockContentSettingsObserver
: public ContentSettingsObserver
{
22 explicit MockContentSettingsObserver(content::RenderFrame
* render_frame
);
24 virtual bool Send(IPC::Message
* message
);
26 MOCK_METHOD1(OnContentBlocked
,
27 void(ContentSettingsType
));
29 MOCK_METHOD5(OnAllowDOMStorage
,
30 void(int, const GURL
&, const GURL
&, bool, IPC::Message
*));
32 std::string image_origin_
;
35 MockContentSettingsObserver::MockContentSettingsObserver(
36 content::RenderFrame
* render_frame
)
37 : ContentSettingsObserver(render_frame
, NULL
),
38 image_url_("http://www.foo.com/image.jpg"),
39 image_origin_("http://www.foo.com") {
42 bool MockContentSettingsObserver::Send(IPC::Message
* message
) {
43 IPC_BEGIN_MESSAGE_MAP(MockContentSettingsObserver
, *message
)
44 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked
, OnContentBlocked
)
45 IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_AllowDOMStorage
,
47 IPC_MESSAGE_UNHANDLED(ADD_FAILURE())
50 // Our super class deletes the message.
51 return RenderFrameObserver::Send(message
);
56 TEST_F(ChromeRenderViewTest
, DidBlockContentType
) {
57 MockContentSettingsObserver
observer(view_
->GetMainRenderFrame());
59 OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
));
60 observer
.DidBlockContentType(CONTENT_SETTINGS_TYPE_COOKIES
);
62 // Blocking the same content type a second time shouldn't send a notification.
63 observer
.DidBlockContentType(CONTENT_SETTINGS_TYPE_COOKIES
);
64 ::testing::Mock::VerifyAndClearExpectations(&observer
);
67 // Tests that multiple invokations of AllowDOMStorage result in a single IPC.
68 // Fails due to http://crbug.com/104300
69 TEST_F(ChromeRenderViewTest
, DISABLED_AllowDOMStorage
) {
70 // Load some HTML, so we have a valid security origin.
71 LoadHTML("<html></html>");
72 MockContentSettingsObserver
observer(view_
->GetMainRenderFrame());
74 OnAllowDOMStorage(_
, _
, _
, _
, _
)).WillByDefault(DeleteArg
<4>());
76 OnAllowDOMStorage(_
, _
, _
, _
, _
));
77 observer
.allowStorage(true);
79 // Accessing localStorage from the same origin again shouldn't result in a
81 observer
.allowStorage(true);
82 ::testing::Mock::VerifyAndClearExpectations(&observer
);
85 // Regression test for http://crbug.com/35011
86 TEST_F(ChromeRenderViewTest
, JSBlockSentAfterPageLoad
) {
87 // 1. Load page with JS.
88 std::string html
= "<html>"
90 "<script>document.createElement('div');</script>"
95 render_thread_
->sink().ClearMessages();
96 LoadHTML(html
.c_str());
98 // 2. Block JavaScript.
99 RendererContentSettingRules content_setting_rules
;
100 ContentSettingsForOneType
& script_setting_rules
=
101 content_setting_rules
.script_rules
;
102 script_setting_rules
.push_back(
103 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
104 ContentSettingsPattern::Wildcard(),
105 CONTENT_SETTING_BLOCK
,
108 ContentSettingsObserver
* observer
= ContentSettingsObserver::Get(
109 view_
->GetMainRenderFrame());
110 observer
->SetContentSettingRules(&content_setting_rules
);
112 // Make sure no pending messages are in the queue.
113 ProcessPendingMessages();
114 render_thread_
->sink().ClearMessages();
117 std::string url_str
= "data:text/html;charset=utf-8,";
118 url_str
.append(html
);
121 ProcessPendingMessages();
123 // 4. Verify that the notification that javascript was blocked is sent after
124 // the navigation notification is sent.
125 int navigation_index
= -1;
126 int block_index
= -1;
127 for (size_t i
= 0; i
< render_thread_
->sink().message_count(); ++i
) {
128 const IPC::Message
* msg
= render_thread_
->sink().GetMessageAt(i
);
129 if (msg
->type() == GetNavigationIPCType())
130 navigation_index
= i
;
131 if (msg
->type() == ChromeViewHostMsg_ContentBlocked::ID
)
134 EXPECT_NE(-1, navigation_index
);
135 EXPECT_NE(-1, block_index
);
136 EXPECT_LT(navigation_index
, block_index
);
139 TEST_F(ChromeRenderViewTest
, PluginsTemporarilyAllowed
) {
141 LoadHTML("<html>Foo</html>");
143 std::string foo_plugin
= "foo";
144 std::string bar_plugin
= "bar";
146 ContentSettingsObserver
* observer
=
147 ContentSettingsObserver::Get(view_
->GetMainRenderFrame());
148 EXPECT_FALSE(observer
->IsPluginTemporarilyAllowed(foo_plugin
));
150 // Temporarily allow the "foo" plugin.
151 observer
->OnLoadBlockedPlugins(foo_plugin
);
152 EXPECT_TRUE(observer
->IsPluginTemporarilyAllowed(foo_plugin
));
153 EXPECT_FALSE(observer
->IsPluginTemporarilyAllowed(bar_plugin
));
155 // Simulate a navigation within the page.
156 DidNavigateWithinPage(GetMainFrame(), true);
157 EXPECT_TRUE(observer
->IsPluginTemporarilyAllowed(foo_plugin
));
158 EXPECT_FALSE(observer
->IsPluginTemporarilyAllowed(bar_plugin
));
160 // Navigate to a different page.
161 LoadHTML("<html>Bar</html>");
162 EXPECT_FALSE(observer
->IsPluginTemporarilyAllowed(foo_plugin
));
163 EXPECT_FALSE(observer
->IsPluginTemporarilyAllowed(bar_plugin
));
165 // Temporarily allow all plugins.
166 observer
->OnLoadBlockedPlugins(std::string());
167 EXPECT_TRUE(observer
->IsPluginTemporarilyAllowed(foo_plugin
));
168 EXPECT_TRUE(observer
->IsPluginTemporarilyAllowed(bar_plugin
));
171 TEST_F(ChromeRenderViewTest
, ImagesBlockedByDefault
) {
172 MockContentSettingsObserver
mock_observer(view_
->GetMainRenderFrame());
175 LoadHTML("<html>Foo</html>");
177 // Set the default image blocking setting.
178 RendererContentSettingRules content_setting_rules
;
179 ContentSettingsForOneType
& image_setting_rules
=
180 content_setting_rules
.image_rules
;
181 image_setting_rules
.push_back(
182 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
183 ContentSettingsPattern::Wildcard(),
184 CONTENT_SETTING_BLOCK
,
188 ContentSettingsObserver
* observer
= ContentSettingsObserver::Get(
189 view_
->GetMainRenderFrame());
190 observer
->SetContentSettingRules(&content_setting_rules
);
191 EXPECT_CALL(mock_observer
,
192 OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
));
193 EXPECT_FALSE(observer
->allowImage(true, mock_observer
.image_url_
));
194 ::testing::Mock::VerifyAndClearExpectations(&observer
);
196 // Create an exception which allows the image.
197 image_setting_rules
.insert(
198 image_setting_rules
.begin(),
199 ContentSettingPatternSource(
200 ContentSettingsPattern::Wildcard(),
201 ContentSettingsPattern::FromString(mock_observer
.image_origin_
),
202 CONTENT_SETTING_ALLOW
,
208 OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
)).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
);
235 OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
)).Times(0);
236 EXPECT_TRUE(observer
->allowImage(true, mock_observer
.image_url_
));
237 ::testing::Mock::VerifyAndClearExpectations(&observer
);
239 // Create an exception which blocks the image.
240 image_setting_rules
.insert(
241 image_setting_rules
.begin(),
242 ContentSettingPatternSource(
243 ContentSettingsPattern::Wildcard(),
244 ContentSettingsPattern::FromString(mock_observer
.image_origin_
),
245 CONTENT_SETTING_BLOCK
,
248 EXPECT_CALL(mock_observer
,
249 OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
));
250 EXPECT_FALSE(observer
->allowImage(true, mock_observer
.image_url_
));
251 ::testing::Mock::VerifyAndClearExpectations(&observer
);
254 TEST_F(ChromeRenderViewTest
, ContentSettingsBlockScripts
) {
255 // Set the content settings for scripts.
256 RendererContentSettingRules content_setting_rules
;
257 ContentSettingsForOneType
& script_setting_rules
=
258 content_setting_rules
.script_rules
;
259 script_setting_rules
.push_back(
260 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
261 ContentSettingsPattern::Wildcard(),
262 CONTENT_SETTING_BLOCK
,
266 ContentSettingsObserver
* observer
=
267 ContentSettingsObserver::Get(view_
->GetMainRenderFrame());
268 observer
->SetContentSettingRules(&content_setting_rules
);
270 // Load a page which contains a script.
271 std::string html
= "<html>"
273 "<script src='data:foo'></script>"
278 LoadHTML(html
.c_str());
280 // Verify that the script was blocked.
281 bool was_blocked
= false;
282 for (size_t i
= 0; i
< render_thread_
->sink().message_count(); ++i
) {
283 const IPC::Message
* msg
= render_thread_
->sink().GetMessageAt(i
);
284 if (msg
->type() == ChromeViewHostMsg_ContentBlocked::ID
)
287 EXPECT_TRUE(was_blocked
);
290 TEST_F(ChromeRenderViewTest
, ContentSettingsAllowScripts
) {
291 // Set the content settings for scripts.
292 RendererContentSettingRules content_setting_rules
;
293 ContentSettingsForOneType
& script_setting_rules
=
294 content_setting_rules
.script_rules
;
295 script_setting_rules
.push_back(
296 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
297 ContentSettingsPattern::Wildcard(),
298 CONTENT_SETTING_ALLOW
,
302 ContentSettingsObserver
* observer
=
303 ContentSettingsObserver::Get(view_
->GetMainRenderFrame());
304 observer
->SetContentSettingRules(&content_setting_rules
);
306 // Load a page which contains a script.
307 std::string html
= "<html>"
309 "<script src='data:foo'></script>"
314 LoadHTML(html
.c_str());
316 // Verify that the script was not blocked.
317 bool was_blocked
= false;
318 for (size_t i
= 0; i
< render_thread_
->sink().message_count(); ++i
) {
319 const IPC::Message
* msg
= render_thread_
->sink().GetMessageAt(i
);
320 if (msg
->type() == ChromeViewHostMsg_ContentBlocked::ID
)
323 EXPECT_FALSE(was_blocked
);
326 TEST_F(ChromeRenderViewTest
, ContentSettingsInterstitialPages
) {
327 MockContentSettingsObserver
mock_observer(view_
->GetMainRenderFrame());
329 RendererContentSettingRules content_setting_rules
;
330 ContentSettingsForOneType
& script_setting_rules
=
331 content_setting_rules
.script_rules
;
332 script_setting_rules
.push_back(
333 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
334 ContentSettingsPattern::Wildcard(),
335 CONTENT_SETTING_BLOCK
,
339 ContentSettingsForOneType
& image_setting_rules
=
340 content_setting_rules
.image_rules
;
341 image_setting_rules
.push_back(
342 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
343 ContentSettingsPattern::Wildcard(),
344 CONTENT_SETTING_BLOCK
,
348 ContentSettingsObserver
* observer
=
349 ContentSettingsObserver::Get(view_
->GetMainRenderFrame());
350 observer
->SetContentSettingRules(&content_setting_rules
);
351 observer
->OnSetAsInterstitial();
353 // Load a page which contains a script.
354 std::string html
= "<html>"
356 "<script src='data:foo'></script>"
361 LoadHTML(html
.c_str());
363 // Verify that the script was allowed.
364 bool was_blocked
= false;
365 for (size_t i
= 0; i
< render_thread_
->sink().message_count(); ++i
) {
366 const IPC::Message
* msg
= render_thread_
->sink().GetMessageAt(i
);
367 if (msg
->type() == ChromeViewHostMsg_ContentBlocked::ID
)
370 EXPECT_FALSE(was_blocked
);
372 // Verify that images are allowed.
375 OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
)).Times(0);
376 EXPECT_TRUE(observer
->allowImage(true, mock_observer
.image_url_
));
377 ::testing::Mock::VerifyAndClearExpectations(&observer
);