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/omnibox_edit_controller.h"
9 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
10 #include "chrome/browser/ui/omnibox/omnibox_view.h"
11 #include "chrome/browser/ui/toolbar/test_toolbar_model.h"
12 #include "chrome/test/base/testing_profile.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 using base::ASCIIToUTF16
;
16 using base::UTF8ToUTF16
;
17 using content::WebContents
;
21 class TestingOmniboxView
: public OmniboxView
{
23 explicit TestingOmniboxView(OmniboxEditController
* controller
)
24 : OmniboxView(NULL
, controller
, NULL
) {}
27 virtual void SaveStateToTab(WebContents
* tab
) OVERRIDE
{}
28 virtual void OnTabChanged(const WebContents
* web_contents
) OVERRIDE
{}
29 virtual void Update() OVERRIDE
{}
30 virtual void OpenMatch(const AutocompleteMatch
& match
,
31 WindowOpenDisposition disposition
,
32 const GURL
& alternate_nav_url
,
33 size_t selected_line
) OVERRIDE
{}
34 virtual base::string16
GetText() const OVERRIDE
{ return text_
; }
35 virtual void SetUserText(const base::string16
& text
,
36 const base::string16
& display_text
,
37 bool update_popup
) OVERRIDE
{
40 virtual void SetWindowTextAndCaretPos(const base::string16
& text
,
43 bool notify_text_changed
) OVERRIDE
{
46 virtual void SetForcedQuery() OVERRIDE
{}
47 virtual bool IsSelectAll() const OVERRIDE
{ return false; }
48 virtual bool DeleteAtEndPressed() OVERRIDE
{ return false; }
49 virtual void GetSelectionBounds(size_t* start
, size_t* end
) const OVERRIDE
{}
50 virtual void SelectAll(bool reversed
) OVERRIDE
{}
51 virtual void RevertAll() OVERRIDE
{}
52 virtual void UpdatePopup() OVERRIDE
{}
53 virtual void SetFocus() OVERRIDE
{}
54 virtual void ApplyCaretVisibility() OVERRIDE
{}
55 virtual void OnTemporaryTextMaybeChanged(
56 const base::string16
& display_text
,
57 bool save_original_selection
,
58 bool notify_text_changed
) OVERRIDE
{
61 virtual bool OnInlineAutocompleteTextMaybeChanged(
62 const base::string16
& display_text
, 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 virtual void OnInlineAutocompleteTextCleared() OVERRIDE
{
69 inline_autocomplete_text_
.clear();
71 virtual void OnRevertTemporaryText() OVERRIDE
{}
72 virtual void OnBeforePossibleChange() OVERRIDE
{}
73 virtual bool OnAfterPossibleChange() OVERRIDE
{ return false; }
74 virtual gfx::NativeView
GetNativeView() const OVERRIDE
{ return NULL
; }
75 virtual gfx::NativeView
GetRelativeWindowForPopup() const OVERRIDE
{
78 virtual void SetGrayTextAutocompletion(
79 const base::string16
& input
) OVERRIDE
{}
80 virtual base::string16
GetGrayTextAutocompletion() const OVERRIDE
{
81 return base::string16();
83 virtual int GetTextWidth() const OVERRIDE
{ return 0; }
84 virtual int GetWidth() const OVERRIDE
{ return 0; }
85 virtual bool IsImeComposing() const OVERRIDE
{ return false; }
86 virtual int GetOmniboxTextLength() const OVERRIDE
{ return 0; }
87 virtual void EmphasizeURLComponents() OVERRIDE
{ }
89 const base::string16
& inline_autocomplete_text() const {
90 return inline_autocomplete_text_
;
95 base::string16 inline_autocomplete_text_
;
97 DISALLOW_COPY_AND_ASSIGN(TestingOmniboxView
);
100 class TestingOmniboxEditController
: public OmniboxEditController
{
102 explicit TestingOmniboxEditController(ToolbarModel
* toolbar_model
)
103 : OmniboxEditController(NULL
),
104 toolbar_model_(toolbar_model
) {
107 // OmniboxEditController:
108 virtual void Update(const content::WebContents
* contents
) OVERRIDE
{}
109 virtual void OnChanged() OVERRIDE
{}
110 virtual void OnSetFocus() OVERRIDE
{}
111 virtual InstantController
* GetInstant() OVERRIDE
{ return NULL
; }
112 virtual WebContents
* GetWebContents() OVERRIDE
{ return NULL
; }
113 virtual ToolbarModel
* GetToolbarModel() OVERRIDE
{ return toolbar_model_
; }
114 virtual const ToolbarModel
* GetToolbarModel() const OVERRIDE
{
115 return toolbar_model_
;
119 ToolbarModel
* toolbar_model_
;
121 DISALLOW_COPY_AND_ASSIGN(TestingOmniboxEditController
);
126 class AutocompleteEditTest
: public ::testing::Test
{
128 TestToolbarModel
* toolbar_model() { return &toolbar_model_
; }
131 TestToolbarModel toolbar_model_
;
134 // Tests various permutations of AutocompleteModel::AdjustTextForCopy.
135 TEST_F(AutocompleteEditTest
, AdjustTextForCopy
) {
137 const char* perm_text
;
139 const bool is_all_selected
;
141 const char* expected_output
;
142 const bool write_url
;
143 const char* expected_url
;
144 const bool extracted_search_terms
;
146 // Test that http:// is inserted if all text is selected.
147 { "a.de/b", 0, true, "a.de/b", "http://a.de/b", true, "http://a.de/b",
150 // Test that http:// is inserted if the host is selected.
151 { "a.de/b", 0, false, "a.de/", "http://a.de/", true, "http://a.de/",
154 // Tests that http:// is inserted if the path is modified.
155 { "a.de/b", 0, false, "a.de/c", "http://a.de/c", true, "http://a.de/c",
158 // Tests that http:// isn't inserted if the host is modified.
159 { "a.de/b", 0, false, "a.com/b", "a.com/b", false, "", false },
161 // Tests that http:// isn't inserted if the start of the selection is 1.
162 { "a.de/b", 1, false, "a.de/b", "a.de/b", false, "", false },
164 // Tests that http:// isn't inserted if a portion of the host is selected.
165 { "a.de/", 0, false, "a.d", "a.d", false, "", false },
167 // Tests that http:// isn't inserted for an https url after the user nukes
169 { "https://a.com/", 0, false, "a.com/", "a.com/", false, "", false },
171 // Tests that http:// isn't inserted if the user adds to the host.
172 { "a.de/", 0, false, "a.de.com/", "a.de.com/", false, "", false },
174 // Tests that we don't get double http if the user manually inserts http.
175 { "a.de/", 0, false, "http://a.de/", "http://a.de/", true, "http://a.de/",
178 // Makes sure intranet urls get 'http://' prefixed to them.
179 { "b/foo", 0, true, "b/foo", "http://b/foo", true, "http://b/foo", false },
181 // Verifies a search term 'foo' doesn't end up with http.
182 { "www.google.com/search?", 0, false, "foo", "foo", false, "", false },
184 // Makes sure extracted search terms are not modified.
185 { "www.google.com/webhp?", 0, true, "hello world", "hello world", false,
188 TestingOmniboxEditController
controller(toolbar_model());
189 TestingOmniboxView
view(&controller
);
190 TestingProfile profile
;
191 // NOTE: The TemplateURLService must be created before the
192 // AutocompleteClassifier so that the SearchProvider gets a non-NULL
193 // TemplateURLService at construction time.
194 TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
195 &profile
, &TemplateURLServiceFactory::BuildInstanceFor
);
196 AutocompleteClassifierFactory::GetInstance()->SetTestingFactory(
197 &profile
, &AutocompleteClassifierFactory::BuildInstanceFor
);
198 OmniboxEditModel
model(&view
, &controller
, &profile
);
200 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(input
); ++i
) {
201 toolbar_model()->set_text(ASCIIToUTF16(input
[i
].perm_text
));
202 model
.UpdatePermanentText();
204 toolbar_model()->set_perform_search_term_replacement(
205 input
[i
].extracted_search_terms
);
207 base::string16 result
= ASCIIToUTF16(input
[i
].input
);
210 model
.AdjustTextForCopy(input
[i
].sel_start
, input
[i
].is_all_selected
,
211 &result
, &url
, &write_url
);
212 EXPECT_EQ(ASCIIToUTF16(input
[i
].expected_output
), result
) << "@: " << i
;
213 EXPECT_EQ(input
[i
].write_url
, write_url
) << " @" << i
;
215 EXPECT_EQ(input
[i
].expected_url
, url
.spec()) << " @" << i
;
219 TEST_F(AutocompleteEditTest
, InlineAutocompleteText
) {
220 TestingOmniboxEditController
controller(toolbar_model());
221 TestingOmniboxView
view(&controller
);
222 TestingProfile profile
;
223 // NOTE: The TemplateURLService must be created before the
224 // AutocompleteClassifier so that the SearchProvider gets a non-NULL
225 // TemplateURLService at construction time.
226 TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
227 &profile
, &TemplateURLServiceFactory::BuildInstanceFor
);
228 AutocompleteClassifierFactory::GetInstance()->SetTestingFactory(
229 &profile
, &AutocompleteClassifierFactory::BuildInstanceFor
);
230 OmniboxEditModel
model(&view
, &controller
, &profile
);
232 // Test if the model updates the inline autocomplete text in the view.
233 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());
234 model
.SetUserText(UTF8ToUTF16("he"));
235 model
.OnPopupDataChanged(UTF8ToUTF16("llo"), NULL
, base::string16(), false);
236 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
237 EXPECT_EQ(UTF8ToUTF16("llo"), view
.inline_autocomplete_text());
239 model
.OnAfterPossibleChange(UTF8ToUTF16("he"), UTF8ToUTF16("hel"), 3, 3,
240 false, true, false, true);
241 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());
242 model
.OnPopupDataChanged(UTF8ToUTF16("lo"), NULL
, base::string16(), false);
243 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
244 EXPECT_EQ(UTF8ToUTF16("lo"), view
.inline_autocomplete_text());
247 EXPECT_EQ(base::string16(), view
.GetText());
248 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());
250 model
.SetUserText(UTF8ToUTF16("he"));
251 model
.OnPopupDataChanged(UTF8ToUTF16("llo"), NULL
, base::string16(), false);
252 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
253 EXPECT_EQ(UTF8ToUTF16("llo"), view
.inline_autocomplete_text());
255 model
.AcceptTemporaryTextAsUserText();
256 EXPECT_EQ(UTF8ToUTF16("hello"), view
.GetText());
257 EXPECT_EQ(base::string16(), view
.inline_autocomplete_text());