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.
4
5#include "base/strings/utf_string_conversions.h"
6#include "chrome/browser/chrome_notification_types.h"
7#include "chrome/browser/content_settings/host_content_settings_map.h"
8#include "chrome/browser/content_settings/tab_specific_content_settings.h"
9#include "chrome/browser/prerender/prerender_manager.h"
10#include "chrome/browser/profiles/profile.h"
11#include "chrome/browser/ui/content_settings/content_setting_image_model.h"
12#include "chrome/test/base/chrome_render_view_host_test_harness.h"
13#include "chrome/test/base/testing_profile.h"
14#include "content/public/browser/notification_observer.h"
15#include "content/public/browser/notification_registrar.h"
16#include "content/public/browser/notification_service.h"
17#include "content/public/test/test_renderer_host.h"
18#include "net/cookies/cookie_options.h"
19#include "testing/gtest/include/gtest/gtest.h"
20
21namespace {
22
23// Forward all NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED to the specified
24// ContentSettingImageModel.
25class NotificationForwarder : public content::NotificationObserver {
26 public:
27  explicit NotificationForwarder(ContentSettingImageModel* model)
28      : model_(model) {
29    registrar_.Add(this,
30                   chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
31                   content::NotificationService::AllSources());
32  }
33  virtual ~NotificationForwarder() {}
34
35  void clear() {
36    registrar_.RemoveAll();
37  }
38
39  virtual void Observe(int type,
40                       const content::NotificationSource& source,
41                       const content::NotificationDetails& details) OVERRIDE {
42    if (type == chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED) {
43      model_->UpdateFromWebContents(
44          content::Source<content::WebContents>(source).ptr());
45    }
46  }
47
48 private:
49  content::NotificationRegistrar registrar_;
50  ContentSettingImageModel* model_;
51
52  DISALLOW_COPY_AND_ASSIGN(NotificationForwarder);
53};
54
55class ContentSettingImageModelTest : public ChromeRenderViewHostTestHarness {
56};
57
58TEST_F(ContentSettingImageModelTest, UpdateFromWebContents) {
59  TabSpecificContentSettings::CreateForWebContents(web_contents());
60  TabSpecificContentSettings* content_settings =
61      TabSpecificContentSettings::FromWebContents(web_contents());
62  scoped_ptr<ContentSettingImageModel> content_setting_image_model(
63     ContentSettingImageModel::CreateContentSettingImageModel(
64         CONTENT_SETTINGS_TYPE_IMAGES));
65  EXPECT_FALSE(content_setting_image_model->is_visible());
66  EXPECT_EQ(0, content_setting_image_model->get_icon());
67  EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
68
69  content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES);
70  content_setting_image_model->UpdateFromWebContents(web_contents());
71
72  EXPECT_TRUE(content_setting_image_model->is_visible());
73  EXPECT_NE(0, content_setting_image_model->get_icon());
74  EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
75}
76
77TEST_F(ContentSettingImageModelTest, RPHUpdateFromWebContents) {
78  TabSpecificContentSettings::CreateForWebContents(web_contents());
79  scoped_ptr<ContentSettingImageModel> content_setting_image_model(
80     ContentSettingImageModel::CreateContentSettingImageModel(
81         CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS));
82  content_setting_image_model->UpdateFromWebContents(web_contents());
83  EXPECT_FALSE(content_setting_image_model->is_visible());
84
85  TabSpecificContentSettings* content_settings =
86      TabSpecificContentSettings::FromWebContents(web_contents());
87  content_settings->set_pending_protocol_handler(
88      ProtocolHandler::CreateProtocolHandler(
89          "mailto", GURL("http://www.google.com/")));
90  content_setting_image_model->UpdateFromWebContents(web_contents());
91  EXPECT_TRUE(content_setting_image_model->is_visible());
92}
93
94TEST_F(ContentSettingImageModelTest, CookieAccessed) {
95  TabSpecificContentSettings::CreateForWebContents(web_contents());
96  TabSpecificContentSettings* content_settings =
97      TabSpecificContentSettings::FromWebContents(web_contents());
98  profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
99      CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_BLOCK);
100  scoped_ptr<ContentSettingImageModel> content_setting_image_model(
101     ContentSettingImageModel::CreateContentSettingImageModel(
102         CONTENT_SETTINGS_TYPE_COOKIES));
103  EXPECT_FALSE(content_setting_image_model->is_visible());
104  EXPECT_EQ(0, content_setting_image_model->get_icon());
105  EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
106
107  net::CookieOptions options;
108  content_settings->OnCookieChanged(GURL("http://google.com"),
109                                    GURL("http://google.com"),
110                                    "A=B",
111                                    options,
112                                    false);
113  content_setting_image_model->UpdateFromWebContents(web_contents());
114  EXPECT_TRUE(content_setting_image_model->is_visible());
115  EXPECT_NE(0, content_setting_image_model->get_icon());
116  EXPECT_FALSE(content_setting_image_model->get_tooltip().empty());
117}
118
119// Regression test for http://crbug.com/161854.
120TEST_F(ContentSettingImageModelTest, NULLTabSpecificContentSettings) {
121  scoped_ptr<ContentSettingImageModel> content_setting_image_model(
122     ContentSettingImageModel::CreateContentSettingImageModel(
123         CONTENT_SETTINGS_TYPE_IMAGES));
124  NotificationForwarder forwarder(content_setting_image_model.get());
125  // Should not crash.
126  TabSpecificContentSettings::CreateForWebContents(web_contents());
127  forwarder.clear();
128}
129
130}  // namespace
131