Home | History | Annotate | Download | only in browser
      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/auto_reset.h"
      6 #include "base/command_line.h"
      7 #include "base/utf_string_conversions.h"
      8 #include "chrome/browser/mock_plugin_exceptions_table_model.h"
      9 #include "chrome/common/chrome_switches.h"
     10 #include "chrome/test/testing_pref_service.h"
     11 #include "chrome/test/testing_profile.h"
     12 #include "testing/gmock/include/gmock/gmock.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 #include "ui/base/models/table_model_observer.h"
     15 #include "webkit/plugins/npapi/plugin_group.h"
     16 #include "webkit/plugins/npapi/webplugininfo.h"
     17 
     18 // Can't be an internal namespace because PluginExceptionsTableModel declares
     19 // as a friend.
     20 namespace plugin_test_internal {
     21 
     22 using ::testing::_;
     23 using ::testing::Invoke;
     24 
     25 class MockTableModelObserver : public ui::TableModelObserver {
     26  public:
     27   explicit MockTableModelObserver(ui::TableModel* model)
     28       : model_(model) {
     29     ON_CALL(*this, OnItemsRemoved(_, _))
     30         .WillByDefault(
     31             Invoke(this, &MockTableModelObserver::CheckOnItemsRemoved));
     32   }
     33 
     34   MOCK_METHOD0(OnModelChanged, void());
     35   MOCK_METHOD2(OnItemsChanged, void(int start, int length));
     36   MOCK_METHOD2(OnItemsAdded, void(int start, int length));
     37   MOCK_METHOD2(OnItemsRemoved, void(int start, int length));
     38 
     39  private:
     40   void CheckOnItemsRemoved(int start, int length) {
     41     if (!model_)
     42       return;
     43     // This method is called *after* the items have been removed, so we check if
     44     // the first removed item was still inside the correct range.
     45     EXPECT_LT(start, model_->RowCount() + 1);
     46   }
     47 
     48   ui::TableModel* model_;
     49 };
     50 
     51 }  // namespace plugin_test_internal
     52 
     53 using ::testing::InSequence;
     54 
     55 class PluginExceptionsTableModelTest : public testing::Test {
     56  public:
     57   PluginExceptionsTableModelTest()
     58       : ui_thread_(BrowserThread::UI, &message_loop_),
     59         command_line_(CommandLine::ForCurrentProcess(),
     60                       *CommandLine::ForCurrentProcess()) {}
     61 
     62   virtual void SetUp() {
     63     CommandLine::ForCurrentProcess()->AppendSwitch(
     64         switches::kEnableResourceContentSettings);
     65 
     66     profile_.reset(new TestingProfile());
     67 
     68     HostContentSettingsMap* map = profile_->GetHostContentSettingsMap();
     69 
     70     ContentSettingsPattern example_com("[*.]example.com");
     71     ContentSettingsPattern moose_org("[*.]moose.org");
     72     map->SetContentSetting(example_com,
     73                            CONTENT_SETTINGS_TYPE_PLUGINS,
     74                            "a-foo",
     75                            CONTENT_SETTING_ALLOW);
     76     map->SetContentSetting(moose_org,
     77                            CONTENT_SETTINGS_TYPE_PLUGINS,
     78                            "b-bar",
     79                            CONTENT_SETTING_BLOCK);
     80     map->SetContentSetting(example_com,
     81                            CONTENT_SETTINGS_TYPE_PLUGINS,
     82                            "b-bar",
     83                            CONTENT_SETTING_ALLOW);
     84 
     85     table_model_.reset(new MockPluginExceptionsTableModel(map, NULL));
     86 
     87     std::vector<webkit::npapi::PluginGroup> plugins;
     88     webkit::npapi::WebPluginInfo foo_plugin;
     89     foo_plugin.path = FilePath(FILE_PATH_LITERAL("a-foo"));
     90     foo_plugin.name = ASCIIToUTF16("FooPlugin");
     91     foo_plugin.enabled =
     92         webkit::npapi::WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED;
     93     scoped_ptr<webkit::npapi::PluginGroup> foo_group(
     94         webkit::npapi::PluginGroup::FromWebPluginInfo(foo_plugin));
     95     plugins.push_back(*foo_group);
     96 
     97     webkit::npapi::WebPluginInfo bar_plugin;
     98     bar_plugin.path = FilePath(FILE_PATH_LITERAL("b-bar"));
     99     bar_plugin.name = ASCIIToUTF16("BarPlugin");
    100     bar_plugin.enabled =
    101         webkit::npapi::WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED;
    102     scoped_ptr<webkit::npapi::PluginGroup> bar_group(
    103         webkit::npapi::PluginGroup::FromWebPluginInfo(bar_plugin));
    104     plugins.push_back(*bar_group);
    105 
    106     table_model_->set_plugins(plugins);
    107     table_model_->ReloadSettings();
    108   }
    109 
    110  protected:
    111   void CheckInvariants() const {
    112     typedef std::vector<PluginExceptionsTableModel::SettingsEntry> Entries;
    113     const Entries& settings = table_model_->settings_;
    114     const std::vector<int>& row_counts = table_model_->row_counts_;
    115     const std::vector<std::string>& resources = table_model_->resources_;
    116     const ui::TableModel::Groups& groups = table_model_->groups_;
    117 
    118     EXPECT_EQ(groups.size(), row_counts.size());
    119     EXPECT_EQ(groups.size(), resources.size());
    120 
    121     int last_plugin = 0;
    122     int count = 0;
    123     for (Entries::const_iterator it = settings.begin();
    124          it != settings.end(); ++it) {
    125       // Plugin IDs are indices into |groups|.
    126       EXPECT_GE(it->plugin_id, 0);
    127       EXPECT_LT(it->plugin_id, static_cast<int>(groups.size()));
    128       if (it->plugin_id == last_plugin) {
    129         count++;
    130       } else {
    131         // Plugin IDs are ascending one by one.
    132         EXPECT_EQ(last_plugin+1, it->plugin_id);
    133 
    134         // Consecutive runs of plugins with id |x| are |row_counts[x]| long.
    135         EXPECT_EQ(count, row_counts[last_plugin]);
    136         count = 1;
    137         last_plugin = it->plugin_id;
    138       }
    139     }
    140     if (!row_counts.empty())
    141       EXPECT_EQ(count, row_counts[last_plugin]);
    142   }
    143 
    144  protected:
    145   MessageLoop message_loop_;
    146   BrowserThread ui_thread_;
    147 
    148   scoped_ptr<TestingProfile> profile_;
    149   scoped_ptr<MockPluginExceptionsTableModel> table_model_;
    150 
    151  private:
    152   AutoReset<CommandLine> command_line_;
    153 };
    154 
    155 TEST_F(PluginExceptionsTableModelTest, Basic) {
    156   EXPECT_EQ(3, table_model_->RowCount());
    157   CheckInvariants();
    158 }
    159 
    160 TEST_F(PluginExceptionsTableModelTest, RemoveOneRow) {
    161   plugin_test_internal::MockTableModelObserver observer(table_model_.get());
    162   table_model_->SetObserver(&observer);
    163 
    164   EXPECT_CALL(observer, OnItemsRemoved(1, 1));
    165   RemoveRowsTableModel::Rows rows;
    166   rows.insert(1);
    167   table_model_->RemoveRows(rows);
    168   EXPECT_EQ(2, table_model_->RowCount());
    169   EXPECT_EQ(2, static_cast<int>(table_model_->GetGroups().size()));
    170   CheckInvariants();
    171   table_model_->SetObserver(NULL);
    172 }
    173 
    174 TEST_F(PluginExceptionsTableModelTest, RemoveLastRowInGroup) {
    175   plugin_test_internal::MockTableModelObserver observer(table_model_.get());
    176   table_model_->SetObserver(&observer);
    177 
    178   EXPECT_CALL(observer, OnModelChanged());
    179   RemoveRowsTableModel::Rows rows;
    180   rows.insert(0);
    181   table_model_->RemoveRows(rows);
    182   EXPECT_EQ(2, table_model_->RowCount());
    183   EXPECT_EQ(1, static_cast<int>(table_model_->GetGroups().size()));
    184   CheckInvariants();
    185 
    186   HostContentSettingsMap* map = profile_->GetHostContentSettingsMap();
    187   EXPECT_CALL(observer, OnModelChanged());
    188   map->SetContentSetting(ContentSettingsPattern("[*.]blurp.net"),
    189                          CONTENT_SETTINGS_TYPE_PLUGINS,
    190                          "b-bar",
    191                          CONTENT_SETTING_BLOCK);
    192   EXPECT_EQ(3, table_model_->RowCount());
    193 
    194   InSequence s;
    195   EXPECT_CALL(observer, OnItemsRemoved(2, 1));
    196   EXPECT_CALL(observer, OnItemsRemoved(0, 1));
    197   rows.clear();
    198   rows.insert(0);
    199   rows.insert(2);
    200   table_model_->RemoveRows(rows);
    201   EXPECT_EQ(1, table_model_->RowCount());
    202   EXPECT_EQ(1, static_cast<int>(table_model_->GetGroups().size()));
    203   CheckInvariants();
    204 
    205   table_model_->SetObserver(NULL);
    206 }
    207 
    208 TEST_F(PluginExceptionsTableModelTest, RemoveAllRows) {
    209   plugin_test_internal::MockTableModelObserver observer(table_model_.get());
    210   table_model_->SetObserver(&observer);
    211 
    212   EXPECT_CALL(observer, OnModelChanged());
    213   table_model_->RemoveAll();
    214   EXPECT_EQ(0, table_model_->RowCount());
    215   EXPECT_EQ(0, static_cast<int>(table_model_->GetGroups().size()));
    216   CheckInvariants();
    217   table_model_->SetObserver(NULL);
    218 }
    219