| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" |
| #include "chrome/browser/search_engines/template_url_service_factory.h" |
| #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h" |
| #include "chrome/browser/ui/omnibox/omnibox_edit_model.h" |
| #include "chrome/browser/ui/omnibox/omnibox_view.h" |
| #include "chrome/browser/ui/toolbar/test_toolbar_model.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using base::ASCIIToUTF16; |
| using base::UTF8ToUTF16; |
| using content::WebContents; |
| |
| namespace { |
| |
| class TestingOmniboxView : public OmniboxView { |
| public: |
| explicit TestingOmniboxView(OmniboxEditController* controller) |
| : OmniboxView(NULL, controller, NULL) {} |
| |
| // OmniboxView: |
| virtual void SaveStateToTab(WebContents* tab) OVERRIDE {} |
| virtual void OnTabChanged(const WebContents* web_contents) OVERRIDE {} |
| virtual void Update() OVERRIDE {} |
| virtual void OpenMatch(const AutocompleteMatch& match, |
| WindowOpenDisposition disposition, |
| const GURL& alternate_nav_url, |
| const base::string16& pasted_text, |
| size_t selected_line) OVERRIDE {} |
| virtual base::string16 GetText() const OVERRIDE { return text_; } |
| virtual void SetUserText(const base::string16& text, |
| const base::string16& display_text, |
| bool update_popup) OVERRIDE { |
| text_ = display_text; |
| } |
| virtual void SetWindowTextAndCaretPos(const base::string16& text, |
| size_t caret_pos, |
| bool update_popup, |
| bool notify_text_changed) OVERRIDE { |
| text_ = text; |
| } |
| virtual void SetForcedQuery() OVERRIDE {} |
| virtual bool IsSelectAll() const OVERRIDE { return false; } |
| virtual bool DeleteAtEndPressed() OVERRIDE { return false; } |
| virtual void GetSelectionBounds(size_t* start, size_t* end) const OVERRIDE {} |
| virtual void SelectAll(bool reversed) OVERRIDE {} |
| virtual void RevertAll() OVERRIDE {} |
| virtual void UpdatePopup() OVERRIDE {} |
| virtual void SetFocus() OVERRIDE {} |
| virtual void ApplyCaretVisibility() OVERRIDE {} |
| virtual void OnTemporaryTextMaybeChanged( |
| const base::string16& display_text, |
| bool save_original_selection, |
| bool notify_text_changed) OVERRIDE { |
| text_ = display_text; |
| } |
| virtual bool OnInlineAutocompleteTextMaybeChanged( |
| const base::string16& display_text, size_t user_text_length) OVERRIDE { |
| const bool text_changed = text_ != display_text; |
| text_ = display_text; |
| inline_autocomplete_text_ = display_text.substr(user_text_length); |
| return text_changed; |
| } |
| virtual void OnInlineAutocompleteTextCleared() OVERRIDE { |
| inline_autocomplete_text_.clear(); |
| } |
| virtual void OnRevertTemporaryText() OVERRIDE {} |
| virtual void OnBeforePossibleChange() OVERRIDE {} |
| virtual bool OnAfterPossibleChange() OVERRIDE { return false; } |
| virtual gfx::NativeView GetNativeView() const OVERRIDE { return NULL; } |
| virtual gfx::NativeView GetRelativeWindowForPopup() const OVERRIDE { |
| return NULL; |
| } |
| virtual void SetGrayTextAutocompletion( |
| const base::string16& input) OVERRIDE {} |
| virtual base::string16 GetGrayTextAutocompletion() const OVERRIDE { |
| return base::string16(); |
| } |
| virtual int GetTextWidth() const OVERRIDE { return 0; } |
| virtual int GetWidth() const OVERRIDE { return 0; } |
| virtual bool IsImeComposing() const OVERRIDE { return false; } |
| virtual int GetOmniboxTextLength() const OVERRIDE { return 0; } |
| virtual void EmphasizeURLComponents() OVERRIDE { } |
| |
| const base::string16& inline_autocomplete_text() const { |
| return inline_autocomplete_text_; |
| } |
| |
| private: |
| base::string16 text_; |
| base::string16 inline_autocomplete_text_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TestingOmniboxView); |
| }; |
| |
| class TestingOmniboxEditController : public OmniboxEditController { |
| public: |
| explicit TestingOmniboxEditController(ToolbarModel* toolbar_model) |
| : OmniboxEditController(NULL), |
| toolbar_model_(toolbar_model) { |
| } |
| |
| protected: |
| // OmniboxEditController: |
| virtual void Update(const content::WebContents* contents) OVERRIDE {} |
| virtual void OnChanged() OVERRIDE {} |
| virtual void OnSetFocus() OVERRIDE {} |
| virtual void ShowURL() OVERRIDE {} |
| virtual void HideURL() OVERRIDE {} |
| virtual void EndOriginChipAnimations(bool cancel_fade) OVERRIDE {} |
| virtual InstantController* GetInstant() OVERRIDE { return NULL; } |
| virtual WebContents* GetWebContents() OVERRIDE { return NULL; } |
| virtual ToolbarModel* GetToolbarModel() OVERRIDE { return toolbar_model_; } |
| virtual const ToolbarModel* GetToolbarModel() const OVERRIDE { |
| return toolbar_model_; |
| } |
| |
| private: |
| ToolbarModel* toolbar_model_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TestingOmniboxEditController); |
| }; |
| |
| } // namespace |
| |
| class AutocompleteEditTest : public ::testing::Test { |
| public: |
| TestToolbarModel* toolbar_model() { return &toolbar_model_; } |
| |
| private: |
| TestToolbarModel toolbar_model_; |
| }; |
| |
| // Tests various permutations of AutocompleteModel::AdjustTextForCopy. |
| TEST_F(AutocompleteEditTest, AdjustTextForCopy) { |
| struct Data { |
| const char* perm_text; |
| const int sel_start; |
| const bool is_all_selected; |
| const char* input; |
| const char* expected_output; |
| const bool write_url; |
| const char* expected_url; |
| const bool extracted_search_terms; |
| } input[] = { |
| // Test that http:// is inserted if all text is selected. |
| { "a.de/b", 0, true, "a.de/b", "http://a.de/b", true, "http://a.de/b", |
| false }, |
| |
| // Test that http:// is inserted if the host is selected. |
| { "a.de/b", 0, false, "a.de/", "http://a.de/", true, "http://a.de/", |
| false }, |
| |
| // Tests that http:// is inserted if the path is modified. |
| { "a.de/b", 0, false, "a.de/c", "http://a.de/c", true, "http://a.de/c", |
| false }, |
| |
| // Tests that http:// isn't inserted if the host is modified. |
| { "a.de/b", 0, false, "a.com/b", "a.com/b", false, "", false }, |
| |
| // Tests that http:// isn't inserted if the start of the selection is 1. |
| { "a.de/b", 1, false, "a.de/b", "a.de/b", false, "", false }, |
| |
| // Tests that http:// isn't inserted if a portion of the host is selected. |
| { "a.de/", 0, false, "a.d", "a.d", false, "", false }, |
| |
| // Tests that http:// isn't inserted for an https url after the user nukes |
| // https. |
| { "https://a.com/", 0, false, "a.com/", "a.com/", false, "", false }, |
| |
| // Tests that http:// isn't inserted if the user adds to the host. |
| { "a.de/", 0, false, "a.de.com/", "a.de.com/", false, "", false }, |
| |
| // Tests that we don't get double http if the user manually inserts http. |
| { "a.de/", 0, false, "http://a.de/", "http://a.de/", true, "http://a.de/", |
| false }, |
| |
| // Makes sure intranet urls get 'http://' prefixed to them. |
| { "b/foo", 0, true, "b/foo", "http://b/foo", true, "http://b/foo", false }, |
| |
| // Verifies a search term 'foo' doesn't end up with http. |
| { "www.google.com/search?", 0, false, "foo", "foo", false, "", false }, |
| |
| // Makes sure extracted search terms are not modified. |
| { "www.google.com/webhp?", 0, true, "hello world", "hello world", false, |
| "", true }, |
| }; |
| TestingOmniboxEditController controller(toolbar_model()); |
| TestingOmniboxView view(&controller); |
| TestingProfile profile; |
| // NOTE: The TemplateURLService must be created before the |
| // AutocompleteClassifier so that the SearchProvider gets a non-NULL |
| // TemplateURLService at construction time. |
| TemplateURLServiceFactory::GetInstance()->SetTestingFactory( |
| &profile, &TemplateURLServiceFactory::BuildInstanceFor); |
| AutocompleteClassifierFactory::GetInstance()->SetTestingFactory( |
| &profile, &AutocompleteClassifierFactory::BuildInstanceFor); |
| OmniboxEditModel model(&view, &controller, &profile); |
| |
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input); ++i) { |
| toolbar_model()->set_text(ASCIIToUTF16(input[i].perm_text)); |
| model.UpdatePermanentText(); |
| |
| toolbar_model()->set_perform_search_term_replacement( |
| input[i].extracted_search_terms); |
| |
| base::string16 result = ASCIIToUTF16(input[i].input); |
| GURL url; |
| bool write_url; |
| model.AdjustTextForCopy(input[i].sel_start, input[i].is_all_selected, |
| &result, &url, &write_url); |
| EXPECT_EQ(ASCIIToUTF16(input[i].expected_output), result) << "@: " << i; |
| EXPECT_EQ(input[i].write_url, write_url) << " @" << i; |
| if (write_url) |
| EXPECT_EQ(input[i].expected_url, url.spec()) << " @" << i; |
| } |
| } |
| |
| TEST_F(AutocompleteEditTest, InlineAutocompleteText) { |
| TestingOmniboxEditController controller(toolbar_model()); |
| TestingOmniboxView view(&controller); |
| TestingProfile profile; |
| // NOTE: The TemplateURLService must be created before the |
| // AutocompleteClassifier so that the SearchProvider gets a non-NULL |
| // TemplateURLService at construction time. |
| TemplateURLServiceFactory::GetInstance()->SetTestingFactory( |
| &profile, &TemplateURLServiceFactory::BuildInstanceFor); |
| AutocompleteClassifierFactory::GetInstance()->SetTestingFactory( |
| &profile, &AutocompleteClassifierFactory::BuildInstanceFor); |
| OmniboxEditModel model(&view, &controller, &profile); |
| |
| // Test if the model updates the inline autocomplete text in the view. |
| EXPECT_EQ(base::string16(), view.inline_autocomplete_text()); |
| model.SetUserText(UTF8ToUTF16("he")); |
| model.OnPopupDataChanged(UTF8ToUTF16("llo"), NULL, base::string16(), false); |
| EXPECT_EQ(UTF8ToUTF16("hello"), view.GetText()); |
| EXPECT_EQ(UTF8ToUTF16("llo"), view.inline_autocomplete_text()); |
| |
| model.OnAfterPossibleChange(UTF8ToUTF16("he"), UTF8ToUTF16("hel"), 3, 3, |
| false, true, false, true); |
| EXPECT_EQ(base::string16(), view.inline_autocomplete_text()); |
| model.OnPopupDataChanged(UTF8ToUTF16("lo"), NULL, base::string16(), false); |
| EXPECT_EQ(UTF8ToUTF16("hello"), view.GetText()); |
| EXPECT_EQ(UTF8ToUTF16("lo"), view.inline_autocomplete_text()); |
| |
| model.Revert(); |
| EXPECT_EQ(base::string16(), view.GetText()); |
| EXPECT_EQ(base::string16(), view.inline_autocomplete_text()); |
| |
| model.SetUserText(UTF8ToUTF16("he")); |
| model.OnPopupDataChanged(UTF8ToUTF16("llo"), NULL, base::string16(), false); |
| EXPECT_EQ(UTF8ToUTF16("hello"), view.GetText()); |
| EXPECT_EQ(UTF8ToUTF16("llo"), view.inline_autocomplete_text()); |
| |
| model.AcceptTemporaryTextAsUserText(); |
| EXPECT_EQ(UTF8ToUTF16("hello"), view.GetText()); |
| EXPECT_EQ(base::string16(), view.inline_autocomplete_text()); |
| } |