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_service_factory_test_util.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/test/base/testing_pref_service_syncable.h"
13 #include "chrome/test/base/testing_profile.h"
14 #include "components/search_engines/template_url.h"
15 #include "components/search_engines/template_url_service.h"
16 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/base/models/table_model_observer.h"
20 using base::ASCIIToUTF16
;
22 static const base::string16
kA(ASCIIToUTF16("a"));
23 static const base::string16
kA1(ASCIIToUTF16("a1"));
24 static const base::string16
kB(ASCIIToUTF16("b"));
25 static const base::string16
kB1(ASCIIToUTF16("b1"));
27 // Base class for keyword editor tests. Creates a profile containing an
28 // empty TemplateURLService.
29 class KeywordEditorControllerTest
: public testing::Test
,
30 public ui::TableModelObserver
{
32 KeywordEditorControllerTest()
34 simulate_load_failure_(false),
35 model_changed_count_(0),
36 items_changed_count_(0),
40 explicit KeywordEditorControllerTest(bool simulate_load_failure
)
42 simulate_load_failure_(simulate_load_failure
),
43 model_changed_count_(0),
44 items_changed_count_(0),
48 void SetUp() override
{
49 if (simulate_load_failure_
)
50 util_
.model()->OnWebDataServiceRequestDone(0, NULL
);
54 controller_
.reset(new KeywordEditorController(&profile_
));
55 controller_
->table_model()->SetObserver(this);
58 void TearDown() override
{ controller_
.reset(); }
60 void OnModelChanged() override
{ model_changed_count_
++; }
62 void OnItemsChanged(int start
, int length
) override
{
63 items_changed_count_
++;
66 void OnItemsAdded(int start
, int length
) override
{ added_count_
++; }
68 void OnItemsRemoved(int start
, int length
) override
{ removed_count_
++; }
70 void VerifyChangeCount(int model_changed_count
, int item_changed_count
,
71 int added_count
, int removed_count
) {
72 ASSERT_EQ(model_changed_count
, model_changed_count_
);
73 ASSERT_EQ(item_changed_count
, items_changed_count_
);
74 ASSERT_EQ(added_count
, added_count_
);
75 ASSERT_EQ(removed_count
, removed_count_
);
79 void ClearChangeCount() {
80 model_changed_count_
= items_changed_count_
= added_count_
=
84 void SimulateDefaultSearchIsManaged(const std::string
& url
) {
85 util_
.SetManagedDefaultSearchPreferences(true,
96 TemplateURLTableModel
* table_model() { return controller_
->table_model(); }
97 KeywordEditorController
* controller() { return controller_
.get(); }
98 const TemplateURLServiceFactoryTestUtil
* util() const { return &util_
; }
100 int items_changed_count() const { return items_changed_count_
; }
101 int added_count() const { return added_count_
; }
102 int removed_count() const { return removed_count_
; }
105 content::TestBrowserThreadBundle thread_bundle_
;
106 TestingProfile profile_
;
107 scoped_ptr
<KeywordEditorController
> controller_
;
108 TemplateURLServiceFactoryTestUtil util_
;
109 bool simulate_load_failure_
;
111 int model_changed_count_
;
112 int items_changed_count_
;
117 class KeywordEditorControllerNoWebDataTest
118 : public KeywordEditorControllerTest
{
120 KeywordEditorControllerNoWebDataTest() : KeywordEditorControllerTest(true) {}
123 // Tests adding a TemplateURL.
124 TEST_F(KeywordEditorControllerTest
, Add
) {
125 int original_row_count
= table_model()->RowCount();
126 controller()->AddTemplateURL(kA
, kB
, "http://c");
128 // Verify the observer was notified.
129 VerifyChangeCount(0, 0, 1, 0);
130 if (HasFatalFailure())
133 // Verify the TableModel has the new data.
134 ASSERT_EQ(original_row_count
+ 1, table_model()->RowCount());
136 // Verify the TemplateURLService has the new data.
137 const TemplateURL
* turl
= util()->model()->GetTemplateURLForKeyword(kB
);
139 EXPECT_EQ(ASCIIToUTF16("a"), turl
->short_name());
140 EXPECT_EQ(ASCIIToUTF16("b"), turl
->keyword());
141 EXPECT_EQ("http://c", turl
->url());
144 // Tests modifying a TemplateURL.
145 TEST_F(KeywordEditorControllerTest
, Modify
) {
146 controller()->AddTemplateURL(kA
, kB
, "http://c");
150 TemplateURL
* turl
= util()->model()->GetTemplateURLs()[0];
151 controller()->ModifyTemplateURL(turl
, kA1
, kB1
, "http://c1");
153 // Make sure it was updated appropriately.
154 VerifyChangeCount(0, 1, 0, 0);
155 EXPECT_EQ(ASCIIToUTF16("a1"), turl
->short_name());
156 EXPECT_EQ(ASCIIToUTF16("b1"), turl
->keyword());
157 EXPECT_EQ("http://c1", turl
->url());
160 // Tests making a TemplateURL the default search provider.
161 TEST_F(KeywordEditorControllerTest
, MakeDefault
) {
162 int index
= controller()->AddTemplateURL(kA
, kB
, "http://c{searchTerms}");
165 const TemplateURL
* turl
= util()->model()->GetTemplateURLForKeyword(kB
);
166 int new_default
= controller()->MakeDefaultTemplateURL(index
);
167 EXPECT_EQ(index
, new_default
);
168 // Making an item the default sends a handful of changes. Which are sent isn't
169 // important, what is important is 'something' is sent.
170 ASSERT_TRUE(items_changed_count() > 0 || added_count() > 0 ||
171 removed_count() > 0);
172 ASSERT_TRUE(util()->model()->GetDefaultSearchProvider() == turl
);
174 // Making it default a second time should fail.
175 new_default
= controller()->MakeDefaultTemplateURL(index
);
176 EXPECT_EQ(-1, new_default
);
179 // Tests that a TemplateURL can't be made the default if the default search
180 // provider is managed via policy.
181 TEST_F(KeywordEditorControllerTest
, CannotSetDefaultWhileManaged
) {
182 controller()->AddTemplateURL(kA
, kB
, "http://c{searchTerms}");
183 controller()->AddTemplateURL(kA1
, kB1
, "http://d{searchTerms}");
186 const TemplateURL
* turl1
=
187 util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
188 ASSERT_TRUE(turl1
!= NULL
);
189 const TemplateURL
* turl2
=
190 util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
191 ASSERT_TRUE(turl2
!= NULL
);
193 EXPECT_TRUE(controller()->CanMakeDefault(turl1
));
194 EXPECT_TRUE(controller()->CanMakeDefault(turl2
));
196 SimulateDefaultSearchIsManaged(turl2
->url());
197 EXPECT_TRUE(util()->model()->is_default_search_managed());
199 EXPECT_FALSE(controller()->CanMakeDefault(turl1
));
200 EXPECT_FALSE(controller()->CanMakeDefault(turl2
));
203 // Tests that a TemplateURL can't be edited if it is the managed default search
205 TEST_F(KeywordEditorControllerTest
, EditManagedDefault
) {
206 controller()->AddTemplateURL(kA
, kB
, "http://c{searchTerms}");
207 controller()->AddTemplateURL(kA1
, kB1
, "http://d{searchTerms}");
210 const TemplateURL
* turl1
=
211 util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
212 ASSERT_TRUE(turl1
!= NULL
);
213 const TemplateURL
* turl2
=
214 util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
215 ASSERT_TRUE(turl2
!= NULL
);
217 EXPECT_TRUE(controller()->CanEdit(turl1
));
218 EXPECT_TRUE(controller()->CanEdit(turl2
));
220 // Simulate setting a managed default. This will add another template URL to
222 SimulateDefaultSearchIsManaged(turl2
->url());
223 EXPECT_TRUE(util()->model()->is_default_search_managed());
224 EXPECT_TRUE(controller()->CanEdit(turl1
));
225 EXPECT_TRUE(controller()->CanEdit(turl2
));
227 controller()->CanEdit(util()->model()->GetDefaultSearchProvider()));
230 TEST_F(KeywordEditorControllerNoWebDataTest
, MakeDefaultNoWebData
) {
231 int index
= controller()->AddTemplateURL(kA
, kB
, "http://c{searchTerms}");
234 // This should not result in a crash.
235 int new_default
= controller()->MakeDefaultTemplateURL(index
);
236 EXPECT_EQ(index
, new_default
);
239 // Mutates the TemplateURLService and make sure table model is updating
241 TEST_F(KeywordEditorControllerTest
, MutateTemplateURLService
) {
242 int original_row_count
= table_model()->RowCount();
244 TemplateURLData data
;
245 data
.short_name
= ASCIIToUTF16("b");
246 data
.SetKeyword(ASCIIToUTF16("a"));
247 TemplateURL
* turl
= new TemplateURL(data
);
248 util()->model()->Add(turl
);
250 // Table model should have updated.
251 VerifyChangeCount(1, 0, 0, 0);
253 // And should contain the newly added TemplateURL.
254 ASSERT_EQ(original_row_count
+ 1, table_model()->RowCount());
255 ASSERT_GE(table_model()->IndexOfTemplateURL(turl
), 0);