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/auto_reset.h"
6#include "base/command_line.h"
7#include "base/strings/utf_string_conversions.h"
8#include "chrome/browser/content_settings/host_content_settings_map.h"
9#include "chrome/browser/content_settings/tab_specific_content_settings.h"
10#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
11#include "chrome/browser/infobars/infobar_delegate.h"
12#include "chrome/browser/infobars/infobar_service.h"
13#include "chrome/browser/media/media_capture_devices_dispatcher.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
16#include "chrome/common/chrome_switches.h"
17#include "chrome/common/content_settings.h"
18#include "chrome/test/base/chrome_render_view_host_test_harness.h"
19#include "chrome/test/base/testing_profile.h"
20#include "content/public/browser/web_contents.h"
21#include "content/public/test/web_contents_tester.h"
22#include "grit/generated_resources.h"
23#include "testing/gtest/include/gtest/gtest.h"
24#include "ui/base/l10n/l10n_util.h"
25
26using content::WebContentsTester;
27
28class ContentSettingBubbleModelTest : public ChromeRenderViewHostTestHarness {
29 protected:
30  virtual void SetUp() OVERRIDE {
31    ChromeRenderViewHostTestHarness::SetUp();
32    TabSpecificContentSettings::CreateForWebContents(web_contents());
33    InfoBarService::CreateForWebContents(web_contents());
34  }
35
36  void CheckGeolocationBubble(size_t expected_domains,
37                              bool expect_clear_link,
38                              bool expect_reload_hint) {
39    scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
40        ContentSettingBubbleModel::CreateContentSettingBubbleModel(
41            NULL, web_contents(), profile(),
42            CONTENT_SETTINGS_TYPE_GEOLOCATION));
43    const ContentSettingBubbleModel::BubbleContent& bubble_content =
44        content_setting_bubble_model->bubble_content();
45    EXPECT_TRUE(bubble_content.title.empty());
46    EXPECT_TRUE(bubble_content.radio_group.radio_items.empty());
47    EXPECT_TRUE(bubble_content.popup_items.empty());
48    EXPECT_EQ(expected_domains, bubble_content.domain_lists.size());
49    EXPECT_NE(expect_clear_link || expect_reload_hint,
50              bubble_content.custom_link.empty());
51    EXPECT_EQ(expect_clear_link, bubble_content.custom_link_enabled);
52    EXPECT_FALSE(bubble_content.manage_link.empty());
53  }
54};
55
56TEST_F(ContentSettingBubbleModelTest, ImageRadios) {
57  TabSpecificContentSettings* content_settings =
58      TabSpecificContentSettings::FromWebContents(web_contents());
59  content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES);
60
61  scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
62      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
63         NULL, web_contents(), profile(),
64         CONTENT_SETTINGS_TYPE_IMAGES));
65  const ContentSettingBubbleModel::BubbleContent& bubble_content =
66      content_setting_bubble_model->bubble_content();
67  EXPECT_FALSE(bubble_content.title.empty());
68  EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
69  EXPECT_EQ(0, bubble_content.radio_group.default_item);
70  EXPECT_TRUE(bubble_content.custom_link.empty());
71  EXPECT_FALSE(bubble_content.manage_link.empty());
72}
73
74TEST_F(ContentSettingBubbleModelTest, Cookies) {
75  TabSpecificContentSettings* content_settings =
76      TabSpecificContentSettings::FromWebContents(web_contents());
77  content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
78
79  scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
80      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
81          NULL, web_contents(), profile(), CONTENT_SETTINGS_TYPE_COOKIES));
82  const ContentSettingBubbleModel::BubbleContent& bubble_content =
83      content_setting_bubble_model->bubble_content();
84  std::string title = bubble_content.title;
85  EXPECT_FALSE(title.empty());
86  ASSERT_EQ(2U, bubble_content.radio_group.radio_items.size());
87  std::string radio1 = bubble_content.radio_group.radio_items[0];
88  std::string radio2 = bubble_content.radio_group.radio_items[1];
89  EXPECT_FALSE(bubble_content.custom_link.empty());
90  EXPECT_TRUE(bubble_content.custom_link_enabled);
91  EXPECT_FALSE(bubble_content.manage_link.empty());
92
93  content_settings->ClearCookieSpecificContentSettings();
94  content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
95  content_setting_bubble_model.reset(
96      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
97          NULL, web_contents(), profile(), CONTENT_SETTINGS_TYPE_COOKIES));
98  const ContentSettingBubbleModel::BubbleContent& bubble_content_2 =
99      content_setting_bubble_model->bubble_content();
100
101  EXPECT_FALSE(bubble_content_2.title.empty());
102  EXPECT_NE(title, bubble_content_2.title);
103  ASSERT_EQ(2U, bubble_content_2.radio_group.radio_items.size());
104  // TODO(bauerb): Update this once the strings have been updated.
105  EXPECT_EQ(radio1, bubble_content_2.radio_group.radio_items[0]);
106  EXPECT_EQ(radio2, bubble_content_2.radio_group.radio_items[1]);
107  EXPECT_FALSE(bubble_content_2.custom_link.empty());
108  EXPECT_TRUE(bubble_content_2.custom_link_enabled);
109  EXPECT_FALSE(bubble_content_2.manage_link.empty());
110}
111
112TEST_F(ContentSettingBubbleModelTest, MediastreamMicAndCamera) {
113  // Required to break dependency on BrowserMainLoop.
114  MediaCaptureDevicesDispatcher::GetInstance()->
115      DisableDeviceEnumerationForTesting();
116
117  TabSpecificContentSettings* content_settings =
118      TabSpecificContentSettings::FromWebContents(web_contents());
119  std::string request_host = "google.com";
120  GURL security_origin("http://" + request_host);
121  MediaStreamDevicesController::MediaStreamTypeSettingsMap
122      request_permissions;
123  request_permissions[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
124      MediaStreamDevicesController::MEDIA_ALLOWED;
125  request_permissions[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
126      MediaStreamDevicesController::MEDIA_ALLOWED;
127  content_settings->OnMediaStreamPermissionSet(security_origin,
128                                               request_permissions);
129
130  scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
131      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
132         NULL, web_contents(), profile(),
133         CONTENT_SETTINGS_TYPE_MEDIASTREAM));
134  const ContentSettingBubbleModel::BubbleContent& bubble_content =
135      content_setting_bubble_model->bubble_content();
136  EXPECT_EQ(bubble_content.title,
137            l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED));
138  EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
139  EXPECT_EQ(bubble_content.radio_group.radio_items[0],
140            l10n_util::GetStringFUTF8(
141                IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION,
142                UTF8ToUTF16(request_host)));
143  EXPECT_EQ(bubble_content.radio_group.radio_items[1],
144            l10n_util::GetStringUTF8(
145                IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK));
146  EXPECT_EQ(0, bubble_content.radio_group.default_item);
147  EXPECT_TRUE(bubble_content.custom_link.empty());
148  EXPECT_FALSE(bubble_content.custom_link_enabled);
149  EXPECT_FALSE(bubble_content.manage_link.empty());
150  EXPECT_EQ(2U, bubble_content.media_menus.size());
151}
152
153TEST_F(ContentSettingBubbleModelTest, BlockedMediastreamMicAndCamera) {
154  // Required to break dependency on BrowserMainLoop.
155  MediaCaptureDevicesDispatcher::GetInstance()->
156      DisableDeviceEnumerationForTesting();
157
158  WebContentsTester::For(web_contents())->
159      NavigateAndCommit(GURL("https://www.example.com"));
160  GURL url = web_contents()->GetURL();
161
162  HostContentSettingsMap* host_content_settings_map =
163      profile()->GetHostContentSettingsMap();
164  ContentSettingsPattern primary_pattern =
165      ContentSettingsPattern::FromURL(url);
166  ContentSetting setting = CONTENT_SETTING_BLOCK;
167  host_content_settings_map->SetContentSetting(
168        primary_pattern,
169        ContentSettingsPattern::Wildcard(),
170        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
171        std::string(),
172        setting);
173  host_content_settings_map->SetContentSetting(
174        primary_pattern,
175        ContentSettingsPattern::Wildcard(),
176        CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
177        std::string(),
178        setting);
179
180  TabSpecificContentSettings* content_settings =
181      TabSpecificContentSettings::FromWebContents(web_contents());
182  MediaStreamDevicesController::MediaStreamTypeSettingsMap
183      request_permissions;
184  request_permissions[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
185      MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER;
186  request_permissions[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
187      MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER;
188  content_settings->OnMediaStreamPermissionSet(url, request_permissions);
189  {
190    scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
191        ContentSettingBubbleModel::CreateContentSettingBubbleModel(
192           NULL, web_contents(), profile(),
193           CONTENT_SETTINGS_TYPE_MEDIASTREAM));
194    const ContentSettingBubbleModel::BubbleContent& bubble_content =
195        content_setting_bubble_model->bubble_content();
196    // Test if the correct radio item is selected for the blocked mediastream
197    // setting.
198    EXPECT_EQ(1, bubble_content.radio_group.default_item);
199  }
200
201  // Test that the media settings where not changed.
202  EXPECT_EQ(CONTENT_SETTING_BLOCK,
203            host_content_settings_map->GetContentSetting(
204                url,
205                url,
206                CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
207                std::string()));
208  EXPECT_EQ(CONTENT_SETTING_BLOCK,
209            host_content_settings_map->GetContentSetting(
210                url,
211                url,
212                CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
213                std::string()));
214
215  {
216    scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
217        ContentSettingBubbleModel::CreateContentSettingBubbleModel(
218           NULL, web_contents(), profile(),
219           CONTENT_SETTINGS_TYPE_MEDIASTREAM));
220    // Change the radio setting.
221    content_setting_bubble_model->OnRadioClicked(0);
222  }
223  // Test that the media setting were change correctly.
224  EXPECT_EQ(CONTENT_SETTING_ALLOW,
225            host_content_settings_map->GetContentSetting(
226                url,
227                url,
228                CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
229                std::string()));
230  EXPECT_EQ(CONTENT_SETTING_ALLOW,
231            host_content_settings_map->GetContentSetting(
232                url,
233                url,
234                CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
235                std::string()));
236
237  InfoBarService* infobar_service =
238      InfoBarService::FromWebContents(web_contents());
239  infobar_service->RemoveInfoBar(infobar_service->infobar_at(0));
240}
241
242TEST_F(ContentSettingBubbleModelTest, MediastreamMic) {
243  // Required to break dependency on BrowserMainLoop.
244  MediaCaptureDevicesDispatcher::GetInstance()->
245      DisableDeviceEnumerationForTesting();
246
247  TabSpecificContentSettings* content_settings =
248      TabSpecificContentSettings::FromWebContents(web_contents());
249  std::string request_host = "google.com";
250  GURL security_origin("http://" + request_host);
251  MediaStreamDevicesController::MediaStreamTypeSettingsMap
252      request_permissions;
253  request_permissions[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
254      MediaStreamDevicesController::MEDIA_ALLOWED;
255  content_settings->OnMediaStreamPermissionSet(security_origin,
256                                               request_permissions);
257
258  scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
259      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
260          NULL, web_contents(), profile(),
261          CONTENT_SETTINGS_TYPE_MEDIASTREAM));
262  const ContentSettingBubbleModel::BubbleContent& bubble_content =
263      content_setting_bubble_model->bubble_content();
264  EXPECT_EQ(bubble_content.title,
265            l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED));
266  EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
267  EXPECT_EQ(bubble_content.radio_group.radio_items[0],
268            l10n_util::GetStringFUTF8(
269                IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION,
270                UTF8ToUTF16(request_host)));
271  EXPECT_EQ(bubble_content.radio_group.radio_items[1],
272            l10n_util::GetStringUTF8(
273                IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK));
274  EXPECT_EQ(0, bubble_content.radio_group.default_item);
275  EXPECT_TRUE(bubble_content.custom_link.empty());
276  EXPECT_FALSE(bubble_content.custom_link_enabled);
277  EXPECT_FALSE(bubble_content.manage_link.empty());
278  EXPECT_EQ(1U, bubble_content.media_menus.size());
279  EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE,
280            bubble_content.media_menus.begin()->first);
281
282  // Change the microphone access.
283  request_permissions[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
284      MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER;
285  content_settings->OnMediaStreamPermissionSet(security_origin,
286                                               request_permissions);
287  content_setting_bubble_model.reset(
288      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
289          NULL, web_contents(), profile(),
290          CONTENT_SETTINGS_TYPE_MEDIASTREAM));
291  const ContentSettingBubbleModel::BubbleContent& new_bubble_content =
292      content_setting_bubble_model->bubble_content();
293  EXPECT_EQ(new_bubble_content.title,
294            l10n_util::GetStringUTF8(IDS_MICROPHONE_BLOCKED));
295  EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size());
296  EXPECT_EQ(new_bubble_content.radio_group.radio_items[0],
297            l10n_util::GetStringFUTF8(
298                IDS_BLOCKED_MEDIASTREAM_MIC_ASK,
299                UTF8ToUTF16(request_host)));
300  EXPECT_EQ(new_bubble_content.radio_group.radio_items[1],
301            l10n_util::GetStringUTF8(
302                IDS_BLOCKED_MEDIASTREAM_MIC_NO_ACTION));
303  EXPECT_EQ(1, new_bubble_content.radio_group.default_item);
304  EXPECT_TRUE(new_bubble_content.custom_link.empty());
305  EXPECT_FALSE(new_bubble_content.custom_link_enabled);
306  EXPECT_FALSE(new_bubble_content.manage_link.empty());
307  EXPECT_EQ(1U, new_bubble_content.media_menus.size());
308  EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE,
309            new_bubble_content.media_menus.begin()->first);
310}
311
312TEST_F(ContentSettingBubbleModelTest, MediastreamCamera) {
313  // Required to break dependency on BrowserMainLoop.
314  MediaCaptureDevicesDispatcher::GetInstance()->
315      DisableDeviceEnumerationForTesting();
316
317  TabSpecificContentSettings* content_settings =
318      TabSpecificContentSettings::FromWebContents(web_contents());
319  std::string request_host = "google.com";
320  GURL security_origin("http://" + request_host);
321  MediaStreamDevicesController::MediaStreamTypeSettingsMap
322      request_permissions;
323  request_permissions[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
324      MediaStreamDevicesController::MEDIA_ALLOWED;
325  content_settings->OnMediaStreamPermissionSet(security_origin,
326                                               request_permissions);
327
328  scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
329      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
330          NULL, web_contents(), profile(),
331          CONTENT_SETTINGS_TYPE_MEDIASTREAM));
332  const ContentSettingBubbleModel::BubbleContent& bubble_content =
333      content_setting_bubble_model->bubble_content();
334  EXPECT_EQ(bubble_content.title,
335            l10n_util::GetStringUTF8(IDS_CAMERA_ACCESSED));
336  EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
337  EXPECT_EQ(bubble_content.radio_group.radio_items[0],
338            l10n_util::GetStringFUTF8(
339                IDS_ALLOWED_MEDIASTREAM_CAMERA_NO_ACTION,
340                UTF8ToUTF16(request_host)));
341  EXPECT_EQ(bubble_content.radio_group.radio_items[1],
342            l10n_util::GetStringUTF8(
343                IDS_ALLOWED_MEDIASTREAM_CAMERA_BLOCK));
344  EXPECT_EQ(0, bubble_content.radio_group.default_item);
345  EXPECT_TRUE(bubble_content.custom_link.empty());
346  EXPECT_FALSE(bubble_content.custom_link_enabled);
347  EXPECT_FALSE(bubble_content.manage_link.empty());
348  EXPECT_EQ(1U, bubble_content.media_menus.size());
349  EXPECT_EQ(content::MEDIA_DEVICE_VIDEO_CAPTURE,
350            bubble_content.media_menus.begin()->first);
351
352  // Change the camera access.
353  request_permissions[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
354      MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER;
355  content_settings->OnMediaStreamPermissionSet(security_origin,
356                                               request_permissions);
357  content_setting_bubble_model.reset(
358      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
359          NULL, web_contents(), profile(),
360          CONTENT_SETTINGS_TYPE_MEDIASTREAM));
361  const ContentSettingBubbleModel::BubbleContent& new_bubble_content =
362      content_setting_bubble_model->bubble_content();
363  EXPECT_EQ(new_bubble_content.title,
364            l10n_util::GetStringUTF8(IDS_CAMERA_BLOCKED));
365  EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size());
366  EXPECT_EQ(new_bubble_content.radio_group.radio_items[0],
367            l10n_util::GetStringFUTF8(
368                IDS_BLOCKED_MEDIASTREAM_CAMERA_ASK,
369                UTF8ToUTF16(request_host)));
370  EXPECT_EQ(new_bubble_content.radio_group.radio_items[1],
371            l10n_util::GetStringUTF8(
372                IDS_BLOCKED_MEDIASTREAM_CAMERA_NO_ACTION));
373  EXPECT_EQ(1, new_bubble_content.radio_group.default_item);
374  EXPECT_TRUE(new_bubble_content.custom_link.empty());
375  EXPECT_FALSE(new_bubble_content.custom_link_enabled);
376  EXPECT_FALSE(new_bubble_content.manage_link.empty());
377  EXPECT_EQ(1U, new_bubble_content.media_menus.size());
378  EXPECT_EQ(content::MEDIA_DEVICE_VIDEO_CAPTURE,
379            new_bubble_content.media_menus.begin()->first);
380}
381
382TEST_F(ContentSettingBubbleModelTest, AccumulateMediastreamMicAndCamera) {
383  // Required to break dependency on BrowserMainLoop.
384  MediaCaptureDevicesDispatcher::GetInstance()->
385      DisableDeviceEnumerationForTesting();
386
387  TabSpecificContentSettings* content_settings =
388      TabSpecificContentSettings::FromWebContents(web_contents());
389  std::string request_host = "google.com";
390  GURL security_origin("http://" + request_host);
391
392  // Firstly, add microphone access.
393  MediaStreamDevicesController::MediaStreamTypeSettingsMap
394      request_permissions;
395  request_permissions[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
396      MediaStreamDevicesController::MEDIA_ALLOWED;
397  content_settings->OnMediaStreamPermissionSet(security_origin,
398                                               request_permissions);
399
400  scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
401      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
402          NULL, web_contents(), profile(),
403          CONTENT_SETTINGS_TYPE_MEDIASTREAM));
404  const ContentSettingBubbleModel::BubbleContent& bubble_content =
405      content_setting_bubble_model->bubble_content();
406  EXPECT_EQ(bubble_content.title,
407            l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED));
408  EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
409  EXPECT_EQ(bubble_content.radio_group.radio_items[0],
410            l10n_util::GetStringFUTF8(
411                IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION,
412                UTF8ToUTF16(request_host)));
413  EXPECT_EQ(bubble_content.radio_group.radio_items[1],
414            l10n_util::GetStringUTF8(
415                IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK));
416  EXPECT_EQ(0, bubble_content.radio_group.default_item);
417  EXPECT_EQ(1U, bubble_content.media_menus.size());
418  EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE,
419            bubble_content.media_menus.begin()->first);
420
421  // Then add camera access.
422  request_permissions[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
423      MediaStreamDevicesController::MEDIA_ALLOWED;
424  content_settings->OnMediaStreamPermissionSet(security_origin,
425                                               request_permissions);
426
427  content_setting_bubble_model.reset(
428      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
429          NULL, web_contents(), profile(),
430          CONTENT_SETTINGS_TYPE_MEDIASTREAM));
431  const ContentSettingBubbleModel::BubbleContent& new_bubble_content =
432      content_setting_bubble_model->bubble_content();
433  EXPECT_EQ(new_bubble_content.title,
434            l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED));
435  EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size());
436  EXPECT_EQ(new_bubble_content.radio_group.radio_items[0],
437            l10n_util::GetStringFUTF8(
438                IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION,
439                UTF8ToUTF16(request_host)));
440  EXPECT_EQ(new_bubble_content.radio_group.radio_items[1],
441            l10n_util::GetStringUTF8(
442                IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK));
443  EXPECT_EQ(0, new_bubble_content.radio_group.default_item);
444  EXPECT_EQ(2U, new_bubble_content.media_menus.size());
445}
446
447TEST_F(ContentSettingBubbleModelTest, Plugins) {
448  TabSpecificContentSettings* content_settings =
449      TabSpecificContentSettings::FromWebContents(web_contents());
450  content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS);
451
452  scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
453      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
454         NULL, web_contents(), profile(),
455         CONTENT_SETTINGS_TYPE_PLUGINS));
456  const ContentSettingBubbleModel::BubbleContent& bubble_content =
457      content_setting_bubble_model->bubble_content();
458  EXPECT_FALSE(bubble_content.title.empty());
459  EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
460  EXPECT_FALSE(bubble_content.custom_link.empty());
461  EXPECT_TRUE(bubble_content.custom_link_enabled);
462  EXPECT_FALSE(bubble_content.manage_link.empty());
463}
464
465TEST_F(ContentSettingBubbleModelTest, PepperBroker) {
466  TabSpecificContentSettings* content_settings =
467      TabSpecificContentSettings::FromWebContents(web_contents());
468  content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
469
470  scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
471      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
472         NULL, web_contents(), profile(),
473         CONTENT_SETTINGS_TYPE_PPAPI_BROKER));
474  const ContentSettingBubbleModel::BubbleContent& bubble_content =
475      content_setting_bubble_model->bubble_content();
476
477  std::string title = bubble_content.title;
478  EXPECT_FALSE(title.empty());
479  ASSERT_EQ(2U, bubble_content.radio_group.radio_items.size());
480  std::string radio1 = bubble_content.radio_group.radio_items[0];
481  std::string radio2 = bubble_content.radio_group.radio_items[1];
482  EXPECT_FALSE(bubble_content.custom_link_enabled);
483  EXPECT_FALSE(bubble_content.manage_link.empty());
484
485  content_settings->ClearBlockedContentSettingsExceptForCookies();
486  content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
487  content_setting_bubble_model.reset(
488      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
489          NULL, web_contents(), profile(),
490          CONTENT_SETTINGS_TYPE_PPAPI_BROKER));
491  const ContentSettingBubbleModel::BubbleContent& bubble_content_2 =
492      content_setting_bubble_model->bubble_content();
493
494  EXPECT_FALSE(bubble_content_2.title.empty());
495  EXPECT_NE(title, bubble_content_2.title);
496  ASSERT_EQ(2U, bubble_content_2.radio_group.radio_items.size());
497  EXPECT_NE(radio1, bubble_content_2.radio_group.radio_items[0]);
498  EXPECT_NE(radio2, bubble_content_2.radio_group.radio_items[1]);
499  EXPECT_FALSE(bubble_content_2.custom_link_enabled);
500  EXPECT_FALSE(bubble_content_2.manage_link.empty());
501}
502
503TEST_F(ContentSettingBubbleModelTest, Geolocation) {
504  const GURL page_url("http://toplevel.example/");
505  const GURL frame1_url("http://host1.example/");
506  const GURL frame2_url("http://host2.example:999/");
507
508  NavigateAndCommit(page_url);
509  TabSpecificContentSettings* content_settings =
510      TabSpecificContentSettings::FromWebContents(web_contents());
511
512  // One permitted frame, but not in the content map: requires reload.
513  content_settings->OnGeolocationPermissionSet(frame1_url, true);
514  CheckGeolocationBubble(1, false, true);
515
516  // Add it to the content map, should now have a clear link.
517  HostContentSettingsMap* setting_map =
518      profile()->GetHostContentSettingsMap();
519  setting_map->SetContentSetting(
520      ContentSettingsPattern::FromURLNoWildcard(frame1_url),
521      ContentSettingsPattern::FromURLNoWildcard(page_url),
522      CONTENT_SETTINGS_TYPE_GEOLOCATION,
523      std::string(),
524      CONTENT_SETTING_ALLOW);
525  CheckGeolocationBubble(1, true, false);
526
527  // Change the default to allow: no message needed.
528  profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
529      CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_ALLOW);
530  CheckGeolocationBubble(1, false, false);
531
532  // Second frame denied, but not stored in the content map: requires reload.
533  content_settings->OnGeolocationPermissionSet(frame2_url, false);
534  CheckGeolocationBubble(2, false, true);
535
536  // Change the default to block: offer a clear link for the persisted frame 1.
537  profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
538      CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_BLOCK);
539  CheckGeolocationBubble(2, true, false);
540}
541
542TEST_F(ContentSettingBubbleModelTest, FileURL) {
543  std::string file_url("file:///tmp/test.html");
544  NavigateAndCommit(GURL(file_url));
545  TabSpecificContentSettings::FromWebContents(web_contents())->OnContentBlocked(
546      CONTENT_SETTINGS_TYPE_IMAGES);
547  scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
548      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
549          NULL, web_contents(), profile(),
550          CONTENT_SETTINGS_TYPE_IMAGES));
551  std::string title =
552      content_setting_bubble_model->bubble_content().radio_group.radio_items[0];
553  ASSERT_NE(std::string::npos, title.find(file_url));
554}
555
556TEST_F(ContentSettingBubbleModelTest, RegisterProtocolHandler) {
557  const GURL page_url("http://toplevel.example/");
558  NavigateAndCommit(page_url);
559  TabSpecificContentSettings* content_settings =
560      TabSpecificContentSettings::FromWebContents(web_contents());
561  content_settings->set_pending_protocol_handler(
562      ProtocolHandler::CreateProtocolHandler("mailto",
563          GURL("http://www.toplevel.example/"), ASCIIToUTF16("Handler")));
564
565  ContentSettingRPHBubbleModel content_setting_bubble_model(
566          NULL, web_contents(), profile(), NULL,
567          CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS);
568
569  const ContentSettingBubbleModel::BubbleContent& bubble_content =
570      content_setting_bubble_model.bubble_content();
571  EXPECT_FALSE(bubble_content.title.empty());
572  EXPECT_FALSE(bubble_content.radio_group.radio_items.empty());
573  EXPECT_TRUE(bubble_content.popup_items.empty());
574  EXPECT_TRUE(bubble_content.domain_lists.empty());
575  EXPECT_TRUE(bubble_content.custom_link.empty());
576  EXPECT_FALSE(bubble_content.custom_link_enabled);
577  EXPECT_FALSE(bubble_content.manage_link.empty());
578}
579
580class FakeDelegate : public ProtocolHandlerRegistry::Delegate {
581 public:
582  virtual void RegisterExternalHandler(const std::string& protocol) OVERRIDE {
583    // Overrides in order to not register the handler with the
584    // ChildProcessSecurityPolicy. That has persistent and unalterable
585    // side effects on other tests.
586  }
587
588  virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
589      ShellIntegration::DefaultWebClientObserver* observer,
590      const std::string& protocol) OVERRIDE {
591    VLOG(1) << "CreateShellWorker";
592    return NULL;
593  }
594
595  virtual ProtocolHandlerRegistry::DefaultClientObserver* CreateShellObserver(
596      ProtocolHandlerRegistry* registry) OVERRIDE {
597    return NULL;
598  }
599
600  virtual void RegisterWithOSAsDefaultClient(
601      const std::string& protocol,
602      ProtocolHandlerRegistry* registry) OVERRIDE {
603    VLOG(1) << "Register With OS";
604  }
605};
606
607TEST_F(ContentSettingBubbleModelTest, RPHAllow) {
608  ProtocolHandlerRegistry registry(profile(), new FakeDelegate());
609  registry.InitProtocolSettings();
610
611  const GURL page_url("http://toplevel.example/");
612  NavigateAndCommit(page_url);
613  TabSpecificContentSettings* content_settings =
614      TabSpecificContentSettings::FromWebContents(web_contents());
615  ProtocolHandler test_handler = ProtocolHandler::CreateProtocolHandler(
616      "mailto", GURL("http://www.toplevel.example/"),
617      ASCIIToUTF16("Handler"));
618  content_settings->set_pending_protocol_handler(test_handler);
619
620  ContentSettingRPHBubbleModel content_setting_bubble_model(
621          NULL, web_contents(), profile(), &registry,
622          CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS);
623
624  {
625    ProtocolHandler handler = registry.GetHandlerFor("mailto");
626    EXPECT_TRUE(handler.IsEmpty());
627    EXPECT_EQ(CONTENT_SETTING_DEFAULT,
628              content_settings->pending_protocol_handler_setting());
629  }
630
631  // "0" is the "Allow" radio button.
632  content_setting_bubble_model.OnRadioClicked(0);
633  {
634    ProtocolHandler handler = registry.GetHandlerFor("mailto");
635    ASSERT_FALSE(handler.IsEmpty());
636    EXPECT_EQ(ASCIIToUTF16("Handler"), handler.title());
637    EXPECT_EQ(CONTENT_SETTING_ALLOW,
638              content_settings->pending_protocol_handler_setting());
639  }
640
641  // "1" is the "Deny" radio button.
642  content_setting_bubble_model.OnRadioClicked(1);
643  {
644    ProtocolHandler handler = registry.GetHandlerFor("mailto");
645    EXPECT_TRUE(handler.IsEmpty());
646    EXPECT_EQ(CONTENT_SETTING_BLOCK,
647              content_settings->pending_protocol_handler_setting());
648  }
649
650  // "2" is the "Ignore button.
651  content_setting_bubble_model.OnRadioClicked(2);
652  {
653    ProtocolHandler handler = registry.GetHandlerFor("mailto");
654    EXPECT_TRUE(handler.IsEmpty());
655    EXPECT_EQ(CONTENT_SETTING_DEFAULT,
656              content_settings->pending_protocol_handler_setting());
657    EXPECT_TRUE(registry.IsIgnored(test_handler));
658  }
659
660  // "0" is the "Allow" radio button.
661  content_setting_bubble_model.OnRadioClicked(0);
662  {
663    ProtocolHandler handler = registry.GetHandlerFor("mailto");
664    ASSERT_FALSE(handler.IsEmpty());
665    EXPECT_EQ(ASCIIToUTF16("Handler"), handler.title());
666    EXPECT_EQ(CONTENT_SETTING_ALLOW,
667              content_settings->pending_protocol_handler_setting());
668    EXPECT_FALSE(registry.IsIgnored(test_handler));
669  }
670
671  registry.Shutdown();
672}
673