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/message_loop/message_loop.h"
6 #include "base/strings/string16.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/search_engines/template_url.h"
11 #include "chrome/browser/search_engines/template_url_service.h"
12 #include "chrome/browser/search_engines/template_url_service_factory.h"
13 #include "chrome/browser/ui/search_engines/keyword_editor_controller.h"
14 #include "chrome/browser/ui/search_engines/template_url_table_model.h"
15 #include "chrome/common/pref_names.h"
16 #include "chrome/test/base/testing_pref_service_syncable.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/browser/notification_service.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "ui/base/models/table_model_observer.h"
22 using base::ASCIIToUTF16
;
24 static const base::string16
kA(ASCIIToUTF16("a"));
25 static const base::string16
kA1(ASCIIToUTF16("a1"));
26 static const base::string16
kB(ASCIIToUTF16("b"));
27 static const base::string16
kB1(ASCIIToUTF16("b1"));
29 // Base class for keyword editor tests. Creates a profile containing an
30 // empty TemplateURLService.
31 class KeywordEditorControllerTest
: public testing::Test
,
32 public ui::TableModelObserver
{
34 // Initializes all of the state.
35 void Init(bool simulate_load_failure
);
37 virtual void SetUp() {
41 virtual void OnModelChanged() OVERRIDE
{
42 model_changed_count_
++;
45 virtual void OnItemsChanged(int start
, int length
) OVERRIDE
{
46 items_changed_count_
++;
49 virtual void OnItemsAdded(int start
, int length
) OVERRIDE
{
53 virtual void OnItemsRemoved(int start
, int length
) OVERRIDE
{
57 void VerifyChangeCount(int model_changed_count
, int item_changed_count
,
58 int added_count
, int removed_count
) {
59 ASSERT_EQ(model_changed_count
, model_changed_count_
);
60 ASSERT_EQ(item_changed_count
, items_changed_count_
);
61 ASSERT_EQ(added_count
, added_count_
);
62 ASSERT_EQ(removed_count
, removed_count_
);
66 void ClearChangeCount() {
67 model_changed_count_
= items_changed_count_
= added_count_
=
71 void SimulateDefaultSearchIsManaged(const std::string
& url
) {
72 ASSERT_FALSE(url
.empty());
73 TestingPrefServiceSyncable
* service
= profile_
->GetTestingPrefService();
74 service
->SetManagedPref(prefs::kDefaultSearchProviderEnabled
,
75 new base::FundamentalValue(true));
76 service
->SetManagedPref(prefs::kDefaultSearchProviderSearchURL
,
77 new base::StringValue(url
));
78 service
->SetManagedPref(prefs::kDefaultSearchProviderName
,
79 new base::StringValue("managed"));
80 // Clear the IDs that are not specified via policy.
81 service
->SetManagedPref(prefs::kDefaultSearchProviderID
,
82 new base::StringValue(std::string()));
83 service
->SetManagedPref(prefs::kDefaultSearchProviderPrepopulateID
,
84 new base::StringValue(std::string()));
85 model_
->Observe(chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED
,
86 content::NotificationService::AllSources(),
87 content::NotificationService::NoDetails());
90 TemplateURLTableModel
* table_model() const {
91 return controller_
->table_model();
95 base::MessageLoopForUI message_loop_
;
96 scoped_ptr
<TestingProfile
> profile_
;
97 scoped_ptr
<KeywordEditorController
> controller_
;
98 TemplateURLService
* model_
;
100 int model_changed_count_
;
101 int items_changed_count_
;
106 void KeywordEditorControllerTest::Init(bool simulate_load_failure
) {
109 // If init is called twice, make sure that the controller is destroyed before
112 profile_
.reset(new TestingProfile());
113 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
114 profile_
.get(), &TemplateURLServiceFactory::BuildInstanceFor
);
116 model_
= TemplateURLServiceFactory::GetForProfile(profile_
.get());
117 if (simulate_load_failure
)
118 model_
->OnWebDataServiceRequestDone(0, NULL
);
120 controller_
.reset(new KeywordEditorController(profile_
.get()));
121 controller_
->table_model()->SetObserver(this);
124 // Tests adding a TemplateURL.
125 TEST_F(KeywordEditorControllerTest
, Add
) {
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(1, table_model()->RowCount());
136 // Verify the TemplateURLService has the new entry.
137 ASSERT_EQ(1U, model_
->GetTemplateURLs().size());
139 // Verify the entry is what we added.
140 const TemplateURL
* turl
= model_
->GetTemplateURLs()[0];
141 EXPECT_EQ(ASCIIToUTF16("a"), turl
->short_name());
142 EXPECT_EQ(ASCIIToUTF16("b"), turl
->keyword());
143 EXPECT_EQ("http://c", turl
->url());
146 // Tests modifying a TemplateURL.
147 TEST_F(KeywordEditorControllerTest
, Modify
) {
148 controller_
->AddTemplateURL(kA
, kB
, "http://c");
152 TemplateURL
* turl
= model_
->GetTemplateURLs()[0];
153 controller_
->ModifyTemplateURL(turl
, kA1
, kB1
, "http://c1");
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 EXPECT_EQ("http://c1", turl
->url());
162 // Tests making a TemplateURL the default search provider.
163 TEST_F(KeywordEditorControllerTest
, MakeDefault
) {
164 controller_
->AddTemplateURL(kA
, kB
, "http://c{searchTerms}");
167 const TemplateURL
* turl
= model_
->GetTemplateURLs()[0];
168 int new_default
= controller_
->MakeDefaultTemplateURL(0);
169 EXPECT_EQ(0, new_default
);
170 // Making an item the default sends a handful of changes. Which are sent isn't
171 // important, what is important is 'something' is sent.
172 ASSERT_TRUE(items_changed_count_
> 0 || added_count_
> 0 ||
174 ASSERT_TRUE(model_
->GetDefaultSearchProvider() == turl
);
176 // Making it default a second time should fail.
177 new_default
= controller_
->MakeDefaultTemplateURL(0);
178 EXPECT_EQ(-1, new_default
);
181 // Tests that a TemplateURL can't be made the default if the default search
182 // provider is managed via policy.
183 TEST_F(KeywordEditorControllerTest
, CannotSetDefaultWhileManaged
) {
184 controller_
->AddTemplateURL(kA
, kB
, "http://c{searchTerms}");
185 controller_
->AddTemplateURL(kA1
, kB1
, "http://d{searchTerms}");
188 const TemplateURL
* turl1
=
189 model_
->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
190 ASSERT_TRUE(turl1
!= NULL
);
191 const TemplateURL
* turl2
=
192 model_
->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
193 ASSERT_TRUE(turl2
!= NULL
);
195 EXPECT_TRUE(controller_
->CanMakeDefault(turl1
));
196 EXPECT_TRUE(controller_
->CanMakeDefault(turl2
));
198 SimulateDefaultSearchIsManaged(turl2
->url());
199 EXPECT_TRUE(model_
->is_default_search_managed());
201 EXPECT_FALSE(controller_
->CanMakeDefault(turl1
));
202 EXPECT_FALSE(controller_
->CanMakeDefault(turl2
));
205 // Tests that a TemplateURL can't be edited if it is the managed default search
207 TEST_F(KeywordEditorControllerTest
, EditManagedDefault
) {
208 controller_
->AddTemplateURL(kA
, kB
, "http://c{searchTerms}");
209 controller_
->AddTemplateURL(kA1
, kB1
, "http://d{searchTerms}");
212 const TemplateURL
* turl1
=
213 model_
->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
214 ASSERT_TRUE(turl1
!= NULL
);
215 const TemplateURL
* turl2
=
216 model_
->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
217 ASSERT_TRUE(turl2
!= NULL
);
219 EXPECT_TRUE(controller_
->CanEdit(turl1
));
220 EXPECT_TRUE(controller_
->CanEdit(turl2
));
222 // Simulate setting a managed default. This will add another template URL to
224 SimulateDefaultSearchIsManaged(turl2
->url());
225 EXPECT_TRUE(model_
->is_default_search_managed());
226 EXPECT_TRUE(controller_
->CanEdit(turl1
));
227 EXPECT_TRUE(controller_
->CanEdit(turl2
));
228 EXPECT_FALSE(controller_
->CanEdit(model_
->GetDefaultSearchProvider()));
231 TEST_F(KeywordEditorControllerTest
, MakeDefaultNoWebData
) {
232 // Simulate a failure to load Web Data.
235 controller_
->AddTemplateURL(kA
, kB
, "http://c{searchTerms}");
238 // This should not result in a crash.
239 int new_default
= controller_
->MakeDefaultTemplateURL(0);
240 EXPECT_EQ(0, new_default
);
243 // Mutates the TemplateURLService and make sure table model is updating
245 TEST_F(KeywordEditorControllerTest
, MutateTemplateURLService
) {
246 TemplateURLData data
;
247 data
.short_name
= ASCIIToUTF16("b");
248 data
.SetKeyword(ASCIIToUTF16("a"));
249 TemplateURL
* turl
= new TemplateURL(profile_
.get(), data
);
252 // Table model should have updated.
253 VerifyChangeCount(1, 0, 0, 0);
255 // And should contain the newly added TemplateURL.
256 ASSERT_EQ(1, table_model()->RowCount());
257 ASSERT_EQ(0, table_model()->IndexOfTemplateURL(turl
));