Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: chrome/browser/ui/app_list/search/people/people_provider_browsertest.cc

Issue 23874015: Implement people search. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string> 5 #include <string>
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h" 11 #include "base/run_loop.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/profiles/profile_manager.h" 13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/browser/ui/app_list/search/chrome_search_result.h" 14 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
15 #include "chrome/browser/ui/app_list/search/webstore_provider.h" 15 #include "chrome/browser/ui/app_list/search/people/people_provider.h"
16 #include "chrome/common/chrome_switches.h" 16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/test/base/in_process_browser_test.h" 17 #include "chrome/test/base/in_process_browser_test.h"
18 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
19 #include "net/test/embedded_test_server/embedded_test_server.h" 19 #include "net/test/embedded_test_server/embedded_test_server.h"
20 #include "net/test/embedded_test_server/http_request.h" 20 #include "net/test/embedded_test_server/http_request.h"
21 #include "net/test/embedded_test_server/http_response.h" 21 #include "net/test/embedded_test_server/http_response.h"
22 22
23 using content::BrowserThread; 23 using content::BrowserThread;
24 using net::test_server::BasicHttpResponse; 24 using net::test_server::BasicHttpResponse;
25 using net::test_server::HttpRequest; 25 using net::test_server::HttpRequest;
26 using net::test_server::HttpResponse; 26 using net::test_server::HttpResponse;
27 using net::test_server::EmbeddedTestServer; 27 using net::test_server::EmbeddedTestServer;
28 28
29 namespace app_list { 29 namespace app_list {
30 namespace test { 30 namespace test {
31 namespace { 31 namespace {
32 32
33 // Mock results. 33 // Mock results.
34 const char kOneResult[] = "{" 34 const char kOneResult[] = "{"
35 "\"search_url\": \"http://host/search\"," 35 "\"items\":["
36 "\"results\":["
37 "{" 36 "{"
38 "\"id\": \"app1_id\"," 37 "\"person\" : {"
39 "\"localized_name\": \"app1 name\"," 38 "\"id\": \"1\","
40 "\"icon_url\": \"http://host/icon\"" 39 "\"names\" : [{"
40 "\"displayName\": \"first person\""
41 "}],"
42 "\"images\" : [{"
43 "\"url\": \"http://host/icon\""
44 "}],"
45 "\"sortKeys\" : {"
46 "\"interactionRank\": \"0.98\""
47 "}"
48 "}"
41 "}" 49 "}"
42 "]}"; 50 "]}";
43 51
44 const char kThreeResults[] = "{" 52 const char kThreeValidResults[] = "{"
45 "\"search_url\": \"http://host/search\"," 53 "\"items\":["
46 "\"results\":["
47 "{" 54 "{"
48 "\"id\": \"app1_id\"," 55 "\"person\" : {"
49 "\"localized_name\": \"one\"," 56 "\"id\": \"1\","
50 "\"icon_url\": \"http://host/icon\"" 57 "\"names\" : [{"
58 "\"displayName\": \"first person\""
59 "}],"
60 "\"images\" : [{"
61 "\"url\": \"http://host/icon\""
62 "}],"
63 "\"sortKeys\" : {"
64 "\"interactionRank\": \"0.98\""
65 "}"
66 "}"
51 "}," 67 "},"
52 "{" 68 "{"
53 "\"id\": \"app2_id\"," 69 "\"person\" : {"
54 "\"localized_name\": \"two\"," 70 "\"id\": \"2\","
55 "\"icon_url\": \"http://host/icon\"" 71 "\"names\" : [{"
72 "\"displayName\": \"second person\""
73 "}],"
74 "\"images\" : [{"
75 "\"url\": \"http://host/icon\""
76 "}],"
77 "\"sortKeys\" : {"
78 "\"interactionRank\": \"0.84\""
79 "}"
80 "}"
56 "}," 81 "},"
57 "{" 82 "{"
58 "\"id\": \"app3_id\"," 83 "\"person\" : {"
59 "\"localized_name\": \"three\"," 84 "\"id\": \"3\","
60 "\"icon_url\": \"http://host/icon\"" 85 "\"names\" : [{"
86 "\"displayName\": \"third person\""
87 "}],"
88 "\"images\" : [{"
89 "\"url\": \"http://host/icon\""
90 "}],"
91 "\"sortKeys\" : {"
92 "\"interactionRank\": \"0.67\""
93 "}"
94 "}"
95 "},"
96 "{"
97 "\"person\" : {"
98 "\"id\": \"4\","
99 "\"names\" : [{"
100 "\"displayName\": \"fourth person\""
101 "}],"
102 "\"images\" : [{"
103 "\"url\": \"http://host/icon\""
104 "}],"
105 "\"sortKeys\" : {"
106 "\"interactionRank\": \"0.0\""
107 "}"
108 "}"
109 "},"
110 "{"
111 "\"person\" : {"
112 "\"id\": \"5\","
113 "\"names\" : [{"
114 "\"displayName\": \"fifth person\""
115 "}],"
116 // Images field is missing on purpose.
117 "\"sortKeys\" : {"
118 "\"interactionRank\": \"0.98\""
119 "}"
120 "}"
61 "}" 121 "}"
62 "]}"; 122 "]}";
63 123
64 } // namespace 124 } // namespace
65 125
66 class WebstoreProviderTest : public InProcessBrowserTest { 126 class PeopleProviderTest : public InProcessBrowserTest {
67 public: 127 public:
68 WebstoreProviderTest() {} 128 PeopleProviderTest() {}
69 virtual ~WebstoreProviderTest() {} 129 virtual ~PeopleProviderTest() {}
70 130
71 // InProcessBrowserTest overrides: 131 // InProcessBrowserTest overrides:
72 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 132 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
73 command_line->AppendSwitchASCII(switches::kForceFieldTrials, 133 command_line->AppendSwitch(switches::kEnablePeopleSearch);
74 "LauncherUseWebstoreSearch/Enable/");
75 } 134 }
76 135
77 virtual void SetUpOnMainThread() OVERRIDE { 136 virtual void SetUpOnMainThread() OVERRIDE {
78 test_server_.reset(new EmbeddedTestServer( 137 test_server_.reset(new EmbeddedTestServer(
79 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))); 138 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
80 139
81 ASSERT_TRUE(test_server_->InitializeAndWaitUntilReady()); 140 ASSERT_TRUE(test_server_->InitializeAndWaitUntilReady());
82 test_server_->RegisterRequestHandler( 141 test_server_->RegisterRequestHandler(
83 base::Bind(&WebstoreProviderTest::HandleRequest, 142 base::Bind(&PeopleProviderTest::HandleRequest,
84 base::Unretained(this))); 143 base::Unretained(this)));
85 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
86 switches::kAppsGalleryURL, test_server_->base_url().spec());
87 144
88 webstore_provider_.reset(new WebstoreProvider( 145 people_provider_.reset(new PeopleProvider(
89 ProfileManager::GetDefaultProfile(), NULL)); 146 ProfileManager::GetDefaultProfile()));
90 webstore_provider_->set_webstore_search_fetched_callback( 147
91 base::Bind(&WebstoreProviderTest::OnSearchResultsFetched, 148 people_provider_->SetupForTest(
92 base::Unretained(this))); 149 base::Bind(&PeopleProviderTest::OnSearchResultsFetched,
93 // TODO(mukai): add test cases for throttling. 150 base::Unretained(this)),
94 webstore_provider_->set_use_throttling(false); 151 test_server_->base_url());
152 people_provider_->set_use_throttling(false);
95 } 153 }
96 154
97 virtual void CleanUpOnMainThread() OVERRIDE { 155 virtual void CleanUpOnMainThread() OVERRIDE {
98 EXPECT_TRUE(test_server_->ShutdownAndWaitUntilComplete()); 156 EXPECT_TRUE(test_server_->ShutdownAndWaitUntilComplete());
99 test_server_.reset(); 157 test_server_.reset();
100 } 158 }
101 159
102 std::string RunQuery(const std::string& query, 160 std::string RunQuery(const std::string& query,
103 const std::string& mock_server_response) { 161 const std::string& mock_server_response) {
104 webstore_provider_->Start(UTF8ToUTF16(query)); 162 people_provider_->Start(UTF8ToUTF16(query));
105 163
106 if (webstore_provider_->webstore_search_ && !mock_server_response.empty()) { 164 if (people_provider_->people_search_ && !mock_server_response.empty()) {
107 mock_server_response_ = mock_server_response; 165 mock_server_response_ = mock_server_response;
108 166
109 DCHECK(!run_loop_); 167 DCHECK(!run_loop_);
110 run_loop_.reset(new base::RunLoop); 168 run_loop_.reset(new base::RunLoop);
111 run_loop_->Run(); 169 run_loop_->Run();
112 run_loop_.reset(); 170 run_loop_.reset();
113 171
114 mock_server_response_.clear(); 172 mock_server_response_.clear();
115 } 173 }
116 174
117 webstore_provider_->Stop(); 175 people_provider_->Stop();
118 return GetResults(); 176 return GetResults();
119 } 177 }
120 178
121 std::string GetResults() const { 179 std::string GetResults() const {
122 std::string results; 180 std::string results;
123 for (SearchProvider::Results::const_iterator it = 181 for (SearchProvider::Results::const_iterator it =
124 webstore_provider_->results().begin(); 182 people_provider_->results().begin();
125 it != webstore_provider_->results().end(); 183 it != people_provider_->results().end();
126 ++it) { 184 ++it) {
127 if (!results.empty()) 185 if (!results.empty())
128 results += ','; 186 results += ',';
129 results += UTF16ToUTF8((*it)->title()); 187 results += UTF16ToUTF8((*it)->title());
130 } 188 }
131 return results; 189 return results;
132 } 190 }
133 191
134 WebstoreProvider* webstore_provider() { return webstore_provider_.get(); } 192 PeopleProvider* people_provider() { return people_provider_.get(); }
135 193
136 private: 194 private:
137 scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) { 195 scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) {
138 scoped_ptr<BasicHttpResponse> response(new BasicHttpResponse); 196 scoped_ptr<BasicHttpResponse> response(new BasicHttpResponse);
139 197 response->set_code(net::HTTP_OK);
140 if (request.relative_url.find("/jsonsearch?") != std::string::npos) { 198 response->set_content(mock_server_response_);
141 if (mock_server_response_ == "404") {
142 response->set_code(net::HTTP_NOT_FOUND);
143 } else if (mock_server_response_ == "500") {
144 response->set_code(net::HTTP_INTERNAL_SERVER_ERROR);
145 } else {
146 response->set_code(net::HTTP_OK);
147 response->set_content(mock_server_response_);
148 }
149 }
150 199
151 return response.PassAs<HttpResponse>(); 200 return response.PassAs<HttpResponse>();
152 } 201 }
153 202
154 void OnSearchResultsFetched() { 203 void OnSearchResultsFetched() {
155 if (run_loop_) 204 if (run_loop_)
156 run_loop_->Quit(); 205 run_loop_->Quit();
157 } 206 }
158 207
159 scoped_ptr<EmbeddedTestServer> test_server_; 208 scoped_ptr<EmbeddedTestServer> test_server_;
160 scoped_ptr<base::RunLoop> run_loop_; 209 scoped_ptr<base::RunLoop> run_loop_;
161 210
162 std::string mock_server_response_; 211 std::string mock_server_response_;
163 212
164 scoped_ptr<WebstoreProvider> webstore_provider_; 213 scoped_ptr<PeopleProvider> people_provider_;
165 214
166 DISALLOW_COPY_AND_ASSIGN(WebstoreProviderTest); 215 DISALLOW_COPY_AND_ASSIGN(PeopleProviderTest);
167 }; 216 };
168 217
169 // Flaky on Windows: http://crbug.com/246136. 218 IN_PROC_BROWSER_TEST_F(PeopleProviderTest, Basic) {
170 #if defined(OS_WIN)
171 #define MAYBE_Basic DISABLED_Basic
172 #else
173 #define MAYBE_Basic Basic
174 #endif
175 IN_PROC_BROWSER_TEST_F(WebstoreProviderTest, MAYBE_Basic) {
176 struct { 219 struct {
177 const char* query; 220 const char* query;
178 const char* mock_server_response; 221 const char* mock_server_response;
179 const char* expected_results_content; 222 const char* expected_results_content;
180 } kTestCases[] = { 223 } kTestCases[] = {
181 // "Search in web store" result with query text itself is used for 224 {"first", kOneResult, "first person" },
182 // synchronous placeholder, bad server response etc. 225 {"person", kThreeValidResults, "first person,second person,third person" },
183 {"synchronous", "", "synchronous" },
184 {"404", "404", "404" },
185 {"500", "500", "500" },
186 {"bad json", "invalid json", "bad json" },
187 // Good results.
188 {"1 result", kOneResult, "app1 name" },
189 {"3 result", kThreeResults, "one,two,three" },
190 }; 226 };
191 227
192 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { 228 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
193 EXPECT_EQ(kTestCases[i].expected_results_content, 229 EXPECT_EQ(kTestCases[i].expected_results_content,
194 RunQuery(kTestCases[i].query, 230 RunQuery(kTestCases[i].query,
195 kTestCases[i].mock_server_response)) 231 kTestCases[i].mock_server_response))
196 << "Case " << i << ": q=" << kTestCases[i].query; 232 << "Case " << i << ": q=" << kTestCases[i].query;
197 } 233 }
198 } 234 }
199 235
200 IN_PROC_BROWSER_TEST_F(WebstoreProviderTest, NoSearchForSensitiveData) { 236 IN_PROC_BROWSER_TEST_F(PeopleProviderTest, NoSearchForSensitiveData) {
201 // None of the following input strings should be accepted because they may 237 // None of the following input strings should be accepted because they may
202 // contain private data. 238 // contain private data.
203 const char* inputs[] = { 239 const char* inputs[] = {
204 // file: scheme is bad. 240 // file: scheme is bad.
205 "file://filename", 241 "file://filename",
206 "FILE://filename", 242 "FILE://filename",
207 // URLs with usernames, ports, queries or refs are bad. 243 // URLs with usernames, ports, queries or refs are bad.
208 "http://username:password@hostname/", 244 "http://username:password@hostname/",
209 "http://www.example.com:1000", 245 "http://www.example.com:1000",
210 "http://foo:1000", 246 "http://foo:1000",
211 "http://hostname/?query=q", 247 "http://hostname/?query=q",
212 "http://hostname/path#ref", 248 "http://hostname/path#ref",
213 // A https URL with path is bad. 249 // A https URL with path is bad.
214 "https://hostname/path", 250 "https://hostname/path",
215 }; 251 };
216 252
217 for (size_t i = 0; i < arraysize(inputs); ++i) 253 for (size_t i = 0; i < arraysize(inputs); ++i)
218 EXPECT_EQ("", RunQuery(inputs[i], kOneResult)); 254 EXPECT_EQ("", RunQuery(inputs[i], kOneResult));
219 } 255 }
220 256
221 IN_PROC_BROWSER_TEST_F(WebstoreProviderTest, NoSearchForShortQueries) { 257 IN_PROC_BROWSER_TEST_F(PeopleProviderTest, NoSearchForShortQueries) {
222 EXPECT_EQ("", RunQuery("a", kOneResult)); 258 EXPECT_EQ("", RunQuery("f", kOneResult));
223 EXPECT_EQ("", RunQuery("ab", kOneResult)); 259 EXPECT_EQ("", RunQuery("fi", kOneResult));
224 EXPECT_EQ("app1 name", RunQuery("abc", kOneResult)); 260 EXPECT_EQ("first person", RunQuery("fir", kOneResult));
225 }
226
227 IN_PROC_BROWSER_TEST_F(WebstoreProviderTest, SearchCache) {
228 EXPECT_EQ("app1 name", RunQuery("foo", kOneResult));
229
230 // No result is provided but the provider gets the result from the cache.
231 EXPECT_EQ("app1 name", RunQuery("foo", ""));
232 } 261 }
233 262
234 } // namespace test 263 } // namespace test
235 } // namespace app_list 264 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698