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.
5 #include "base/compiler_specific.h"
6 #include "base/strings/string16.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/search_engines/template_url.h"
10 #include "chrome/browser/search_engines/template_url_service.h"
11 #include "chrome/browser/search_engines/template_url_service_test_util.h"
12 #include "chrome/browser/ui/search_engines/keyword_editor_controller.h"
13 #include "chrome/browser/ui/search_engines/template_url_table_model.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/base/models/table_model_observer.h"
18 using base::ASCIIToUTF16;
20 static const base::string16 kA(ASCIIToUTF16("a"));
21 static const base::string16 kA1(ASCIIToUTF16("a1"));
22 static const base::string16 kB(ASCIIToUTF16("b"));
23 static const base::string16 kB1(ASCIIToUTF16("b1"));
25 // Base class for keyword editor tests. Creates a profile containing an
26 // empty TemplateURLService.
27 class KeywordEditorControllerTest : public testing::Test,
28 public ui::TableModelObserver {
30 KeywordEditorControllerTest()
31 : simulate_load_failure_(false),
32 model_changed_count_(0),
33 items_changed_count_(0),
37 explicit KeywordEditorControllerTest(bool simulate_load_failure)
38 : simulate_load_failure_(simulate_load_failure),
39 model_changed_count_(0),
40 items_changed_count_(0),
44 virtual void SetUp() OVERRIDE {
47 if (simulate_load_failure_)
48 util_.model()->OnWebDataServiceRequestDone(0, NULL);
50 util_.ChangeModelToLoadState();
52 controller_.reset(new KeywordEditorController(util_.profile()));
53 controller_->table_model()->SetObserver(this);
56 virtual void TearDown() OVERRIDE {
61 virtual void OnModelChanged() OVERRIDE {
62 model_changed_count_++;
65 virtual void OnItemsChanged(int start, int length) OVERRIDE {
66 items_changed_count_++;
69 virtual void OnItemsAdded(int start, int length) OVERRIDE {
73 virtual void OnItemsRemoved(int start, int length) OVERRIDE {
77 void VerifyChangeCount(int model_changed_count, int item_changed_count,
78 int added_count, int removed_count) {
79 ASSERT_EQ(model_changed_count, model_changed_count_);
80 ASSERT_EQ(item_changed_count, items_changed_count_);
81 ASSERT_EQ(added_count, added_count_);
82 ASSERT_EQ(removed_count, removed_count_);
86 void ClearChangeCount() {
87 model_changed_count_ = items_changed_count_ = added_count_ =
91 void SimulateDefaultSearchIsManaged(const std::string& url) {
92 util_.SetManagedDefaultSearchPreferences(true,
103 TemplateURLTableModel* table_model() { return controller_->table_model(); }
104 KeywordEditorController* controller() { return controller_.get(); }
105 const TemplateURLServiceTestUtil* util() const { return &util_; }
107 int items_changed_count() const { return items_changed_count_; }
108 int added_count() const { return added_count_; }
109 int removed_count() const { return removed_count_; }
112 scoped_ptr<KeywordEditorController> controller_;
113 TemplateURLServiceTestUtil util_;
114 bool simulate_load_failure_;
116 int model_changed_count_;
117 int items_changed_count_;
122 class KeywordEditorControllerNoWebDataTest
123 : public KeywordEditorControllerTest {
125 KeywordEditorControllerNoWebDataTest() : KeywordEditorControllerTest(true) {}
128 // Tests adding a TemplateURL.
129 TEST_F(KeywordEditorControllerTest, Add) {
130 int original_row_count = table_model()->RowCount();
131 controller()->AddTemplateURL(kA, kB, "http://c");
133 // Verify the observer was notified.
134 VerifyChangeCount(0, 0, 1, 0);
135 if (HasFatalFailure())
138 // Verify the TableModel has the new data.
139 ASSERT_EQ(original_row_count + 1, table_model()->RowCount());
141 // Verify the TemplateURLService has the new data.
142 const TemplateURL* turl = util()->model()->GetTemplateURLForKeyword(kB);
144 EXPECT_EQ(ASCIIToUTF16("a"), turl->short_name());
145 EXPECT_EQ(ASCIIToUTF16("b"), turl->keyword());
146 EXPECT_EQ("http://c", turl->url());
149 // Tests modifying a TemplateURL.
150 TEST_F(KeywordEditorControllerTest, Modify) {
151 controller()->AddTemplateURL(kA, kB, "http://c");
155 TemplateURL* turl = util()->model()->GetTemplateURLs()[0];
156 controller()->ModifyTemplateURL(turl, kA1, kB1, "http://c1");
158 // Make sure it was updated appropriately.
159 VerifyChangeCount(0, 1, 0, 0);
160 EXPECT_EQ(ASCIIToUTF16("a1"), turl->short_name());
161 EXPECT_EQ(ASCIIToUTF16("b1"), turl->keyword());
162 EXPECT_EQ("http://c1", turl->url());
165 // Tests making a TemplateURL the default search provider.
166 TEST_F(KeywordEditorControllerTest, MakeDefault) {
167 int index = controller()->AddTemplateURL(kA, kB, "http://c{searchTerms}");
170 const TemplateURL* turl = util()->model()->GetTemplateURLForKeyword(kB);
171 int new_default = controller()->MakeDefaultTemplateURL(index);
172 EXPECT_EQ(index, new_default);
173 // Making an item the default sends a handful of changes. Which are sent isn't
174 // important, what is important is 'something' is sent.
175 ASSERT_TRUE(items_changed_count() > 0 || added_count() > 0 ||
176 removed_count() > 0);
177 ASSERT_TRUE(util()->model()->GetDefaultSearchProvider() == turl);
179 // Making it default a second time should fail.
180 new_default = controller()->MakeDefaultTemplateURL(index);
181 EXPECT_EQ(-1, new_default);
184 // Tests that a TemplateURL can't be made the default if the default search
185 // provider is managed via policy.
186 TEST_F(KeywordEditorControllerTest, CannotSetDefaultWhileManaged) {
187 controller()->AddTemplateURL(kA, kB, "http://c{searchTerms}");
188 controller()->AddTemplateURL(kA1, kB1, "http://d{searchTerms}");
191 const TemplateURL* turl1 =
192 util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
193 ASSERT_TRUE(turl1 != NULL);
194 const TemplateURL* turl2 =
195 util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
196 ASSERT_TRUE(turl2 != NULL);
198 EXPECT_TRUE(controller()->CanMakeDefault(turl1));
199 EXPECT_TRUE(controller()->CanMakeDefault(turl2));
201 SimulateDefaultSearchIsManaged(turl2->url());
202 EXPECT_TRUE(util()->model()->is_default_search_managed());
204 EXPECT_FALSE(controller()->CanMakeDefault(turl1));
205 EXPECT_FALSE(controller()->CanMakeDefault(turl2));
208 // Tests that a TemplateURL can't be edited if it is the managed default search
210 TEST_F(KeywordEditorControllerTest, EditManagedDefault) {
211 controller()->AddTemplateURL(kA, kB, "http://c{searchTerms}");
212 controller()->AddTemplateURL(kA1, kB1, "http://d{searchTerms}");
215 const TemplateURL* turl1 =
216 util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
217 ASSERT_TRUE(turl1 != NULL);
218 const TemplateURL* turl2 =
219 util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
220 ASSERT_TRUE(turl2 != NULL);
222 EXPECT_TRUE(controller()->CanEdit(turl1));
223 EXPECT_TRUE(controller()->CanEdit(turl2));
225 // Simulate setting a managed default. This will add another template URL to
227 SimulateDefaultSearchIsManaged(turl2->url());
228 EXPECT_TRUE(util()->model()->is_default_search_managed());
229 EXPECT_TRUE(controller()->CanEdit(turl1));
230 EXPECT_TRUE(controller()->CanEdit(turl2));
232 controller()->CanEdit(util()->model()->GetDefaultSearchProvider()));
235 TEST_F(KeywordEditorControllerNoWebDataTest, MakeDefaultNoWebData) {
236 int index = controller()->AddTemplateURL(kA, kB, "http://c{searchTerms}");
239 // This should not result in a crash.
240 int new_default = controller()->MakeDefaultTemplateURL(index);
241 EXPECT_EQ(index, new_default);
244 // Mutates the TemplateURLService and make sure table model is updating
246 TEST_F(KeywordEditorControllerTest, MutateTemplateURLService) {
247 int original_row_count = table_model()->RowCount();
249 TemplateURLData data;
250 data.short_name = ASCIIToUTF16("b");
251 data.SetKeyword(ASCIIToUTF16("a"));
252 TemplateURL* turl = new TemplateURL(util()->profile(), data);
253 util()->model()->Add(turl);
255 // Table model should have updated.
256 VerifyChangeCount(1, 0, 0, 0);
258 // And should contain the newly added TemplateURL.
259 ASSERT_EQ(original_row_count + 1, table_model()->RowCount());
260 ASSERT_GE(table_model()->IndexOfTemplateURL(turl), 0);