Home | History | Annotate | Download | only in content_settings
      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 "chrome/browser/extensions/api/content_settings/content_settings_store.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "chrome/browser/content_settings/content_settings_rule.h"
      9 #include "chrome/browser/content_settings/content_settings_utils.h"
     10 #include "testing/gmock/include/gmock/gmock.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 using ::testing::Mock;
     14 
     15 namespace extensions {
     16 
     17 namespace {
     18 
     19 void CheckRule(const content_settings::Rule& rule,
     20                const ContentSettingsPattern& primary_pattern,
     21                const ContentSettingsPattern& secondary_pattern,
     22                ContentSetting setting) {
     23   EXPECT_EQ(primary_pattern.ToString(), rule.primary_pattern.ToString());
     24   EXPECT_EQ(secondary_pattern.ToString(), rule.secondary_pattern.ToString());
     25   EXPECT_EQ(setting, content_settings::ValueToContentSetting(rule.value.get()));
     26 }
     27 
     28 // Helper class which returns monotonically-increasing base::Time objects.
     29 class FakeTimer {
     30  public:
     31   FakeTimer() : internal_(0) {}
     32 
     33   base::Time GetNext() {
     34     return base::Time::FromInternalValue(++internal_);
     35   }
     36 
     37  private:
     38   int64 internal_;
     39 };
     40 
     41 class MockContentSettingsStoreObserver
     42     : public ContentSettingsStore::Observer {
     43  public:
     44   MOCK_METHOD2(OnContentSettingChanged,
     45                void(const std::string& extension_id, bool incognito));
     46 };
     47 
     48 ContentSetting GetContentSettingFromStore(
     49     const ContentSettingsStore* store,
     50     const GURL& primary_url, const GURL& secondary_url,
     51     ContentSettingsType content_type,
     52     const std::string& resource_identifier,
     53     bool incognito) {
     54   scoped_ptr<content_settings::RuleIterator> rule_iterator (
     55       store->GetRuleIterator(content_type, resource_identifier, incognito));
     56   scoped_ptr<base::Value> setting(
     57       content_settings::GetContentSettingValueAndPatterns(
     58           rule_iterator.get(), primary_url, secondary_url, NULL, NULL));
     59   return content_settings::ValueToContentSetting(setting.get());
     60 }
     61 
     62 void GetSettingsForOneTypeFromStore(
     63     const ContentSettingsStore* store,
     64     ContentSettingsType content_type,
     65     const std::string& resource_identifier,
     66     bool incognito,
     67     std::vector<content_settings::Rule>* rules) {
     68   rules->clear();
     69   scoped_ptr<content_settings::RuleIterator> rule_iterator(
     70       store->GetRuleIterator(content_type, resource_identifier, incognito));
     71   while (rule_iterator->HasNext())
     72     rules->push_back(rule_iterator->Next());
     73 }
     74 
     75 }  // namespace
     76 
     77 class ContentSettingsStoreTest : public ::testing::Test {
     78  public:
     79   ContentSettingsStoreTest() :
     80       store_(new ContentSettingsStore()) {
     81   }
     82 
     83  protected:
     84   void RegisterExtension(const std::string& ext_id) {
     85     store_->RegisterExtension(ext_id, timer_.GetNext(), true);
     86   }
     87 
     88   ContentSettingsStore* store() {
     89     return store_.get();
     90   }
     91 
     92  private:
     93   FakeTimer timer_;
     94   scoped_refptr<ContentSettingsStore> store_;
     95 };
     96 
     97 TEST_F(ContentSettingsStoreTest, RegisterUnregister) {
     98   ::testing::StrictMock<MockContentSettingsStoreObserver> observer;
     99   store()->AddObserver(&observer);
    100 
    101   GURL url("http://www.youtube.com");
    102 
    103   EXPECT_EQ(CONTENT_SETTING_DEFAULT,
    104             GetContentSettingFromStore(store(),
    105                                        url,
    106                                        url,
    107                                        CONTENT_SETTINGS_TYPE_COOKIES,
    108                                        std::string(),
    109                                        false));
    110 
    111   // Register first extension
    112   std::string ext_id("my_extension");
    113   RegisterExtension(ext_id);
    114 
    115   EXPECT_EQ(CONTENT_SETTING_DEFAULT,
    116             GetContentSettingFromStore(store(),
    117                                        url,
    118                                        url,
    119                                        CONTENT_SETTINGS_TYPE_COOKIES,
    120                                        std::string(),
    121                                        false));
    122 
    123   // Set setting
    124   ContentSettingsPattern pattern =
    125       ContentSettingsPattern::FromURL(GURL("http://www.youtube.com"));
    126   EXPECT_CALL(observer, OnContentSettingChanged(ext_id, false));
    127   store()->SetExtensionContentSetting(ext_id,
    128                                       pattern,
    129                                       pattern,
    130                                       CONTENT_SETTINGS_TYPE_COOKIES,
    131                                       std::string(),
    132                                       CONTENT_SETTING_ALLOW,
    133                                       kExtensionPrefsScopeRegular);
    134   Mock::VerifyAndClear(&observer);
    135 
    136   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    137             GetContentSettingFromStore(store(),
    138                                        url,
    139                                        url,
    140                                        CONTENT_SETTINGS_TYPE_COOKIES,
    141                                        std::string(),
    142                                        false));
    143 
    144   // Register second extension.
    145   std::string ext_id_2("my_second_extension");
    146   RegisterExtension(ext_id_2);
    147   EXPECT_CALL(observer, OnContentSettingChanged(ext_id_2, false));
    148   store()->SetExtensionContentSetting(ext_id_2,
    149                                       pattern,
    150                                       pattern,
    151                                       CONTENT_SETTINGS_TYPE_COOKIES,
    152                                       std::string(),
    153                                       CONTENT_SETTING_BLOCK,
    154                                       kExtensionPrefsScopeRegular);
    155 
    156   EXPECT_EQ(CONTENT_SETTING_BLOCK,
    157             GetContentSettingFromStore(store(),
    158                                        url,
    159                                        url,
    160                                        CONTENT_SETTINGS_TYPE_COOKIES,
    161                                        std::string(),
    162                                        false));
    163 
    164   // Unregister first extension. This shouldn't change the setting.
    165   EXPECT_CALL(observer, OnContentSettingChanged(ext_id, false));
    166   store()->UnregisterExtension(ext_id);
    167   EXPECT_EQ(CONTENT_SETTING_BLOCK,
    168             GetContentSettingFromStore(store(),
    169                                        url,
    170                                        url,
    171                                        CONTENT_SETTINGS_TYPE_COOKIES,
    172                                        std::string(),
    173                                        false));
    174   Mock::VerifyAndClear(&observer);
    175 
    176   // Unregister second extension. This should reset the setting to its default
    177   // value.
    178   EXPECT_CALL(observer, OnContentSettingChanged(ext_id_2, false));
    179   store()->UnregisterExtension(ext_id_2);
    180   EXPECT_EQ(CONTENT_SETTING_DEFAULT,
    181             GetContentSettingFromStore(store(),
    182                                        url,
    183                                        url,
    184                                        CONTENT_SETTINGS_TYPE_COOKIES,
    185                                        std::string(),
    186                                        false));
    187 
    188   store()->RemoveObserver(&observer);
    189 }
    190 
    191 TEST_F(ContentSettingsStoreTest, GetAllSettings) {
    192   bool incognito = false;
    193   std::vector<content_settings::Rule> rules;
    194   GetSettingsForOneTypeFromStore(
    195       store(), CONTENT_SETTINGS_TYPE_COOKIES, std::string(), incognito, &rules);
    196   ASSERT_EQ(0u, rules.size());
    197 
    198   // Register first extension.
    199   std::string ext_id("my_extension");
    200   RegisterExtension(ext_id);
    201   ContentSettingsPattern pattern =
    202       ContentSettingsPattern::FromURL(GURL("http://www.youtube.com"));
    203   store()->SetExtensionContentSetting(ext_id,
    204                                       pattern,
    205                                       pattern,
    206                                       CONTENT_SETTINGS_TYPE_COOKIES,
    207                                       std::string(),
    208                                       CONTENT_SETTING_ALLOW,
    209                                       kExtensionPrefsScopeRegular);
    210 
    211   GetSettingsForOneTypeFromStore(
    212       store(), CONTENT_SETTINGS_TYPE_COOKIES, std::string(), incognito, &rules);
    213   ASSERT_EQ(1u, rules.size());
    214   CheckRule(rules[0], pattern, pattern, CONTENT_SETTING_ALLOW);
    215 
    216   // Register second extension.
    217   std::string ext_id_2("my_second_extension");
    218   RegisterExtension(ext_id_2);
    219   ContentSettingsPattern pattern_2 =
    220       ContentSettingsPattern::FromURL(GURL("http://www.example.com"));
    221   store()->SetExtensionContentSetting(ext_id_2,
    222                                       pattern_2,
    223                                       pattern_2,
    224                                       CONTENT_SETTINGS_TYPE_COOKIES,
    225                                       std::string(),
    226                                       CONTENT_SETTING_BLOCK,
    227                                       kExtensionPrefsScopeRegular);
    228 
    229   GetSettingsForOneTypeFromStore(
    230       store(), CONTENT_SETTINGS_TYPE_COOKIES, std::string(), incognito, &rules);
    231   ASSERT_EQ(2u, rules.size());
    232   // Rules appear in the reverse installation order of the extensions.
    233   CheckRule(rules[0], pattern_2, pattern_2, CONTENT_SETTING_BLOCK);
    234   CheckRule(rules[1], pattern, pattern, CONTENT_SETTING_ALLOW);
    235 
    236   // Disable first extension.
    237   store()->SetExtensionState(ext_id, false);
    238 
    239   GetSettingsForOneTypeFromStore(
    240       store(), CONTENT_SETTINGS_TYPE_COOKIES, std::string(), incognito, &rules);
    241   ASSERT_EQ(1u, rules.size());
    242   CheckRule(rules[0], pattern_2, pattern_2, CONTENT_SETTING_BLOCK);
    243 
    244   // Uninstall second extension.
    245   store()->UnregisterExtension(ext_id_2);
    246 
    247   GetSettingsForOneTypeFromStore(
    248       store(), CONTENT_SETTINGS_TYPE_COOKIES, std::string(), incognito, &rules);
    249   ASSERT_EQ(0u, rules.size());
    250 }
    251 
    252 }  // namespace extensions
    253