- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / app_list / search / webstore / webstore_provider_browsertest.cc
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
3 // found in the LICENSE file.
4
5 #include <string>
6
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
15 #include "chrome/browser/ui/app_list/search/webstore/webstore_provider.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/test/base/in_process_browser_test.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "net/test/embedded_test_server/embedded_test_server.h"
20 #include "net/test/embedded_test_server/http_request.h"
21 #include "net/test/embedded_test_server/http_response.h"
22
23 using content::BrowserThread;
24 using net::test_server::BasicHttpResponse;
25 using net::test_server::HttpRequest;
26 using net::test_server::HttpResponse;
27 using net::test_server::EmbeddedTestServer;
28
29 namespace app_list {
30 namespace test {
31 namespace {
32
33 // Mock results.
34 const char kOneResult[] = "{"
35     "\"search_url\": \"http://host/search\","
36     "\"results\":["
37       "{"
38         "\"id\": \"app1_id\","
39         "\"localized_name\": \"app1 name\","
40         "\"icon_url\": \"http://host/icon\""
41       "}"
42     "]}";
43
44 const char kThreeResults[] = "{"
45     "\"search_url\": \"http://host/search\","
46     "\"results\":["
47       "{"
48         "\"id\": \"app1_id\","
49         "\"localized_name\": \"one\","
50         "\"icon_url\": \"http://host/icon\""
51       "},"
52       "{"
53         "\"id\": \"app2_id\","
54         "\"localized_name\": \"two\","
55         "\"icon_url\": \"http://host/icon\""
56       "},"
57       "{"
58         "\"id\": \"app3_id\","
59         "\"localized_name\": \"three\","
60         "\"icon_url\": \"http://host/icon\""
61       "}"
62     "]}";
63
64 }  // namespace
65
66 class WebstoreProviderTest : public InProcessBrowserTest {
67  public:
68   WebstoreProviderTest() {}
69   virtual ~WebstoreProviderTest() {}
70
71   // InProcessBrowserTest overrides:
72   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
73     command_line->AppendSwitchASCII(switches::kForceFieldTrials,
74                                     "LauncherUseWebstoreSearch/Enable/");
75   }
76
77   virtual void SetUpOnMainThread() OVERRIDE {
78     test_server_.reset(new EmbeddedTestServer);
79
80     ASSERT_TRUE(test_server_->InitializeAndWaitUntilReady());
81     test_server_->RegisterRequestHandler(
82         base::Bind(&WebstoreProviderTest::HandleRequest,
83                    base::Unretained(this)));
84     CommandLine::ForCurrentProcess()->AppendSwitchASCII(
85         switches::kAppsGalleryURL, test_server_->base_url().spec());
86
87     webstore_provider_.reset(new WebstoreProvider(
88         ProfileManager::GetDefaultProfile(), NULL));
89     webstore_provider_->set_webstore_search_fetched_callback(
90         base::Bind(&WebstoreProviderTest::OnSearchResultsFetched,
91                    base::Unretained(this)));
92     // TODO(mukai): add test cases for throttling.
93     webstore_provider_->set_use_throttling(false);
94   }
95
96   virtual void CleanUpOnMainThread() OVERRIDE {
97     EXPECT_TRUE(test_server_->ShutdownAndWaitUntilComplete());
98     test_server_.reset();
99   }
100
101   std::string RunQuery(const std::string& query,
102                        const std::string& mock_server_response) {
103     webstore_provider_->Start(UTF8ToUTF16(query));
104
105     if (webstore_provider_->webstore_search_ && !mock_server_response.empty()) {
106       mock_server_response_ = mock_server_response;
107
108       DCHECK(!run_loop_);
109       run_loop_.reset(new base::RunLoop);
110       run_loop_->Run();
111       run_loop_.reset();
112
113       mock_server_response_.clear();
114     }
115
116     webstore_provider_->Stop();
117     return GetResults();
118   }
119
120   std::string GetResults() const {
121     std::string results;
122     for (SearchProvider::Results::const_iterator it =
123              webstore_provider_->results().begin();
124          it != webstore_provider_->results().end();
125          ++it) {
126       if (!results.empty())
127         results += ',';
128       results += UTF16ToUTF8((*it)->title());
129     }
130     return results;
131   }
132
133   WebstoreProvider* webstore_provider() { return webstore_provider_.get(); }
134
135  private:
136   scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) {
137     scoped_ptr<BasicHttpResponse> response(new BasicHttpResponse);
138
139     if (request.relative_url.find("/jsonsearch?") != std::string::npos) {
140       if (mock_server_response_ == "404") {
141         response->set_code(net::HTTP_NOT_FOUND);
142       } else if (mock_server_response_ == "500") {
143         response->set_code(net::HTTP_INTERNAL_SERVER_ERROR);
144       } else {
145         response->set_code(net::HTTP_OK);
146         response->set_content(mock_server_response_);
147       }
148     }
149
150     return response.PassAs<HttpResponse>();
151   }
152
153   void OnSearchResultsFetched() {
154     if (run_loop_)
155       run_loop_->Quit();
156   }
157
158   scoped_ptr<EmbeddedTestServer> test_server_;
159   scoped_ptr<base::RunLoop> run_loop_;
160
161   std::string mock_server_response_;
162
163   scoped_ptr<WebstoreProvider> webstore_provider_;
164
165   DISALLOW_COPY_AND_ASSIGN(WebstoreProviderTest);
166 };
167
168 // Flaky on CrOS and Windows: http://crbug.com/246136.
169 #if defined(OS_WIN) || defined(OS_CHROMEOS)
170 #define MAYBE_Basic DISABLED_Basic
171 #else
172 #define MAYBE_Basic Basic
173 #endif
174 IN_PROC_BROWSER_TEST_F(WebstoreProviderTest, MAYBE_Basic) {
175   struct {
176     const char* query;
177     const char* mock_server_response;
178     const char* expected_results_content;
179   } kTestCases[] = {
180     // "Search in web store" result with query text itself is used for
181     // synchronous placeholder, bad server response etc.
182     {"synchronous", "", "synchronous" },
183     {"404", "404", "404" },
184     {"500", "500", "500" },
185     {"bad json", "invalid json", "bad json" },
186     // Good results.
187     {"1 result", kOneResult, "app1 name" },
188     {"3 result", kThreeResults, "one,two,three" },
189   };
190
191   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
192     EXPECT_EQ(kTestCases[i].expected_results_content,
193               RunQuery(kTestCases[i].query,
194                        kTestCases[i].mock_server_response))
195         << "Case " << i << ": q=" << kTestCases[i].query;
196   }
197 }
198
199 IN_PROC_BROWSER_TEST_F(WebstoreProviderTest, NoSearchForSensitiveData) {
200   // None of the following input strings should be accepted because they may
201   // contain private data.
202   const char* inputs[] = {
203     // file: scheme is bad.
204     "file://filename",
205     "FILE://filename",
206     // URLs with usernames, ports, queries or refs are bad.
207     "http://username:password@hostname/",
208     "http://www.example.com:1000",
209     "http://foo:1000",
210     "http://hostname/?query=q",
211     "http://hostname/path#ref",
212     // A https URL with path is bad.
213     "https://hostname/path",
214   };
215
216   for (size_t i = 0; i < arraysize(inputs); ++i)
217     EXPECT_EQ("", RunQuery(inputs[i], kOneResult));
218 }
219
220 IN_PROC_BROWSER_TEST_F(WebstoreProviderTest, NoSearchForShortQueries) {
221   EXPECT_EQ("", RunQuery("a", kOneResult));
222   EXPECT_EQ("", RunQuery("ab", kOneResult));
223   EXPECT_EQ("app1 name", RunQuery("abc", kOneResult));
224 }
225
226 // Flaky on CrOS and Windows: http://crbug.com/246136.
227 #if defined(OS_WIN) || defined(OS_CHROMEOS)
228 #define MAYBE_SearchCache DISABLED_SearchCache
229 #else
230 #define MAYBE_SearchCache SearchCache
231 #endif
232 IN_PROC_BROWSER_TEST_F(WebstoreProviderTest, MAYBE_SearchCache) {
233   EXPECT_EQ("app1 name", RunQuery("foo", kOneResult));
234
235   // No result is provided but the provider gets the result from the cache.
236   EXPECT_EQ("app1 name", RunQuery("foo", ""));
237 }
238
239 }  // namespace test
240 }  // namespace app_list