Home | History | Annotate | Download | only in geolocation
      1 // Copyright (c) 2011 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/message_loop.h"
      6 #include "chrome/browser/content_settings/content_settings_details.h"
      7 #include "chrome/browser/geolocation/geolocation_content_settings_map.h"
      8 #include "chrome/browser/prefs/pref_service.h"
      9 #include "chrome/browser/prefs/scoped_user_pref_update.h"
     10 #include "chrome/common/pref_names.h"
     11 #include "chrome/test/testing_profile.h"
     12 #include "content/browser/browser_thread.h"
     13 #include "content/common/notification_registrar.h"
     14 #include "content/common/notification_service.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 
     18 namespace {
     19 
     20 class StubSettingsObserver : public NotificationObserver {
     21  public:
     22   StubSettingsObserver() : last_notifier(NULL), counter(0) {
     23     registrar_.Add(this, NotificationType::GEOLOCATION_SETTINGS_CHANGED,
     24                    NotificationService::AllSources());
     25   }
     26 
     27   virtual void Observe(NotificationType type,
     28                        const NotificationSource& source,
     29                        const NotificationDetails& details) {
     30     ++counter;
     31     Source<GeolocationContentSettingsMap> content_settings(source);
     32     Details<ContentSettingsDetails> settings_details(details);
     33     last_notifier = content_settings.ptr();
     34     last_pattern = settings_details.ptr()->pattern();
     35     last_update_all = settings_details.ptr()->update_all();
     36     last_update_all_types = settings_details.ptr()->update_all_types();
     37     last_type = settings_details.ptr()->type();
     38     // This checks that calling a Get function from an observer doesn't
     39     // deadlock.
     40     last_notifier->GetContentSetting(GURL("http://random-hostname.com/"),
     41                                      GURL("http://foo.random-hostname.com/"));
     42   }
     43 
     44   GeolocationContentSettingsMap* last_notifier;
     45   ContentSettingsPattern last_pattern;
     46   bool last_update_all;
     47   bool last_update_all_types;
     48   int counter;
     49   ContentSettingsType last_type;
     50 
     51  private:
     52   NotificationRegistrar registrar_;
     53 };
     54 
     55 class GeolocationContentSettingsMapTests : public testing::Test {
     56  public:
     57   GeolocationContentSettingsMapTests()
     58     : ui_thread_(BrowserThread::UI, &message_loop_) {
     59   }
     60 
     61  protected:
     62   MessageLoop message_loop_;
     63   BrowserThread ui_thread_;
     64 };
     65 
     66 TEST_F(GeolocationContentSettingsMapTests, DefaultValues) {
     67   TestingProfile profile;
     68   GeolocationContentSettingsMap* map =
     69       profile.GetGeolocationContentSettingsMap();
     70 
     71   // Check setting defaults.
     72   EXPECT_EQ(CONTENT_SETTING_ASK, map->GetDefaultContentSetting());
     73   map->SetDefaultContentSetting(CONTENT_SETTING_BLOCK);
     74   EXPECT_EQ(CONTENT_SETTING_BLOCK, map->GetDefaultContentSetting());
     75 }
     76 
     77 TEST_F(GeolocationContentSettingsMapTests, Embedder) {
     78   TestingProfile profile;
     79   GeolocationContentSettingsMap* map =
     80       profile.GetGeolocationContentSettingsMap();
     81   GURL top_level("http://www.toplevel0.com/foo/bar");
     82   EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(top_level, top_level));
     83   // Now set the permission for requester_0.
     84   map->SetContentSetting(top_level, top_level, CONTENT_SETTING_ALLOW);
     85   EXPECT_EQ(CONTENT_SETTING_ALLOW,
     86             map->GetContentSetting(top_level, top_level));
     87 
     88   GURL requester_0("http://www.frame0.com/foo/bar");
     89   EXPECT_EQ(CONTENT_SETTING_ASK,
     90             map->GetContentSetting(requester_0, top_level));
     91   // Now set the permission for only requester_1.
     92   map->SetContentSetting(requester_0, top_level, CONTENT_SETTING_ALLOW);
     93   EXPECT_EQ(CONTENT_SETTING_ALLOW,
     94             map->GetContentSetting(top_level, top_level));
     95   EXPECT_EQ(CONTENT_SETTING_ALLOW,
     96             map->GetContentSetting(requester_0, top_level));
     97   // Block only requester_1.
     98   map->SetContentSetting(requester_0, top_level, CONTENT_SETTING_BLOCK);
     99   EXPECT_EQ(CONTENT_SETTING_BLOCK,
    100             map->GetContentSetting(requester_0, top_level));
    101   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    102             map->GetContentSetting(top_level, top_level));
    103 }
    104 
    105 TEST_F(GeolocationContentSettingsMapTests, MultipleEmbeddersAndOrigins) {
    106   TestingProfile profile;
    107   GeolocationContentSettingsMap* map =
    108       profile.GetGeolocationContentSettingsMap();
    109   GURL requester_0("http://www.iframe0.com/foo/bar");
    110   GURL requester_1("http://www.iframe1.co.uk/bar/foo");
    111   GURL embedder_0("http://www.toplevel0.com/foo/bar");
    112   EXPECT_EQ(CONTENT_SETTING_ASK,
    113             map->GetContentSetting(requester_0, embedder_0));
    114   EXPECT_EQ(CONTENT_SETTING_ASK,
    115             map->GetContentSetting(requester_1, embedder_0));
    116   // Now set the permission for only one origin.
    117   map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW);
    118   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    119             map->GetContentSetting(requester_0, embedder_0));
    120   EXPECT_EQ(CONTENT_SETTING_ASK,
    121             map->GetContentSetting(requester_1, embedder_0));
    122   // Set the permission for the other origin.
    123   map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_ALLOW);
    124   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    125             map->GetContentSetting(requester_1, embedder_0));
    126   // Check they're not allowed on a different embedder.
    127   GURL embedder_1("http://www.toplevel1.com/foo/bar");
    128   EXPECT_EQ(CONTENT_SETTING_ASK,
    129             map->GetContentSetting(requester_0, embedder_1));
    130   EXPECT_EQ(CONTENT_SETTING_ASK,
    131             map->GetContentSetting(requester_1, embedder_1));
    132   // Check all settings are valid.
    133   GeolocationContentSettingsMap::AllOriginsSettings content_settings(
    134       map->GetAllOriginsSettings());
    135   EXPECT_EQ(0U, content_settings.count(requester_0));
    136   EXPECT_EQ(1U, content_settings.count(requester_0.GetOrigin()));
    137   GeolocationContentSettingsMap::OneOriginSettings one_origin_settings(
    138       content_settings[requester_0.GetOrigin()]);
    139   EXPECT_EQ(CONTENT_SETTING_ALLOW, one_origin_settings[embedder_0.GetOrigin()]);
    140 
    141   EXPECT_EQ(0U, content_settings.count(requester_1));
    142   EXPECT_EQ(1U, content_settings.count(requester_1.GetOrigin()));
    143   one_origin_settings = content_settings[requester_1.GetOrigin()];
    144   EXPECT_EQ(CONTENT_SETTING_ALLOW, one_origin_settings[embedder_0.GetOrigin()]);
    145   // Block requester_1 on the first embedder and add it to the second.
    146   map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_BLOCK);
    147   map->SetContentSetting(requester_1, embedder_1, CONTENT_SETTING_ALLOW);
    148   EXPECT_EQ(CONTENT_SETTING_BLOCK,
    149             map->GetContentSetting(requester_1, embedder_0));
    150   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    151             map->GetContentSetting(requester_1, embedder_1));
    152 }
    153 
    154 TEST_F(GeolocationContentSettingsMapTests, SetContentSettingDefault) {
    155   TestingProfile profile;
    156   GeolocationContentSettingsMap* map =
    157       profile.GetGeolocationContentSettingsMap();
    158   GURL top_level("http://www.toplevel0.com/foo/bar");
    159   map->SetContentSetting(top_level, top_level, CONTENT_SETTING_ALLOW);
    160   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    161             map->GetContentSetting(top_level, top_level));
    162   // Set to CONTENT_SETTING_DEFAULT and check the actual value has changed.
    163   map->SetContentSetting(top_level, top_level, CONTENT_SETTING_DEFAULT);
    164   EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(top_level, top_level));
    165 }
    166 
    167 TEST_F(GeolocationContentSettingsMapTests, Reset) {
    168   TestingProfile profile;
    169   GeolocationContentSettingsMap* map =
    170       profile.GetGeolocationContentSettingsMap();
    171   GURL requester_0("http://www.iframe0.com/foo/bar");
    172   GURL embedder_0("http://www.toplevel0.com/foo/bar");
    173   map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW);
    174   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    175             map->GetContentSetting(requester_0, embedder_0));
    176   GeolocationContentSettingsMap::AllOriginsSettings content_settings(
    177       map->GetAllOriginsSettings());
    178   EXPECT_EQ(1U, content_settings.size());
    179 
    180   // Set to CONTENT_SETTING_DEFAULT and check the actual value has changed.
    181   map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_DEFAULT);
    182   EXPECT_EQ(CONTENT_SETTING_ASK,
    183             map->GetContentSetting(requester_0, embedder_0));
    184   content_settings = map->GetAllOriginsSettings();
    185   EXPECT_TRUE(content_settings.empty());
    186 }
    187 
    188 TEST_F(GeolocationContentSettingsMapTests, ClearsWhenSettingBackToDefault) {
    189   TestingProfile profile;
    190   GeolocationContentSettingsMap* map =
    191       profile.GetGeolocationContentSettingsMap();
    192   GURL requester_0("http://www.iframe0.com/foo/bar");
    193   GURL requester_1("http://www.iframe1.com/foo/bar");
    194   GURL embedder_0("http://www.toplevel0.com/foo/bar");
    195   map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW);
    196   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    197             map->GetContentSetting(requester_0, embedder_0));
    198   GeolocationContentSettingsMap::AllOriginsSettings content_settings(
    199       map->GetAllOriginsSettings());
    200   EXPECT_EQ(1U, content_settings.size());
    201 
    202   map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_ALLOW);
    203   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    204             map->GetContentSetting(requester_1, embedder_0));
    205   content_settings = map->GetAllOriginsSettings();
    206   EXPECT_EQ(2U, content_settings.size());
    207   EXPECT_EQ(1U, content_settings[requester_0.GetOrigin()].size());
    208   EXPECT_EQ(1U, content_settings[requester_1.GetOrigin()].size());
    209 
    210   // Set to default.
    211   map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_DEFAULT);
    212   content_settings = map->GetAllOriginsSettings();
    213   EXPECT_EQ(1U, content_settings.size());
    214 
    215   map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_DEFAULT);
    216   content_settings = map->GetAllOriginsSettings();
    217   EXPECT_TRUE(content_settings.empty());
    218 }
    219 
    220 TEST_F(GeolocationContentSettingsMapTests, WildCardForEmptyEmbedder) {
    221   TestingProfile profile;
    222   GeolocationContentSettingsMap* map =
    223       profile.GetGeolocationContentSettingsMap();
    224   GURL requester_0("http://www.iframe0.com/foo/bar");
    225   GURL embedder_0("http://www.toplevel0.com/foo/bar");
    226   GURL embedder_1("http://www.toplevel1.com/foo/bar");
    227   GURL empty_url;
    228   map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_BLOCK);
    229   map->SetContentSetting(requester_0, empty_url, CONTENT_SETTING_ALLOW);
    230   EXPECT_EQ(CONTENT_SETTING_BLOCK,
    231             map->GetContentSetting(requester_0, embedder_0));
    232   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    233             map->GetContentSetting(requester_0, embedder_1));
    234   EXPECT_EQ(CONTENT_SETTING_ASK,
    235             map->GetContentSetting(requester_0, requester_0));
    236 
    237   // Change the wildcard behavior.
    238   map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW);
    239   map->SetContentSetting(requester_0, empty_url, CONTENT_SETTING_BLOCK);
    240   map->SetDefaultContentSetting(CONTENT_SETTING_ALLOW);
    241   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    242             map->GetContentSetting(requester_0, embedder_0));
    243   EXPECT_EQ(CONTENT_SETTING_BLOCK,
    244             map->GetContentSetting(requester_0, embedder_1));
    245   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    246             map->GetContentSetting(requester_0, requester_0));
    247 }
    248 
    249 TEST_F(GeolocationContentSettingsMapTests, IgnoreInvalidURLsInPrefs) {
    250   TestingProfile profile;
    251   {
    252     DictionaryPrefUpdate update(profile.GetPrefs(),
    253                                 prefs::kGeolocationContentSettings);
    254     DictionaryValue* all_settings_dictionary = update.Get();
    255     // For simplicity, use the overloads that do path expansion. As '.' is the
    256     // path separator, we can't have dotted hostnames (which is fine).
    257     all_settings_dictionary->SetInteger("http://a/.http://b/",
    258                                         CONTENT_SETTING_ALLOW);
    259     all_settings_dictionary->SetInteger("bad_requester.http://b/",
    260                                         CONTENT_SETTING_ALLOW);
    261     all_settings_dictionary->SetInteger("http://a/.bad-embedder",
    262                                         CONTENT_SETTING_ALLOW);
    263   }
    264 
    265   GeolocationContentSettingsMap* map =
    266       profile.GetGeolocationContentSettingsMap();
    267   EXPECT_EQ(CONTENT_SETTING_ASK, map->GetDefaultContentSetting());
    268 
    269   // Check the valid entry was read OK.
    270   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    271             map->GetContentSetting(GURL("http://a/"), GURL("http://b/")));
    272   // But everything else should be according to the default.
    273   EXPECT_EQ(CONTENT_SETTING_ASK,
    274             map->GetContentSetting(GURL("http://a/"),
    275             GURL("http://bad-embedder")));
    276   EXPECT_EQ(CONTENT_SETTING_ASK,
    277             map->GetContentSetting(GURL("http://a/"),
    278             GURL("http://example.com")));
    279   EXPECT_EQ(CONTENT_SETTING_ASK,
    280             map->GetContentSetting(GURL("http://bad_requester/"),
    281             GURL("http://b/")));
    282 }
    283 
    284 TEST_F(GeolocationContentSettingsMapTests, Observe) {
    285   TestingProfile profile;
    286   GeolocationContentSettingsMap* map =
    287       profile.GetGeolocationContentSettingsMap();
    288   StubSettingsObserver observer;
    289 
    290   EXPECT_EQ(CONTENT_SETTING_ASK, map->GetDefaultContentSetting());
    291 
    292   // Test if a CONTENT_SETTING_CHANGE notification is sent after the geolocation
    293   // default content setting was changed through calling the
    294   // SetDefaultContentSetting method.
    295   map->SetDefaultContentSetting(CONTENT_SETTING_BLOCK);
    296   EXPECT_EQ(map, observer.last_notifier);
    297   EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type);
    298   EXPECT_EQ(1, observer.counter);
    299 
    300 
    301   // Test if a CONTENT_SETTING_CHANGE notification is sent after the preference
    302   // GeolocationDefaultContentSetting was changed.
    303   PrefService* prefs = profile.GetPrefs();
    304   prefs->SetInteger(prefs::kGeolocationDefaultContentSetting,
    305                     CONTENT_SETTING_ALLOW);
    306   EXPECT_EQ(2, observer.counter);
    307   EXPECT_EQ(map, observer.last_notifier);
    308   EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type);
    309   EXPECT_EQ(CONTENT_SETTING_ALLOW, map->GetDefaultContentSetting());
    310 }
    311 
    312 }  // namespace
    313