OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/browser/android/webapk/webapk_installer.h" | 5 #include "chrome/browser/android/webapk/webapk_installer.h" |
6 | 6 |
7 #include <jni.h> | 7 #include <jni.h> |
8 #include <memory> | 8 #include <memory> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 18 matching lines...) Expand all Loading... | |
29 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
30 #include "third_party/skia/include/core/SkBitmap.h" | 30 #include "third_party/skia/include/core/SkBitmap.h" |
31 #include "url/gurl.h" | 31 #include "url/gurl.h" |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 const base::FilePath::CharType kTestDataDir[] = | 35 const base::FilePath::CharType kTestDataDir[] = |
36 FILE_PATH_LITERAL("chrome/test/data"); | 36 FILE_PATH_LITERAL("chrome/test/data"); |
37 | 37 |
38 // URL of mock WebAPK server. | 38 // URL of mock WebAPK server. |
39 const char* kServerUrl = "/webapkserver"; | 39 const char* kServerUrl = "/webapkserver/"; |
40 | 40 |
41 // Icon URL from Web Manifest. We use a random file in the test data directory. | 41 // Icon URL from Web Manifest. We use a random file in the test data directory. |
42 // Since WebApkInstaller does not try to decode the file as an image it is OK | 42 // Since WebApkInstaller does not try to decode the file as an image it is OK |
43 // that the file is not an image. | 43 // that the file is not an image. |
44 const char* kIconUrl = "/simple.html"; | 44 const char* kIconUrl = "/simple.html"; |
45 | 45 |
46 // The response format type expected from the WebAPK server. | |
47 const char* kWebApkServerUrlResponseType = "?alt=proto"; | |
48 | |
46 // URL of file to download from the WebAPK server. We use a random file in the | 49 // URL of file to download from the WebAPK server. We use a random file in the |
47 // test data directory. | 50 // test data directory. |
48 const char* kDownloadUrl = "/simple.html"; | 51 const char* kDownloadUrl = "/simple.html"; |
49 | 52 |
50 // The package name of the downloaded WebAPK. | 53 // The package name of the downloaded WebAPK. |
51 const char* kDownloadedWebApkPackageName = "party.unicode"; | 54 const char* kDownloadedWebApkPackageName = "party.unicode"; |
52 | 55 |
53 // WebApkInstaller subclass where | 56 // WebApkInstaller subclass where |
54 // WebApkInstaller::StartDownloadedWebApkInstall() is stubbed out. | 57 // WebApkInstaller::StartInstallingDownloadedWebApk() and |
58 // WebApkInstaller::StartUpdateUsingDownloadedWebApk() are stubbed out. | |
55 class TestWebApkInstaller : public WebApkInstaller { | 59 class TestWebApkInstaller : public WebApkInstaller { |
56 public: | 60 public: |
57 TestWebApkInstaller(const ShortcutInfo& shortcut_info, | 61 TestWebApkInstaller(const ShortcutInfo& shortcut_info, |
58 const SkBitmap& shortcut_icon) | 62 const SkBitmap& shortcut_icon) |
59 : WebApkInstaller(shortcut_info, shortcut_icon) {} | 63 : WebApkInstaller(shortcut_info, shortcut_icon) {} |
60 | 64 |
61 bool StartDownloadedWebApkInstall( | 65 bool StartInstallingDownloadedWebApk( |
62 JNIEnv* env, | 66 JNIEnv* env, |
63 const base::android::ScopedJavaLocalRef<jstring>& file_path, | 67 const base::android::ScopedJavaLocalRef<jstring>& file_path, |
64 const base::android::ScopedJavaLocalRef<jstring>& package_name) override { | 68 const base::android::ScopedJavaLocalRef<jstring>& package_name) override { |
69 return true; | |
70 } | |
71 | |
72 bool StartUpdateUsingDownloadedWebApk( | |
73 JNIEnv* env, | |
74 const base::android::ScopedJavaLocalRef<jstring>& file_path, | |
75 const base::android::ScopedJavaLocalRef<jstring>& package_name) override { | |
65 return true; | 76 return true; |
66 } | 77 } |
67 | 78 |
68 private: | 79 private: |
69 DISALLOW_COPY_AND_ASSIGN(TestWebApkInstaller); | 80 DISALLOW_COPY_AND_ASSIGN(TestWebApkInstaller); |
70 }; | 81 }; |
71 | 82 |
72 // Runs the WebApkInstaller installation process and blocks till done. | 83 // Runs the WebApkInstaller installation process/update and blocks till done. |
73 class WebApkInstallerRunner { | 84 class WebApkInstallerRunner { |
74 public: | 85 public: |
75 explicit WebApkInstallerRunner(const GURL& icon_url) | 86 explicit WebApkInstallerRunner(const GURL& icon_url) |
76 : url_request_context_getter_(new net::TestURLRequestContextGetter( | 87 : url_request_context_getter_(new net::TestURLRequestContextGetter( |
77 base::ThreadTaskRunnerHandle::Get())), | 88 base::ThreadTaskRunnerHandle::Get())), |
78 icon_url_(icon_url) {} | 89 icon_url_(icon_url) {} |
79 ~WebApkInstallerRunner() {} | 90 ~WebApkInstallerRunner() {} |
80 | 91 |
81 void Run() { | 92 void RunCreateWebApk() { |
gone
2016/08/18 20:51:02
nit: Should be consistent about Installing vs Crea
Xi Han
2016/08/18 21:06:48
Done.
| |
93 WebApkInstaller* installer = CreateWebApkInstaller(); | |
94 | |
95 installer->InstallAsyncWithURLRequestContextGetter( | |
96 url_request_context_getter_.get(), | |
97 base::Bind(&WebApkInstallerRunner::OnCompleted, | |
98 base::Unretained(this))); | |
99 Run(); | |
100 } | |
101 | |
102 void RunUpdateWebApk() { | |
103 const int webapk_version = 1; | |
104 | |
105 WebApkInstaller* installer = CreateWebApkInstaller(); | |
106 | |
107 installer->UpdateAsyncWithURLRequestContextGetter( | |
108 url_request_context_getter_.get(), | |
109 base::Bind(&WebApkInstallerRunner::OnCompleted, base::Unretained(this)), | |
110 kDownloadedWebApkPackageName, | |
111 webapk_version); | |
112 | |
113 Run(); | |
114 } | |
115 | |
116 WebApkInstaller* CreateWebApkInstaller() { | |
82 ShortcutInfo info(GURL::EmptyGURL()); | 117 ShortcutInfo info(GURL::EmptyGURL()); |
83 info.icon_url = icon_url_; | 118 info.icon_url = icon_url_; |
84 | 119 |
85 // WebApkInstaller owns itself. | 120 // WebApkInstaller owns itself. |
86 WebApkInstaller* installer = new TestWebApkInstaller(info, SkBitmap()); | 121 WebApkInstaller* installer = new TestWebApkInstaller(info, SkBitmap()); |
122 installer->SetTimeoutMs(100); | |
123 return installer; | |
124 } | |
87 | 125 |
88 installer->SetTimeoutMs(100); | 126 void Run() { |
89 | |
90 base::RunLoop run_loop; | 127 base::RunLoop run_loop; |
91 on_completed_callback_ = run_loop.QuitClosure(); | 128 on_completed_callback_ = run_loop.QuitClosure(); |
92 installer->InstallAsyncWithURLRequestContextGetter( | |
93 url_request_context_getter_.get(), | |
94 base::Bind(&WebApkInstallerRunner::OnCompleted, | |
95 base::Unretained(this))); | |
96 run_loop.Run(); | 129 run_loop.Run(); |
97 } | 130 } |
98 | 131 |
99 bool success() { return success_; } | 132 bool success() { return success_; } |
100 | 133 |
101 private: | 134 private: |
102 void OnCompleted(bool success) { | 135 void OnCompleted(bool success) { |
103 success_ = success; | 136 success_ = success; |
104 on_completed_callback_.Run(); | 137 on_completed_callback_.Run(); |
105 } | 138 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 typedef base::Callback<std::unique_ptr<net::test_server::HttpResponse>(void)> | 177 typedef base::Callback<std::unique_ptr<net::test_server::HttpResponse>(void)> |
145 WebApkResponseBuilder; | 178 WebApkResponseBuilder; |
146 | 179 |
147 WebApkInstallerTest() | 180 WebApkInstallerTest() |
148 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {} | 181 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {} |
149 ~WebApkInstallerTest() override {} | 182 ~WebApkInstallerTest() override {} |
150 | 183 |
151 void SetUp() override { | 184 void SetUp() override { |
152 test_server_.AddDefaultHandlers(base::FilePath(kTestDataDir)); | 185 test_server_.AddDefaultHandlers(base::FilePath(kTestDataDir)); |
153 test_server_.RegisterRequestHandler( | 186 test_server_.RegisterRequestHandler( |
154 base::Bind(&WebApkInstallerTest::HandleCreateWebApkRequest, | 187 base::Bind(&WebApkInstallerTest::HandleWebApkRequest, |
155 base::Unretained(this))); | 188 base::Unretained(this))); |
156 ASSERT_TRUE(test_server_.Start()); | 189 ASSERT_TRUE(test_server_.Start()); |
157 | 190 |
158 SetDefaults(); | 191 SetDefaults(); |
159 } | 192 } |
160 | 193 |
161 // Sets the Web Manifest's icon URL. | 194 // Sets the Web Manifest's icon URL. |
162 void SetIconUrl(const GURL& icon_url) { icon_url_ = icon_url; } | 195 void SetIconUrl(const GURL& icon_url) { icon_url_ = icon_url; } |
163 | 196 |
164 // Sets the URL to send the webapk::CreateWebApkRequest to. WebApkInstaller | 197 // Sets the URL to send the webapk::CreateWebApkRequest to. WebApkInstaller |
(...skipping 21 matching lines...) Expand all Loading... | |
186 void SetDefaults() { | 219 void SetDefaults() { |
187 GURL icon_url = test_server_.GetURL(kIconUrl); | 220 GURL icon_url = test_server_.GetURL(kIconUrl); |
188 SetIconUrl(icon_url); | 221 SetIconUrl(icon_url); |
189 GURL server_url = test_server_.GetURL(kServerUrl); | 222 GURL server_url = test_server_.GetURL(kServerUrl); |
190 SetWebApkServerUrl(server_url); | 223 SetWebApkServerUrl(server_url); |
191 GURL download_url = test_server_.GetURL(kDownloadUrl); | 224 GURL download_url = test_server_.GetURL(kDownloadUrl); |
192 SetWebApkResponseBuilder( | 225 SetWebApkResponseBuilder( |
193 base::Bind(&BuildValidWebApkResponse, download_url)); | 226 base::Bind(&BuildValidWebApkResponse, download_url)); |
194 } | 227 } |
195 | 228 |
196 std::unique_ptr<net::test_server::HttpResponse> HandleCreateWebApkRequest( | 229 std::unique_ptr<net::test_server::HttpResponse> HandleWebApkRequest( |
197 const net::test_server::HttpRequest& request) { | 230 const net::test_server::HttpRequest& request) { |
198 return (request.relative_url == kServerUrl) | 231 return (request.relative_url == GetServerUrlForCreateWebApk() || |
232 request.relative_url == GetServerUrlForUpdateWebApk()) | |
199 ? webapk_response_builder_.Run() | 233 ? webapk_response_builder_.Run() |
200 : std::unique_ptr<net::test_server::HttpResponse>(); | 234 : std::unique_ptr<net::test_server::HttpResponse>(); |
201 } | 235 } |
202 | 236 |
237 std::string GetServerUrlForCreateWebApk() const { | |
238 std::string url(kServerUrl); | |
239 return url.append(kWebApkServerUrlResponseType); | |
240 } | |
241 | |
242 std::string GetServerUrlForUpdateWebApk() const { | |
243 std::string url(kServerUrl); | |
244 url.append(kDownloadedWebApkPackageName); | |
245 url.append("/"); | |
246 url.append(kWebApkServerUrlResponseType); | |
247 return url; | |
248 } | |
249 | |
203 content::TestBrowserThreadBundle thread_bundle_; | 250 content::TestBrowserThreadBundle thread_bundle_; |
204 net::EmbeddedTestServer test_server_; | 251 net::EmbeddedTestServer test_server_; |
205 | 252 |
206 // Web Manifest's icon URL. | 253 // Web Manifest's icon URL. |
207 GURL icon_url_; | 254 GURL icon_url_; |
208 | 255 |
209 // Builds response to the WebAPK creation request. | 256 // Builds response to the WebAPK creation request. |
210 WebApkResponseBuilder webapk_response_builder_; | 257 WebApkResponseBuilder webapk_response_builder_; |
211 | 258 |
212 DISALLOW_COPY_AND_ASSIGN(WebApkInstallerTest); | 259 DISALLOW_COPY_AND_ASSIGN(WebApkInstallerTest); |
213 }; | 260 }; |
214 | 261 |
215 // Test installation succeeding. | 262 // Test installation succeeding. |
216 TEST_F(WebApkInstallerTest, Success) { | 263 TEST_F(WebApkInstallerTest, Success) { |
217 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); | 264 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
218 runner->Run(); | 265 runner->RunCreateWebApk(); |
219 EXPECT_TRUE(runner->success()); | 266 EXPECT_TRUE(runner->success()); |
220 } | 267 } |
221 | 268 |
222 // Test that installation fails if fetching the bitmap at the icon URL times | 269 // Test that installation fails if fetching the bitmap at the icon URL times |
223 // out. In a perfect world the fetch would never time out because the bitmap at | 270 // out. In a perfect world the fetch would never time out because the bitmap at |
224 // the icon URL should be in the HTTP cache. | 271 // the icon URL should be in the HTTP cache. |
225 TEST_F(WebApkInstallerTest, IconUrlDownloadTimesOut) { | 272 TEST_F(WebApkInstallerTest, IconUrlDownloadTimesOut) { |
226 GURL icon_url = test_server()->GetURL("/slow?1000"); | 273 GURL icon_url = test_server()->GetURL("/slow?1000"); |
227 SetIconUrl(icon_url); | 274 SetIconUrl(icon_url); |
228 | 275 |
229 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); | 276 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
230 runner->Run(); | 277 runner->RunCreateWebApk(); |
231 EXPECT_FALSE(runner->success()); | 278 EXPECT_FALSE(runner->success()); |
232 } | 279 } |
233 | 280 |
234 // Test that installation fails if the WebAPK creation request times out. | 281 // Test that installation fails if the WebAPK creation request times out. |
235 TEST_F(WebApkInstallerTest, CreateWebApkRequestTimesOut) { | 282 TEST_F(WebApkInstallerTest, CreateWebApkRequestTimesOut) { |
236 GURL server_url = test_server()->GetURL("/slow?1000"); | 283 GURL server_url = test_server()->GetURL("/slow?1000"); |
237 SetWebApkServerUrl(server_url); | 284 SetWebApkServerUrl(server_url); |
238 | 285 |
239 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); | 286 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
240 runner->Run(); | 287 runner->RunCreateWebApk(); |
241 EXPECT_FALSE(runner->success()); | 288 EXPECT_FALSE(runner->success()); |
242 } | 289 } |
243 | 290 |
244 // Test that installation fails if the WebAPK download times out. | 291 // Test that installation fails if the WebAPK download times out. |
245 TEST_F(WebApkInstallerTest, WebApkDownloadTimesOut) { | 292 TEST_F(WebApkInstallerTest, WebApkDownloadTimesOut) { |
246 GURL download_url = test_server()->GetURL("/slow?1000"); | 293 GURL download_url = test_server()->GetURL("/slow?1000"); |
247 SetWebApkResponseBuilder(base::Bind(&BuildValidWebApkResponse, download_url)); | 294 SetWebApkResponseBuilder(base::Bind(&BuildValidWebApkResponse, download_url)); |
248 | 295 |
249 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); | 296 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
250 runner->Run(); | 297 runner->RunCreateWebApk(); |
251 EXPECT_FALSE(runner->success()); | 298 EXPECT_FALSE(runner->success()); |
252 } | 299 } |
253 | 300 |
254 // Test that installation fails if the WebAPK download fails. | 301 // Test that installation fails if the WebAPK download fails. |
255 TEST_F(WebApkInstallerTest, WebApkDownloadFails) { | 302 TEST_F(WebApkInstallerTest, WebApkDownloadFails) { |
256 GURL download_url = test_server()->GetURL("/nocontent"); | 303 GURL download_url = test_server()->GetURL("/nocontent"); |
257 SetWebApkResponseBuilder(base::Bind(&BuildValidWebApkResponse, download_url)); | 304 SetWebApkResponseBuilder(base::Bind(&BuildValidWebApkResponse, download_url)); |
258 | 305 |
259 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); | 306 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
260 runner->Run(); | 307 runner->RunCreateWebApk(); |
261 EXPECT_FALSE(runner->success()); | 308 EXPECT_FALSE(runner->success()); |
262 } | 309 } |
263 | 310 |
264 namespace { | 311 namespace { |
265 | 312 |
266 // Returns an HttpResponse which cannot be parsed as a webapk::WebApkResponse. | 313 // Returns an HttpResponse which cannot be parsed as a webapk::WebApkResponse. |
267 std::unique_ptr<net::test_server::HttpResponse> | 314 std::unique_ptr<net::test_server::HttpResponse> |
268 BuildUnparsableWebApkResponse() { | 315 BuildUnparsableWebApkResponse() { |
269 std::unique_ptr<net::test_server::BasicHttpResponse> response( | 316 std::unique_ptr<net::test_server::BasicHttpResponse> response( |
270 new net::test_server::BasicHttpResponse()); | 317 new net::test_server::BasicHttpResponse()); |
271 response->set_code(net::HTTP_OK); | 318 response->set_code(net::HTTP_OK); |
272 response->set_content("😀"); | 319 response->set_content("😀"); |
273 return std::move(response); | 320 return std::move(response); |
274 } | 321 } |
275 | 322 |
276 } // anonymous namespace | 323 } // anonymous namespace |
277 | 324 |
278 // Test that an HTTP response which cannot be parsed as a webapk::WebApkResponse | 325 // Test that an HTTP response which cannot be parsed as a webapk::WebApkResponse |
279 // is handled properly. | 326 // is handled properly. |
280 TEST_F(WebApkInstallerTest, UnparsableCreateWebApkResponse) { | 327 TEST_F(WebApkInstallerTest, UnparsableCreateWebApkResponse) { |
281 SetWebApkResponseBuilder(base::Bind(&BuildUnparsableWebApkResponse)); | 328 SetWebApkResponseBuilder(base::Bind(&BuildUnparsableWebApkResponse)); |
282 | 329 |
283 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); | 330 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
284 runner->Run(); | 331 runner->RunCreateWebApk(); |
285 EXPECT_FALSE(runner->success()); | 332 EXPECT_FALSE(runner->success()); |
286 } | 333 } |
334 | |
335 // Test update succeeding. | |
336 TEST_F(WebApkInstallerTest, UpdateSuccess) { | |
337 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); | |
338 runner->RunUpdateWebApk(); | |
339 EXPECT_TRUE(runner->success()); | |
340 } | |
OLD | NEW |