1 // Copyright (c) 2011 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.
4
5 #include "base/utf_string_conversions.h"
6 #include "chrome/browser/autocomplete/autocomplete_edit.h"
7 #include "chrome/browser/autocomplete/autocomplete_edit_view.h"
8 #include "chrome/test/testing_browser_process.h"
9 #include "chrome/test/testing_profile.h"
10 #include "third_party/skia/include/core/SkBitmap.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace {
14
15 class TestingAutocompleteEditView : public AutocompleteEditView {
16 public:
TestingAutocompleteEditView()17 TestingAutocompleteEditView() {}
18
model()19 virtual AutocompleteEditModel* model() { return NULL; }
model() const20 virtual const AutocompleteEditModel* model() const { return NULL; }
SaveStateToTab(TabContents * tab)21 virtual void SaveStateToTab(TabContents* tab) {}
Update(const TabContents * tab_for_state_restoring)22 virtual void Update(const TabContents* tab_for_state_restoring) {}
OpenURL(const GURL & url,WindowOpenDisposition disposition,PageTransition::Type transition,const GURL & alternate_nav_url,size_t selected_line,const string16 & keyword)23 virtual void OpenURL(const GURL& url,
24 WindowOpenDisposition disposition,
25 PageTransition::Type transition,
26 const GURL& alternate_nav_url,
27 size_t selected_line,
28 const string16& keyword) {}
GetText() const29 virtual string16 GetText() const { return string16(); }
IsEditingOrEmpty() const30 virtual bool IsEditingOrEmpty() const { return true; }
GetIcon() const31 virtual int GetIcon() const { return 0; }
SetUserText(const string16 & text)32 virtual void SetUserText(const string16& text) {}
SetUserText(const string16 & text,const string16 & display_text,bool update_popup)33 virtual void SetUserText(const string16& text,
34 const string16& display_text,
35 bool update_popup) {}
SetWindowTextAndCaretPos(const string16 & text,size_t caret_pos)36 virtual void SetWindowTextAndCaretPos(const string16& text,
37 size_t caret_pos) {}
SetForcedQuery()38 virtual void SetForcedQuery() {}
IsSelectAll()39 virtual bool IsSelectAll() { return false; }
DeleteAtEndPressed()40 virtual bool DeleteAtEndPressed() { return false; }
GetSelectionBounds(string16::size_type * start,string16::size_type * end)41 virtual void GetSelectionBounds(string16::size_type* start,
42 string16::size_type* end) {}
SelectAll(bool reversed)43 virtual void SelectAll(bool reversed) {}
RevertAll()44 virtual void RevertAll() {}
UpdatePopup()45 virtual void UpdatePopup() {}
ClosePopup()46 virtual void ClosePopup() {}
SetFocus()47 virtual void SetFocus() {}
OnTemporaryTextMaybeChanged(const string16 & display_text,bool save_original_selection)48 virtual void OnTemporaryTextMaybeChanged(const string16& display_text,
49 bool save_original_selection) {}
OnInlineAutocompleteTextMaybeChanged(const string16 & display_text,size_t user_text_length)50 virtual bool OnInlineAutocompleteTextMaybeChanged(
51 const string16& display_text, size_t user_text_length) {
52 return false;
53 }
OnRevertTemporaryText()54 virtual void OnRevertTemporaryText() {}
OnBeforePossibleChange()55 virtual void OnBeforePossibleChange() {}
OnAfterPossibleChange()56 virtual bool OnAfterPossibleChange() { return false; }
GetNativeView() const57 virtual gfx::NativeView GetNativeView() const { return 0; }
GetCommandUpdater()58 virtual CommandUpdater* GetCommandUpdater() { return NULL; }
SetInstantSuggestion(const string16 & input,bool animate_to_complete)59 virtual void SetInstantSuggestion(const string16& input,
60 bool animate_to_complete) {}
GetInstantSuggestion() const61 virtual string16 GetInstantSuggestion() const { return string16(); }
TextWidth() const62 virtual int TextWidth() const { return 0; }
IsImeComposing() const63 virtual bool IsImeComposing() const { return false; }
64
65 #if defined(TOOLKIT_VIEWS)
AddToView(views::View * parent)66 virtual views::View* AddToView(views::View* parent) { return NULL; }
OnPerformDrop(const views::DropTargetEvent & event)67 virtual int OnPerformDrop(const views::DropTargetEvent& event) { return 0; }
68 #endif
69
70 private:
71 DISALLOW_COPY_AND_ASSIGN(TestingAutocompleteEditView);
72 };
73
74 class TestingAutocompleteEditController : public AutocompleteEditController {
75 public:
TestingAutocompleteEditController()76 TestingAutocompleteEditController() {}
OnAutocompleteAccept(const GURL & url,WindowOpenDisposition disposition,PageTransition::Type transition,const GURL & alternate_nav_url)77 virtual void OnAutocompleteAccept(const GURL& url,
78 WindowOpenDisposition disposition,
79 PageTransition::Type transition,
80 const GURL& alternate_nav_url) OVERRIDE {}
OnChanged()81 virtual void OnChanged() OVERRIDE {}
OnSelectionBoundsChanged()82 virtual void OnSelectionBoundsChanged() OVERRIDE {}
OnInputInProgress(bool in_progress)83 virtual void OnInputInProgress(bool in_progress) OVERRIDE {}
OnKillFocus()84 virtual void OnKillFocus() OVERRIDE {}
OnSetFocus()85 virtual void OnSetFocus() OVERRIDE {}
GetFavicon() const86 virtual SkBitmap GetFavicon() const OVERRIDE { return SkBitmap(); }
GetTitle() const87 virtual string16 GetTitle() const OVERRIDE { return string16(); }
GetInstant()88 virtual InstantController* GetInstant() OVERRIDE { return NULL; }
GetTabContentsWrapper() const89 virtual TabContentsWrapper* GetTabContentsWrapper() const OVERRIDE {
90 return NULL;
91 }
92
93 private:
94 DISALLOW_COPY_AND_ASSIGN(TestingAutocompleteEditController);
95 };
96
97 }
98
99 typedef testing::Test AutocompleteEditTest;
100
101 // Tests various permutations of AutocompleteModel::AdjustTextForCopy.
TEST(AutocompleteEditTest,AdjustTextForCopy)102 TEST(AutocompleteEditTest, AdjustTextForCopy) {
103 struct Data {
104 const char* perm_text;
105 const int sel_start;
106 const bool is_all_selected;
107 const char* input;
108 const char* expected_output;
109 const bool write_url;
110 const char* expected_url;
111 } input[] = {
112 // Test that http:// is inserted if all text is selected.
113 { "a.b/c", 0, true, "a.b/c", "http://a.b/c", true, "http://a.b/c" },
114
115 // Test that http:// is inserted if the host is selected.
116 { "a.b/c", 0, false, "a.b/", "http://a.b/", true, "http://a.b/" },
117
118 // Tests that http:// is inserted if the path is modified.
119 { "a.b/c", 0, false, "a.b/d", "http://a.b/d", true, "http://a.b/d" },
120
121 // Tests that http:// isn't inserted if the host is modified.
122 { "a.b/c", 0, false, "a.c/", "a.c/", false, "" },
123
124 // Tests that http:// isn't inserted if the start of the selection is 1.
125 { "a.b/c", 1, false, "a.b/", "a.b/", false, "" },
126
127 // Tests that http:// isn't inserted if a portion of the host is selected.
128 { "a.com/", 0, false, "a.co", "a.co", false, "" },
129
130 // Tests that http:// isn't inserted for an https url after the user nukes
131 // https.
132 { "https://a.com/", 0, false, "a.com/", "a.com/", false, "" },
133
134 // Tests that http:// isn't inserted if the user adds to the host.
135 { "a.b/", 0, false, "a.bc/", "a.bc/", false, "" },
136
137 // Tests that we don't get double http if the user manually inserts http.
138 { "a.b/", 0, false, "http://a.b/", "http://a.b/", true, "http://a.b/" },
139 };
140 ScopedTestingBrowserProcess browser_process;
141 TestingAutocompleteEditView view;
142 TestingAutocompleteEditController controller;
143 TestingProfile profile;
144 AutocompleteEditModel model(&view, &controller, &profile);
145
146 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input); ++i) {
147 model.UpdatePermanentText(ASCIIToUTF16(input[i].perm_text));
148
149 string16 result = ASCIIToUTF16(input[i].input);
150 GURL url;
151 bool write_url;
152 model.AdjustTextForCopy(input[i].sel_start, input[i].is_all_selected,
153 &result, &url, &write_url);
154 EXPECT_EQ(ASCIIToUTF16(input[i].expected_output), result) << "@: " << i;
155 EXPECT_EQ(input[i].write_url, write_url) << " @" << i;
156 if (write_url)
157 EXPECT_EQ(input[i].expected_url, url.spec()) << " @" << i;
158 }
159 }
160