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