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/chrome_omnibox_edit_controller.h"
10 #include "chrome/browser/ui/toolbar/test_toolbar_model.h"
11 #include "chrome/test/base/testing_profile.h"
12 #include "components/omnibox/browser/omnibox_edit_model.h"
13 #include "components/omnibox/browser/omnibox_view.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(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 ChromeOmniboxEditController
{
99 explicit TestingOmniboxEditController(ToolbarModel
* toolbar_model
)
100 : ChromeOmniboxEditController(NULL
), toolbar_model_(toolbar_model
) {}
103 // ChromeOmniboxEditController:
104 void UpdateWithoutTabRestore() override
{}
105 void OnChanged() override
{}
106 void OnSetFocus() override
{}
107 void ShowURL() override
{}
108 ToolbarModel
* GetToolbarModel() override
{ return toolbar_model_
; }
109 const ToolbarModel
* GetToolbarModel() const override
{
110 return toolbar_model_
;
112 WebContents
* GetWebContents() override
{ return nullptr; }
115 ToolbarModel
* toolbar_model_
;
117 DISALLOW_COPY_AND_ASSIGN(TestingOmniboxEditController
);
122 class AutocompleteEditTest
: public ::testing::Test
{
124 TestToolbarModel
* toolbar_model() { return &toolbar_model_
; }
127 content::TestBrowserThreadBundle thread_bundle_
;
128 TestToolbarModel toolbar_model_
;
131 // Tests various permutations of AutocompleteModel::AdjustTextForCopy.
132 TEST_F(AutocompleteEditTest
, AdjustTextForCopy
) {
134 const char* perm_text
;
136 const bool is_all_selected
;
138 const char* expected_output
;
139 const bool write_url
;
140 const char* expected_url
;
141 const bool extracted_search_terms
;
143 // Test that http:// is inserted if all text is selected.
144 { "a.de/b", 0, true, "a.de/b", "http://a.de/b", true, "http://a.de/b",
147 // Test that http:// is inserted if the host is selected.
148 { "a.de/b", 0, false, "a.de/", "http://a.de/", true, "http://a.de/",
151 // Tests that http:// is inserted if the path is modified.
152 { "a.de/b", 0, false, "a.de/c", "http://a.de/c", true, "http://a.de/c",
155 // Tests that http:// isn't inserted if the host is modified.
156 { "a.de/b", 0, false, "a.com/b", "a.com/b", false, "", false },
158 // Tests that http:// isn't inserted if the start of the selection is 1.
159 { "a.de/b", 1, false, "a.de/b", "a.de/b", false, "", false },
161 // Tests that http:// isn't inserted if a portion of the host is selected.
162 { "a.de/", 0, false, "a.d", "a.d", false, "", false },
164 // Tests that http:// isn't inserted for an https url after the user nukes
166 { "https://a.com/", 0, false, "a.com/", "a.com/", false, "", false },
168 // Tests that http:// isn't inserted if the user adds to the host.
169 { "a.de/", 0, false, "a.de.com/", "a.de.com/", false, "", false },
171 // Tests that we don't get double http if the user manually inserts http.
172 { "a.de/", 0, false, "http://a.de/", "http://a.de/", true, "http://a.de/",
175 // Makes sure intranet urls get 'http://' prefixed to them.
176 { "b/foo", 0, true, "b/foo", "http://b/foo", true, "http://b/foo", false },
178 // Verifies a search term 'foo' doesn't end up with http.
179 { "www.google.com/search?", 0, false, "foo", "foo", false, "", false },
181 // Makes sure extracted search terms are not modified.
182 { "www.google.com/webhp?", 0, true, "hello world", "hello world", false,
185 TestingOmniboxEditController
controller(toolbar_model());
186 TestingOmniboxView
view(&controller
);
187 TestingProfile profile
;
188 // NOTE: The TemplateURLService must be created before the
189 // AutocompleteClassifier so that the SearchProvider gets a non-NULL
190 // TemplateURLService at construction time.
191 TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
192 &profile
, &TemplateURLServiceFactory::BuildInstanceFor
);
193 AutocompleteClassifierFactory::GetInstance()->SetTestingFactory(
194 &profile
, &AutocompleteClassifierFactory::BuildInstanceFor
);
195 OmniboxEditModel
model(
197 make_scoped_ptr(new ChromeOmniboxClient(&controller
, &profile
)));
199 for (size_t i
= 0; i
< arraysize(input
); ++i
) {
200 toolbar_model()->set_text(ASCIIToUTF16(input
[i
].perm_text
));
201 model
.UpdatePermanentText();
203 toolbar_model()->set_perform_search_term_replacement(
204 input
[i
].extracted_search_terms
);
206 base::string16 result
= ASCIIToUTF16(input
[i
].input
);
209 model
.AdjustTextForCopy(input
[i
].sel_start
, input
[i
].is_all_selected
,
210 &result
, &url
, &write_url
);
211 EXPECT_EQ(ASCIIToUTF16(input
[i
].expected_output
), result
) << "@: " << i
;
212 EXPECT_EQ(input
[i
].write_url
, write_url
) << " @" << i
;
214 EXPECT_EQ(input
[i
].expected_url
, url
.spec()) << " @" << i
;
218 TEST_F(AutocompleteEditTest
, InlineAutocompleteText
) {
219 TestingOmniboxEditController
controller(toolbar_model());
220 TestingOmniboxView
view(&controller
);
221 TestingProfile profile
;
222 // NOTE: The TemplateURLService must be created before the
223 // AutocompleteClassifier so that the SearchProvider gets a non-NULL
224 // TemplateURLService at construction time.
225 TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
226 &profile
, &TemplateURLServiceFactory::BuildInstanceFor
);
227 AutocompleteClassifierFactory::GetInstance()->SetTestingFactory(
228 &profile
, &AutocompleteClassifierFactory::BuildInstanceFor
);
229 OmniboxEditModel
model(
231 make_scoped_ptr(new ChromeOmniboxClient(&controller
, &profile
)));
233 // Test if the model updates the inline autocomplete text in the view.
234 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());
235 model
.SetUserText(UTF8ToUTF16("he"));
236 model
.OnPopupDataChanged(UTF8ToUTF16("llo"), NULL
, base::string16(), false);
237 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
238 EXPECT_EQ(UTF8ToUTF16("llo"), view
.inline_autocomplete_text());
240 model
.OnAfterPossibleChange(UTF8ToUTF16("he"), UTF8ToUTF16("hel"), 3, 3,
241 false, true, false, true);
242 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());
243 model
.OnPopupDataChanged(UTF8ToUTF16("lo"), NULL
, base::string16(), false);
244 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
245 EXPECT_EQ(UTF8ToUTF16("lo"), view
.inline_autocomplete_text());
248 EXPECT_EQ(base::string16(), view
.GetText());
249 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());
251 model
.SetUserText(UTF8ToUTF16("he"));
252 model
.OnPopupDataChanged(UTF8ToUTF16("llo"), NULL
, base::string16(), false);
253 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
254 EXPECT_EQ(UTF8ToUTF16("llo"), view
.inline_autocomplete_text());
256 model
.AcceptTemporaryTextAsUserText();
257 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
258 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());