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