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/strings/utf_string_conversions.h"
6 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
7 #include "chrome/browser/search_engines/template_url_service_factory.h"
8 #include "chrome/browser/ui/omnibox/chrome_omnibox_client.h"
9 #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
10 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
11 #include "chrome/browser/ui/omnibox/omnibox_view.h"
12 #include "chrome/browser/ui/toolbar/test_toolbar_model.h"
13 #include "chrome/test/base/testing_profile.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 using base::ASCIIToUTF16
;
18 using base::UTF8ToUTF16
;
19 using content::WebContents
;
23 class TestingOmniboxView
: public OmniboxView
{
25 explicit TestingOmniboxView(OmniboxEditController
* controller
)
26 : OmniboxView(nullptr, controller
, nullptr) {}
29 void Update() override
{}
30 void OpenMatch(const AutocompleteMatch
& match
,
31 WindowOpenDisposition disposition
,
32 const GURL
& alternate_nav_url
,
33 const base::string16
& pasted_text
,
34 size_t selected_line
) override
{}
35 base::string16
GetText() const override
{ return text_
; }
36 void SetUserText(const base::string16
& text
,
37 const base::string16
& display_text
,
38 bool update_popup
) override
{
41 void SetWindowTextAndCaretPos(const base::string16
& text
,
44 bool notify_text_changed
) override
{
47 void SetForcedQuery() override
{}
48 bool IsSelectAll() const override
{ return false; }
49 bool DeleteAtEndPressed() override
{ return false; }
50 void GetSelectionBounds(size_t* start
, size_t* end
) const override
{}
51 void SelectAll(bool reversed
) override
{}
52 void RevertAll() override
{}
53 void UpdatePopup() override
{}
54 void SetFocus() override
{}
55 void ApplyCaretVisibility() override
{}
56 void OnTemporaryTextMaybeChanged(const base::string16
& display_text
,
57 bool save_original_selection
,
58 bool notify_text_changed
) override
{
61 bool OnInlineAutocompleteTextMaybeChanged(const base::string16
& display_text
,
62 size_t user_text_length
) override
{
63 const bool text_changed
= text_
!= display_text
;
65 inline_autocomplete_text_
= display_text
.substr(user_text_length
);
68 void OnInlineAutocompleteTextCleared() override
{
69 inline_autocomplete_text_
.clear();
71 void OnRevertTemporaryText() override
{}
72 void OnBeforePossibleChange() override
{}
73 bool OnAfterPossibleChange() override
{ return false; }
74 gfx::NativeView
GetNativeView() const override
{ return NULL
; }
75 gfx::NativeView
GetRelativeWindowForPopup() const override
{ return NULL
; }
76 void SetGrayTextAutocompletion(const base::string16
& input
) override
{}
77 base::string16
GetGrayTextAutocompletion() const override
{
78 return base::string16();
80 int GetTextWidth() const override
{ return 0; }
81 int GetWidth() const override
{ return 0; }
82 bool IsImeComposing() const override
{ return false; }
83 int GetOmniboxTextLength() const override
{ return 0; }
84 void EmphasizeURLComponents() override
{}
86 const base::string16
& inline_autocomplete_text() const {
87 return inline_autocomplete_text_
;
92 base::string16 inline_autocomplete_text_
;
94 DISALLOW_COPY_AND_ASSIGN(TestingOmniboxView
);
97 class TestingOmniboxEditController
: public OmniboxEditController
{
99 explicit TestingOmniboxEditController(ToolbarModel
* toolbar_model
)
100 : OmniboxEditController(NULL
),
101 toolbar_model_(toolbar_model
) {
105 // OmniboxEditController:
106 void UpdateWithoutTabRestore() override
{}
107 void OnChanged() override
{}
108 void OnSetFocus() override
{}
109 void ShowURL() override
{}
110 WebContents
* GetWebContents() override
{ return NULL
; }
111 ToolbarModel
* GetToolbarModel() override
{ return toolbar_model_
; }
112 const ToolbarModel
* GetToolbarModel() const override
{
113 return toolbar_model_
;
117 ToolbarModel
* toolbar_model_
;
119 DISALLOW_COPY_AND_ASSIGN(TestingOmniboxEditController
);
124 class AutocompleteEditTest
: public ::testing::Test
{
126 TestToolbarModel
* toolbar_model() { return &toolbar_model_
; }
129 content::TestBrowserThreadBundle thread_bundle_
;
130 TestToolbarModel toolbar_model_
;
133 // Tests various permutations of AutocompleteModel::AdjustTextForCopy.
134 TEST_F(AutocompleteEditTest
, AdjustTextForCopy
) {
136 const char* perm_text
;
138 const bool is_all_selected
;
140 const char* expected_output
;
141 const bool write_url
;
142 const char* expected_url
;
143 const bool extracted_search_terms
;
145 // Test that http:// is inserted if all text is selected.
146 { "a.de/b", 0, true, "a.de/b", "http://a.de/b", true, "http://a.de/b",
149 // Test that http:// is inserted if the host is selected.
150 { "a.de/b", 0, false, "a.de/", "http://a.de/", true, "http://a.de/",
153 // Tests that http:// is inserted if the path is modified.
154 { "a.de/b", 0, false, "a.de/c", "http://a.de/c", true, "http://a.de/c",
157 // Tests that http:// isn't inserted if the host is modified.
158 { "a.de/b", 0, false, "a.com/b", "a.com/b", false, "", false },
160 // Tests that http:// isn't inserted if the start of the selection is 1.
161 { "a.de/b", 1, false, "a.de/b", "a.de/b", false, "", false },
163 // Tests that http:// isn't inserted if a portion of the host is selected.
164 { "a.de/", 0, false, "a.d", "a.d", false, "", false },
166 // Tests that http:// isn't inserted for an https url after the user nukes
168 { "https://a.com/", 0, false, "a.com/", "a.com/", false, "", false },
170 // Tests that http:// isn't inserted if the user adds to the host.
171 { "a.de/", 0, false, "a.de.com/", "a.de.com/", false, "", false },
173 // Tests that we don't get double http if the user manually inserts http.
174 { "a.de/", 0, false, "http://a.de/", "http://a.de/", true, "http://a.de/",
177 // Makes sure intranet urls get 'http://' prefixed to them.
178 { "b/foo", 0, true, "b/foo", "http://b/foo", true, "http://b/foo", false },
180 // Verifies a search term 'foo' doesn't end up with http.
181 { "www.google.com/search?", 0, false, "foo", "foo", false, "", false },
183 // Makes sure extracted search terms are not modified.
184 { "www.google.com/webhp?", 0, true, "hello world", "hello world", false,
187 TestingOmniboxEditController
controller(toolbar_model());
188 TestingOmniboxView
view(&controller
);
189 TestingProfile profile
;
190 // NOTE: The TemplateURLService must be created before the
191 // AutocompleteClassifier so that the SearchProvider gets a non-NULL
192 // TemplateURLService at construction time.
193 TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
194 &profile
, &TemplateURLServiceFactory::BuildInstanceFor
);
195 AutocompleteClassifierFactory::GetInstance()->SetTestingFactory(
196 &profile
, &AutocompleteClassifierFactory::BuildInstanceFor
);
197 OmniboxEditModel
model(
199 make_scoped_ptr(new ChromeOmniboxClient(&controller
, &profile
)),
202 for (size_t i
= 0; i
< arraysize(input
); ++i
) {
203 toolbar_model()->set_text(ASCIIToUTF16(input
[i
].perm_text
));
204 model
.UpdatePermanentText();
206 toolbar_model()->set_perform_search_term_replacement(
207 input
[i
].extracted_search_terms
);
209 base::string16 result
= ASCIIToUTF16(input
[i
].input
);
212 model
.AdjustTextForCopy(input
[i
].sel_start
, input
[i
].is_all_selected
,
213 &result
, &url
, &write_url
);
214 EXPECT_EQ(ASCIIToUTF16(input
[i
].expected_output
), result
) << "@: " << i
;
215 EXPECT_EQ(input
[i
].write_url
, write_url
) << " @" << i
;
217 EXPECT_EQ(input
[i
].expected_url
, url
.spec()) << " @" << i
;
221 TEST_F(AutocompleteEditTest
, InlineAutocompleteText
) {
222 TestingOmniboxEditController
controller(toolbar_model());
223 TestingOmniboxView
view(&controller
);
224 TestingProfile profile
;
225 // NOTE: The TemplateURLService must be created before the
226 // AutocompleteClassifier so that the SearchProvider gets a non-NULL
227 // TemplateURLService at construction time.
228 TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
229 &profile
, &TemplateURLServiceFactory::BuildInstanceFor
);
230 AutocompleteClassifierFactory::GetInstance()->SetTestingFactory(
231 &profile
, &AutocompleteClassifierFactory::BuildInstanceFor
);
232 OmniboxEditModel
model(
234 make_scoped_ptr(new ChromeOmniboxClient(&controller
, &profile
)),
237 // Test if the model updates the inline autocomplete text in the view.
238 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());
239 model
.SetUserText(UTF8ToUTF16("he"));
240 model
.OnPopupDataChanged(UTF8ToUTF16("llo"), NULL
, base::string16(), false);
241 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
242 EXPECT_EQ(UTF8ToUTF16("llo"), view
.inline_autocomplete_text());
244 model
.OnAfterPossibleChange(UTF8ToUTF16("he"), UTF8ToUTF16("hel"), 3, 3,
245 false, true, false, true);
246 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());
247 model
.OnPopupDataChanged(UTF8ToUTF16("lo"), NULL
, base::string16(), false);
248 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
249 EXPECT_EQ(UTF8ToUTF16("lo"), view
.inline_autocomplete_text());
252 EXPECT_EQ(base::string16(), view
.GetText());
253 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());
255 model
.SetUserText(UTF8ToUTF16("he"));
256 model
.OnPopupDataChanged(UTF8ToUTF16("llo"), NULL
, base::string16(), false);
257 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
258 EXPECT_EQ(UTF8ToUTF16("llo"), view
.inline_autocomplete_text());
260 model
.AcceptTemporaryTextAsUserText();
261 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
262 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());