Home | History | Annotate | Download | only in search_engines
      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/string16.h"
      6 #include "base/utf_string_conversions.h"
      7 #include "chrome/browser/profiles/profile.h"
      8 #include "chrome/browser/search_engines/template_url.h"
      9 #include "chrome/browser/search_engines/template_url_model.h"
     10 #include "chrome/browser/ui/search_engines/keyword_editor_controller.h"
     11 #include "chrome/browser/ui/search_engines/template_url_table_model.h"
     12 #include "chrome/common/pref_names.h"
     13 #include "chrome/test/testing_pref_service.h"
     14 #include "chrome/test/testing_profile.h"
     15 #include "content/common/notification_details.h"
     16 #include "content/common/notification_source.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 #include "ui/base/models/table_model_observer.h"
     19 
     20 static const string16 kA(ASCIIToUTF16("a"));
     21 static const string16 kA1(ASCIIToUTF16("a1"));
     22 static const string16 kB(ASCIIToUTF16("b"));
     23 static const string16 kB1(ASCIIToUTF16("b1"));
     24 
     25 // Base class for keyword editor tests. Creates a profile containing an
     26 // empty TemplateURLModel.
     27 class KeywordEditorControllerTest : public testing::Test,
     28                                     public ui::TableModelObserver {
     29  public:
     30   // Initializes all of the state.
     31   void Init(bool simulate_load_failure);
     32 
     33   virtual void SetUp() {
     34     Init(false);
     35   }
     36 
     37   virtual void OnModelChanged() {
     38     model_changed_count_++;
     39   }
     40 
     41   virtual void OnItemsChanged(int start, int length) {
     42     items_changed_count_++;
     43   }
     44 
     45   virtual void OnItemsAdded(int start, int length) {
     46     added_count_++;
     47   }
     48 
     49   virtual void OnItemsRemoved(int start, int length) {
     50     removed_count_++;
     51   }
     52 
     53   void VerifyChangeCount(int model_changed_count, int item_changed_count,
     54                          int added_count, int removed_count) {
     55     ASSERT_EQ(model_changed_count, model_changed_count_);
     56     ASSERT_EQ(item_changed_count, items_changed_count_);
     57     ASSERT_EQ(added_count, added_count_);
     58     ASSERT_EQ(removed_count, removed_count_);
     59     ClearChangeCount();
     60   }
     61 
     62   void ClearChangeCount() {
     63     model_changed_count_ = items_changed_count_ = added_count_ =
     64         removed_count_ = 0;
     65   }
     66 
     67   void SimulateDefaultSearchIsManaged(const std::string& url) {
     68     ASSERT_FALSE(url.empty());
     69     TestingPrefService* service = profile_->GetTestingPrefService();
     70     service->SetManagedPref(
     71         prefs::kDefaultSearchProviderEnabled,
     72         Value::CreateBooleanValue(true));
     73     service->SetManagedPref(
     74         prefs::kDefaultSearchProviderSearchURL,
     75         Value::CreateStringValue(url));
     76     service->SetManagedPref(
     77         prefs::kDefaultSearchProviderName,
     78         Value::CreateStringValue("managed"));
     79     // Clear the IDs that are not specified via policy.
     80     service->SetManagedPref(
     81         prefs::kDefaultSearchProviderID, new StringValue(""));
     82     service->SetManagedPref(
     83         prefs::kDefaultSearchProviderPrepopulateID, new StringValue(""));
     84     model_->Observe(
     85         NotificationType::PREF_CHANGED,
     86         Source<PrefService>(profile_->GetTestingPrefService()),
     87         Details<std::string>(NULL));
     88   }
     89 
     90   TemplateURLTableModel* table_model() const {
     91     return controller_->table_model();
     92   }
     93 
     94  protected:
     95   MessageLoopForUI message_loop_;
     96   scoped_ptr<TestingProfile> profile_;
     97   scoped_ptr<KeywordEditorController> controller_;
     98   TemplateURLModel* model_;
     99 
    100   int model_changed_count_;
    101   int items_changed_count_;
    102   int added_count_;
    103   int removed_count_;
    104 };
    105 
    106 void KeywordEditorControllerTest::Init(bool simulate_load_failure) {
    107   ClearChangeCount();
    108 
    109   // If init is called twice, make sure that the controller is destroyed before
    110   // the profile is.
    111   controller_.reset();
    112   profile_.reset(new TestingProfile());
    113   profile_->CreateTemplateURLModel();
    114 
    115   model_ = profile_->GetTemplateURLModel();
    116   if (simulate_load_failure)
    117     model_->OnWebDataServiceRequestDone(0, NULL);
    118 
    119   controller_.reset(new KeywordEditorController(profile_.get()));
    120   controller_->table_model()->SetObserver(this);
    121 }
    122 
    123 // Tests adding a TemplateURL.
    124 TEST_F(KeywordEditorControllerTest, Add) {
    125   controller_->AddTemplateURL(kA, kB, "http://c");
    126 
    127   // Verify the observer was notified.
    128   VerifyChangeCount(0, 0, 1, 0);
    129   if (HasFatalFailure())
    130     return;
    131 
    132   // Verify the TableModel has the new data.
    133   ASSERT_EQ(1, table_model()->RowCount());
    134 
    135   // Verify the TemplateURLModel has the new entry.
    136   ASSERT_EQ(1U, model_->GetTemplateURLs().size());
    137 
    138   // Verify the entry is what we added.
    139   const TemplateURL* turl = model_->GetTemplateURLs()[0];
    140   EXPECT_EQ(ASCIIToUTF16("a"), turl->short_name());
    141   EXPECT_EQ(ASCIIToUTF16("b"), turl->keyword());
    142   ASSERT_TRUE(turl->url() != NULL);
    143   EXPECT_EQ("http://c", turl->url()->url());
    144 }
    145 
    146 // Tests modifying a TemplateURL.
    147 TEST_F(KeywordEditorControllerTest, Modify) {
    148   controller_->AddTemplateURL(kA, kB, "http://c");
    149   ClearChangeCount();
    150 
    151   // Modify the entry.
    152   const TemplateURL* turl = model_->GetTemplateURLs()[0];
    153   controller_->ModifyTemplateURL(turl, kA1, kB1, "http://c1");
    154 
    155   // Make sure it was updated appropriately.
    156   VerifyChangeCount(0, 1, 0, 0);
    157   EXPECT_EQ(ASCIIToUTF16("a1"), turl->short_name());
    158   EXPECT_EQ(ASCIIToUTF16("b1"), turl->keyword());
    159   ASSERT_TRUE(turl->url() != NULL);
    160   EXPECT_EQ("http://c1", turl->url()->url());
    161 }
    162 
    163 // Tests making a TemplateURL the default search provider.
    164 TEST_F(KeywordEditorControllerTest, MakeDefault) {
    165   controller_->AddTemplateURL(kA, kB, "http://c{searchTerms}");
    166   ClearChangeCount();
    167 
    168   const TemplateURL* turl = model_->GetTemplateURLs()[0];
    169   int new_default = controller_->MakeDefaultTemplateURL(0);
    170   EXPECT_EQ(0, new_default);
    171   // Making an item the default sends a handful of changes. Which are sent isn't
    172   // important, what is important is 'something' is sent.
    173   ASSERT_TRUE(items_changed_count_ > 0 || added_count_ > 0 ||
    174               removed_count_ > 0);
    175   ASSERT_TRUE(model_->GetDefaultSearchProvider() == turl);
    176 
    177   // Making it default a second time should fail.
    178   new_default = controller_->MakeDefaultTemplateURL(0);
    179   EXPECT_EQ(-1, new_default);
    180 }
    181 
    182 // Tests that a TemplateURL can't be made the default if the default search
    183 // provider is managed via policy.
    184 TEST_F(KeywordEditorControllerTest, CannotSetDefaultWhileManaged) {
    185   controller_->AddTemplateURL(kA, kB, "http://c{searchTerms}");
    186   controller_->AddTemplateURL(kA1, kB1, "http://d{searchTerms}");
    187   ClearChangeCount();
    188 
    189   const TemplateURL* turl1 =
    190       model_->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
    191   ASSERT_TRUE(turl1 != NULL);
    192   const TemplateURL* turl2 =
    193       model_->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
    194   ASSERT_TRUE(turl2 != NULL);
    195 
    196   EXPECT_TRUE(controller_->CanMakeDefault(turl1));
    197   EXPECT_TRUE(controller_->CanMakeDefault(turl2));
    198 
    199   SimulateDefaultSearchIsManaged(turl2->url()->url());
    200   EXPECT_TRUE(model_->is_default_search_managed());
    201 
    202   EXPECT_FALSE(controller_->CanMakeDefault(turl1));
    203   EXPECT_FALSE(controller_->CanMakeDefault(turl2));
    204 }
    205 
    206 // Tests that a TemplateURL can't be edited if it is the managed default search
    207 // provider.
    208 TEST_F(KeywordEditorControllerTest, EditManagedDefault) {
    209   controller_->AddTemplateURL(kA, kB, "http://c{searchTerms}");
    210   controller_->AddTemplateURL(kA1, kB1, "http://d{searchTerms}");
    211   ClearChangeCount();
    212 
    213   const TemplateURL* turl1 =
    214       model_->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
    215   ASSERT_TRUE(turl1 != NULL);
    216   const TemplateURL* turl2 =
    217       model_->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
    218   ASSERT_TRUE(turl2 != NULL);
    219 
    220   EXPECT_TRUE(controller_->CanEdit(turl1));
    221   EXPECT_TRUE(controller_->CanEdit(turl2));
    222 
    223   // Simulate setting a managed default.  This will add another template URL to
    224   // the model.
    225   SimulateDefaultSearchIsManaged(turl2->url()->url());
    226   EXPECT_TRUE(model_->is_default_search_managed());
    227   EXPECT_TRUE(controller_->CanEdit(turl1));
    228   EXPECT_TRUE(controller_->CanEdit(turl2));
    229   EXPECT_FALSE(controller_->CanEdit(model_->GetDefaultSearchProvider()));
    230 }
    231 
    232 TEST_F(KeywordEditorControllerTest, MakeDefaultNoWebData) {
    233   // Simulate a failure to load Web Data.
    234   Init(true);
    235 
    236   controller_->AddTemplateURL(kA, kB, "http://c{searchTerms}");
    237   ClearChangeCount();
    238 
    239   // This should not result in a crash.
    240   int new_default = controller_->MakeDefaultTemplateURL(0);
    241   EXPECT_EQ(0, new_default);
    242 }
    243 
    244 // Mutates the TemplateURLModel and make sure table model is updating
    245 // appropriately.
    246 TEST_F(KeywordEditorControllerTest, MutateTemplateURLModel) {
    247   TemplateURL* turl = new TemplateURL();
    248   turl->set_keyword(ASCIIToUTF16("a"));
    249   turl->set_short_name(ASCIIToUTF16("b"));
    250   model_->Add(turl);
    251 
    252   // Table model should have updated.
    253   VerifyChangeCount(1, 0, 0, 0);
    254 
    255   // And should contain the newly added TemplateURL.
    256   ASSERT_EQ(1, table_model()->RowCount());
    257   ASSERT_EQ(0, table_model()->IndexOfTemplateURL(turl));
    258 }
    259