#include "chrome/common/content_settings.h"
#include "chrome/common/render_messages.h"
#include "chrome/renderer/content_settings_observer.h"
#include "chrome/test/base/chrome_render_view_test.h"
#include "content/public/renderer/render_view.h"
#include "ipc/ipc_message_macros.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
using testing::_;
using testing::DeleteArg;
namespace {
class MockContentSettingsObserver : public ContentSettingsObserver {
public:
explicit MockContentSettingsObserver(content::RenderView* render_view);
virtual bool Send(IPC::Message* message);
MOCK_METHOD2(OnContentBlocked,
void(ContentSettingsType, const std::string&));
MOCK_METHOD5(OnAllowDOMStorage,
void(int, const GURL&, const GURL&, bool, IPC::Message*));
GURL image_url_;
std::string image_origin_;
};
MockContentSettingsObserver::MockContentSettingsObserver(
content::RenderView* render_view)
: ContentSettingsObserver(render_view),
image_url_("http://www.foo.com/image.jpg"),
image_origin_("http://www.foo.com") {
}
bool MockContentSettingsObserver::Send(IPC::Message* message) {
IPC_BEGIN_MESSAGE_MAP(MockContentSettingsObserver, *message)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked, OnContentBlocked)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_AllowDOMStorage,
OnAllowDOMStorage)
IPC_MESSAGE_UNHANDLED(ADD_FAILURE())
IPC_END_MESSAGE_MAP()
return RenderViewObserver::Send(message);
}
}
TEST_F(ChromeRenderViewTest, DidBlockContentType) {
MockContentSettingsObserver observer(view_);
EXPECT_CALL(observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES, std::string()));
observer.DidBlockContentType(CONTENT_SETTINGS_TYPE_COOKIES, std::string());
observer.DidBlockContentType(CONTENT_SETTINGS_TYPE_COOKIES, std::string());
::testing::Mock::VerifyAndClearExpectations(&observer);
std::string kFooPlugin = "foo";
std::string kBarPlugin = "bar";
EXPECT_CALL(observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS, kFooPlugin));
EXPECT_CALL(observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS, kBarPlugin));
observer.DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, kFooPlugin);
observer.DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, kBarPlugin);
}
TEST_F(ChromeRenderViewTest, DISABLED_AllowDOMStorage) {
LoadHTML("<html></html>");
MockContentSettingsObserver observer(view_);
ON_CALL(observer,
OnAllowDOMStorage(_, _, _, _, _)).WillByDefault(DeleteArg<4>());
EXPECT_CALL(observer,
OnAllowDOMStorage(_, _, _, _, _));
observer.AllowStorage(view_->GetWebView()->focusedFrame(), true);
observer.AllowStorage(view_->GetWebView()->focusedFrame(), true);
::testing::Mock::VerifyAndClearExpectations(&observer);
}
TEST_F(ChromeRenderViewTest, JSBlockSentAfterPageLoad) {
std::string html = "<html>"
"<head>"
"<script>document.createElement('div');</script>"
"</head>"
"<body>"
"</body>"
"</html>";
render_thread_->sink().ClearMessages();
LoadHTML(html.c_str());
RendererContentSettingRules content_setting_rules;
ContentSettingsForOneType& script_setting_rules =
content_setting_rules.script_rules;
script_setting_rules.push_back(
ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
CONTENT_SETTING_BLOCK,
"",
false));
ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
observer->SetContentSettingRules(&content_setting_rules);
ProcessPendingMessages();
render_thread_->sink().ClearMessages();
std::string url_str = "data:text/html;charset=utf-8,";
url_str.append(html);
GURL url(url_str);
Reload(url);
ProcessPendingMessages();
int navigation_index = -1;
int block_index = -1;
for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
const IPC::Message* msg = render_thread_->sink().GetMessageAt(i);
if (msg->type() == GetNavigationIPCType())
navigation_index = i;
if (msg->type() == ChromeViewHostMsg_ContentBlocked::ID)
block_index = i;
}
EXPECT_NE(-1, navigation_index);
EXPECT_NE(-1, block_index);
EXPECT_LT(navigation_index, block_index);
}
TEST_F(ChromeRenderViewTest, PluginsTemporarilyAllowed) {
LoadHTML("<html>Foo</html>");
std::string foo_plugin = "foo";
std::string bar_plugin = "bar";
ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
EXPECT_FALSE(observer->IsPluginTemporarilyAllowed(foo_plugin));
OnMessageReceived(ChromeViewMsg_LoadBlockedPlugins(MSG_ROUTING_NONE,
foo_plugin));
EXPECT_TRUE(observer->IsPluginTemporarilyAllowed(foo_plugin));
EXPECT_FALSE(observer->IsPluginTemporarilyAllowed(bar_plugin));
DidNavigateWithinPage(GetMainFrame(), true);
EXPECT_TRUE(observer->IsPluginTemporarilyAllowed(foo_plugin));
EXPECT_FALSE(observer->IsPluginTemporarilyAllowed(bar_plugin));
LoadHTML("<html>Bar</html>");
EXPECT_FALSE(observer->IsPluginTemporarilyAllowed(foo_plugin));
EXPECT_FALSE(observer->IsPluginTemporarilyAllowed(bar_plugin));
OnMessageReceived(ChromeViewMsg_LoadBlockedPlugins(MSG_ROUTING_NONE,
std::string()));
EXPECT_TRUE(observer->IsPluginTemporarilyAllowed(foo_plugin));
EXPECT_TRUE(observer->IsPluginTemporarilyAllowed(bar_plugin));
}
TEST_F(ChromeRenderViewTest, ImagesBlockedByDefault) {
MockContentSettingsObserver mock_observer(view_);
LoadHTML("<html>Foo</html>");
RendererContentSettingRules content_setting_rules;
ContentSettingsForOneType& image_setting_rules =
content_setting_rules.image_rules;
image_setting_rules.push_back(
ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
CONTENT_SETTING_BLOCK,
"",
false));
ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
observer->SetContentSettingRules(&content_setting_rules);
EXPECT_CALL(mock_observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string()));
EXPECT_FALSE(observer->AllowImage(GetMainFrame(),
true, mock_observer.image_url_));
::testing::Mock::VerifyAndClearExpectations(&observer);
image_setting_rules.insert(
image_setting_rules.begin(),
ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::FromString(mock_observer.image_origin_),
CONTENT_SETTING_ALLOW,
"",
false));
EXPECT_CALL(
mock_observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string())).Times(0);
EXPECT_TRUE(observer->AllowImage(GetMainFrame(), true,
mock_observer.image_url_));
::testing::Mock::VerifyAndClearExpectations(&observer);
}
TEST_F(ChromeRenderViewTest, ImagesAllowedByDefault) {
MockContentSettingsObserver mock_observer(view_);
LoadHTML("<html>Foo</html>");
RendererContentSettingRules content_setting_rules;
ContentSettingsForOneType& image_setting_rules =
content_setting_rules.image_rules;
image_setting_rules.push_back(
ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
CONTENT_SETTING_ALLOW,
"",
false));
ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
observer->SetContentSettingRules(&content_setting_rules);
EXPECT_CALL(
mock_observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string())).Times(0);
EXPECT_TRUE(observer->AllowImage(GetMainFrame(), true,
mock_observer.image_url_));
::testing::Mock::VerifyAndClearExpectations(&observer);
image_setting_rules.insert(
image_setting_rules.begin(),
ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::FromString(mock_observer.image_origin_),
CONTENT_SETTING_BLOCK,
"",
false));
EXPECT_CALL(mock_observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string()));
EXPECT_FALSE(observer->AllowImage(GetMainFrame(),
true, mock_observer.image_url_));
::testing::Mock::VerifyAndClearExpectations(&observer);
}
TEST_F(ChromeRenderViewTest, ContentSettingsBlockScripts) {
RendererContentSettingRules content_setting_rules;
ContentSettingsForOneType& script_setting_rules =
content_setting_rules.script_rules;
script_setting_rules.push_back(
ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
CONTENT_SETTING_BLOCK,
"",
false));
ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
observer->SetContentSettingRules(&content_setting_rules);
std::string html = "<html>"
"<head>"
"<script src='data:foo'></script>"
"</head>"
"<body>"
"</body>"
"</html>";
LoadHTML(html.c_str());
bool was_blocked = false;
for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
const IPC::Message* msg = render_thread_->sink().GetMessageAt(i);
if (msg->type() == ChromeViewHostMsg_ContentBlocked::ID)
was_blocked = true;
}
EXPECT_TRUE(was_blocked);
}
TEST_F(ChromeRenderViewTest, ContentSettingsAllowScripts) {
RendererContentSettingRules content_setting_rules;
ContentSettingsForOneType& script_setting_rules =
content_setting_rules.script_rules;
script_setting_rules.push_back(
ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
CONTENT_SETTING_ALLOW,
"",
false));
ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
observer->SetContentSettingRules(&content_setting_rules);
std::string html = "<html>"
"<head>"
"<script src='data:foo'></script>"
"</head>"
"<body>"
"</body>"
"</html>";
LoadHTML(html.c_str());
bool was_blocked = false;
for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
const IPC::Message* msg = render_thread_->sink().GetMessageAt(i);
if (msg->type() == ChromeViewHostMsg_ContentBlocked::ID)
was_blocked = true;
}
EXPECT_FALSE(was_blocked);
}
TEST_F(ChromeRenderViewTest, ContentSettingsInterstitialPages) {
MockContentSettingsObserver mock_observer(view_);
RendererContentSettingRules content_setting_rules;
ContentSettingsForOneType& script_setting_rules =
content_setting_rules.script_rules;
script_setting_rules.push_back(
ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
CONTENT_SETTING_BLOCK, "", false));
ContentSettingsForOneType& image_setting_rules =
content_setting_rules.image_rules;
image_setting_rules.push_back(
ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
CONTENT_SETTING_BLOCK, "", false));
ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
observer->SetContentSettingRules(&content_setting_rules);
observer->OnSetAsInterstitial();
std::string html = "<html>"
"<head>"
"<script src='data:foo'></script>"
"</head>"
"<body>"
"</body>"
"</html>";
LoadHTML(html.c_str());
bool was_blocked = false;
for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
const IPC::Message* msg = render_thread_->sink().GetMessageAt(i);
if (msg->type() == ChromeViewHostMsg_ContentBlocked::ID)
was_blocked = true;
}
EXPECT_FALSE(was_blocked);
EXPECT_CALL(
mock_observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string())).Times(0);
EXPECT_TRUE(observer->AllowImage(GetMainFrame(), true,
mock_observer.image_url_));
::testing::Mock::VerifyAndClearExpectations(&observer);
}