blob: 452ab737b9988a2b02f559d6fae6eead87f6718e [file] [log] [blame]
[email protected]bebe1d02012-08-02 20:17:091// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]5ba5dab2010-11-18 02:31:042// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/convert_web_app.h"
6
avia2f4804a2015-12-24 23:11:137#include <stddef.h>
8
Jinho Bangb5216cec2018-01-17 19:43:119#include <memory>
[email protected]5ba5dab2010-11-18 02:31:0410#include <string>
11#include <vector>
12
[email protected]57999812013-02-24 05:40:5213#include "base/files/file_path.h"
thestig18dfb7a52014-08-26 10:44:0414#include "base/files/file_util.h"
[email protected]ea1a3f62012-11-16 20:34:2315#include "base/files/scoped_temp_dir.h"
[email protected]5ba5dab2010-11-18 02:31:0416#include "base/path_service.h"
Avi Drissman5f0fb8c2018-12-25 23:20:4917#include "base/stl_util.h"
[email protected]00e7bef2013-06-10 20:35:1718#include "base/strings/stringprintf.h"
[email protected]112158af2013-06-07 23:46:1819#include "base/strings/utf_string_conversions.h"
[email protected]41a17c52013-06-28 00:27:5320#include "base/time/time.h"
[email protected]5ba5dab2010-11-18 02:31:0421#include "base/version.h"
[email protected]5ba5dab2010-11-18 02:31:0422#include "chrome/common/chrome_paths.h"
[email protected]6b414c232013-06-05 07:53:3423#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
[email protected]93f50462013-05-10 04:40:4024#include "chrome/common/web_application_info.h"
Jay Harrisd3191c02019-08-16 01:23:3925#include "components/services/app_service/public/cpp/file_handler_info.h"
[email protected]e4452d32013-11-15 23:07:4126#include "extensions/common/extension.h"
[email protected]4b7908842014-04-07 23:50:2227#include "extensions/common/extension_icon_set.h"
[email protected]993da5e2013-03-23 21:25:1628#include "extensions/common/extension_resource.h"
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:1529#include "extensions/common/manifest_constants.h"
Jay Harrise8e148052019-04-04 22:24:0330#include "extensions/common/manifest_handlers/file_handler_info.h"
[email protected]0db486f2014-04-09 19:32:2231#include "extensions/common/manifest_handlers/icons_handler.h"
[email protected]5a55f3f2013-10-29 01:08:2932#include "extensions/common/permissions/permission_set.h"
[email protected]076ebeda2014-06-06 21:47:2633#include "extensions/common/permissions/permissions_data.h"
[email protected]885c0e92012-11-13 20:27:4234#include "extensions/common/url_pattern.h"
Jay Harrise8e148052019-04-04 22:24:0335#include "testing/gmock/include/gmock/gmock-matchers.h"
[email protected]5ba5dab2010-11-18 02:31:0436#include "testing/gtest/include/gtest/gtest.h"
[email protected]08397d52011-02-05 01:53:3837#include "ui/gfx/codec/png_codec.h"
[email protected]a6483d22013-07-03 22:11:0038#include "url/gurl.h"
[email protected]5ba5dab2010-11-18 02:31:0439
[email protected]b1912d592012-08-17 22:29:3840namespace extensions {
41
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:1542namespace keys = manifest_keys;
43
[email protected]5ba5dab2010-11-18 02:31:0444namespace {
45
46// Returns an icon info corresponding to a canned icon.
47WebApplicationInfo::IconInfo GetIconInfo(const GURL& url, int size) {
48 WebApplicationInfo::IconInfo result;
49
[email protected]650b2d52013-02-10 03:41:4550 base::FilePath icon_file;
Avi Drissman9098f9002018-05-04 00:11:5251 if (!base::PathService::Get(chrome::DIR_TEST_DATA, &icon_file)) {
[email protected]5ba5dab2010-11-18 02:31:0452 ADD_FAILURE() << "Could not get test data directory.";
53 return result;
54 }
55
56 icon_file = icon_file.AppendASCII("extensions")
57 .AppendASCII("convert_web_app")
[email protected]7d3cbc92013-03-18 22:33:0458 .AppendASCII(base::StringPrintf("%i.png", size));
[email protected]5ba5dab2010-11-18 02:31:0459
60 result.url = url;
61 result.width = size;
62 result.height = size;
63
64 std::string icon_data;
[email protected]82f84b92013-08-30 18:23:5065 if (!base::ReadFileToString(icon_file, &icon_data)) {
[email protected]5ba5dab2010-11-18 02:31:0466 ADD_FAILURE() << "Could not read test icon.";
67 return result;
68 }
69
[email protected]da87eec22013-05-14 09:25:2870 if (!gfx::PNGCodec::Decode(
71 reinterpret_cast<const unsigned char*>(icon_data.c_str()),
72 icon_data.size(), &result.data)) {
73 ADD_FAILURE() << "Could not decode test icon.";
74 return result;
75 }
[email protected]5ba5dab2010-11-18 02:31:0476
77 return result;
78}
79
80base::Time GetTestTime(int year, int month, int day, int hour, int minute,
81 int second, int millisecond) {
82 base::Time::Exploded exploded = {0};
83 exploded.year = year;
84 exploded.month = month;
85 exploded.day_of_month = day;
86 exploded.hour = hour;
87 exploded.minute = minute;
88 exploded.second = second;
89 exploded.millisecond = millisecond;
maksim.sisovb4dbc73d2016-07-07 09:17:2790 base::Time out_time;
91 EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time));
92 return out_time;
[email protected]5ba5dab2010-11-18 02:31:0493}
94
95} // namespace
96
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:1597TEST(ExtensionFromWebApp, GetScopeURLFromBookmarkApp) {
98 base::ScopedTempDir extensions_dir;
99 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
100
101 base::DictionaryValue manifest;
102 manifest.SetString(keys::kName, "Test App");
103 manifest.SetString(keys::kVersion, "0");
104 manifest.SetString(keys::kLaunchWebURL, "http://aaronboodman.com/gearpad/");
105
106 // Create a "url_handlers" dictionary with one URL handler generated from
107 // the scope.
108 // {
109 // "scope": {
110 // "matches": [ "http://aaronboodman.com/gearpad/*" ],
111 // "title": "Test App"
112 // },
113 // }
114 GURL scope_url = GURL("http://aaronboodman.com/gearpad/");
115 manifest.SetDictionary(keys::kUrlHandlers,
116 CreateURLHandlersForBookmarkApp(
117 scope_url, base::ASCIIToUTF16("Test App")));
118
119 std::string error;
120 scoped_refptr<Extension> bookmark_app =
121 Extension::Create(extensions_dir.GetPath(), Manifest::INTERNAL, manifest,
122 Extension::FROM_BOOKMARK, &error);
123 ASSERT_TRUE(bookmark_app.get());
124
125 EXPECT_EQ(scope_url, GetScopeURLFromBookmarkApp(bookmark_app.get()));
126}
127
128TEST(ExtensionFromWebApp, GetScopeURLFromBookmarkApp_NoURLHandlers) {
129 base::ScopedTempDir extensions_dir;
130 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
131
132 base::DictionaryValue manifest;
133 manifest.SetString(keys::kName, "Test App");
134 manifest.SetString(keys::kVersion, "0");
135 manifest.SetString(keys::kLaunchWebURL, "http://aaronboodman.com/gearpad/");
136 manifest.SetDictionary(keys::kUrlHandlers,
Jinho Bangb5216cec2018-01-17 19:43:11137 std::make_unique<base::DictionaryValue>());
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15138
139 std::string error;
140 scoped_refptr<Extension> bookmark_app =
141 Extension::Create(extensions_dir.GetPath(), Manifest::INTERNAL, manifest,
142 Extension::FROM_BOOKMARK, &error);
143 ASSERT_TRUE(bookmark_app.get());
144
145 EXPECT_EQ(GURL(), GetScopeURLFromBookmarkApp(bookmark_app.get()));
146}
147
148TEST(ExtensionFromWebApp, GetScopeURLFromBookmarkApp_WrongURLHandler) {
149 base::ScopedTempDir extensions_dir;
150 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
151
152 base::DictionaryValue manifest;
153 manifest.SetString(keys::kName, "Test App");
154 manifest.SetString(keys::kVersion, "0");
155 manifest.SetString(keys::kLaunchWebURL, "http://aaronboodman.com/gearpad/");
156
157 // Create a "url_handlers" dictionary with one URL handler not generated
158 // from the scope.
159 // {
160 // "test_url_handler": {
161 // "matches": [ "http://*.aaronboodman.com/" ],
162 // "title": "test handler"
163 // }
164 // }
Jinho Bangb5216cec2018-01-17 19:43:11165 auto test_matches = std::make_unique<base::ListValue>();
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15166 test_matches->AppendString("http://*.aaronboodman.com/");
167
Jinho Bangb5216cec2018-01-17 19:43:11168 auto test_handler = std::make_unique<base::DictionaryValue>();
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15169 test_handler->SetList(keys::kMatches, std::move(test_matches));
170 test_handler->SetString(keys::kUrlHandlerTitle, "test handler");
171
Jinho Bangb5216cec2018-01-17 19:43:11172 auto url_handlers = std::make_unique<base::DictionaryValue>();
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15173 url_handlers->SetDictionary("test_url_handler", std::move(test_handler));
174 manifest.SetDictionary(keys::kUrlHandlers, std::move(url_handlers));
175
176 std::string error;
177 scoped_refptr<Extension> bookmark_app =
178 Extension::Create(extensions_dir.GetPath(), Manifest::INTERNAL, manifest,
179 Extension::FROM_BOOKMARK, &error);
180 ASSERT_TRUE(bookmark_app.get());
181
182 EXPECT_EQ(GURL(), GetScopeURLFromBookmarkApp(bookmark_app.get()));
183}
184
185TEST(ExtensionFromWebApp, GetScopeURLFromBookmarkApp_ExtraURLHandler) {
186 base::ScopedTempDir extensions_dir;
187 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
188
189 base::DictionaryValue manifest;
190 manifest.SetString(keys::kName, "Test App");
191 manifest.SetString(keys::kVersion, "0");
192 manifest.SetString(keys::kLaunchWebURL, "http://aaronboodman.com/gearpad/");
193
194 // Create a "url_handlers" dictionary with two URL handlers. One for
195 // the scope and and extra one for testing.
196 // {
197 // "scope": {
198 // "matches": [ "http://aaronboodman.com/gearpad/*" ],
199 // "title": "Test App"
200 // },
201 // "test_url_handler": {
202 // "matches": [ "http://*.aaronboodman.com/" ],
203 // "title": "test handler"
204 // }
205 // }
206 GURL scope_url = GURL("http://aaronboodman.com/gearpad/");
207 std::unique_ptr<base::DictionaryValue> url_handlers =
208 CreateURLHandlersForBookmarkApp(scope_url,
209 base::ASCIIToUTF16("Test App"));
210
Jinho Bangb5216cec2018-01-17 19:43:11211 auto test_matches = std::make_unique<base::ListValue>();
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15212 test_matches->AppendString("http://*.aaronboodman.com/");
213
Jinho Bangb5216cec2018-01-17 19:43:11214 auto test_handler = std::make_unique<base::DictionaryValue>();
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15215 test_handler->SetList(keys::kMatches, std::move(test_matches));
216 test_handler->SetString(keys::kUrlHandlerTitle, "test handler");
217
218 url_handlers->SetDictionary("test_url_handler", std::move(test_handler));
219 manifest.SetDictionary(keys::kUrlHandlers, std::move(url_handlers));
220
221 std::string error;
222 scoped_refptr<Extension> bookmark_app =
223 Extension::Create(extensions_dir.GetPath(), Manifest::INTERNAL, manifest,
224 Extension::FROM_BOOKMARK, &error);
225 ASSERT_TRUE(bookmark_app.get());
226
227 // Check that we can retrieve the scope even if there is an extra
228 // url handler.
229 EXPECT_EQ(scope_url, GetScopeURLFromBookmarkApp(bookmark_app.get()));
230}
231
[email protected]d592b1bd2013-05-06 06:40:47232TEST(ExtensionFromWebApp, GenerateVersion) {
[email protected]5ba5dab2010-11-18 02:31:04233 EXPECT_EQ("2010.1.1.0",
234 ConvertTimeToExtensionVersion(
235 GetTestTime(2010, 1, 1, 0, 0, 0, 0)));
236 EXPECT_EQ("2010.12.31.22111",
237 ConvertTimeToExtensionVersion(
238 GetTestTime(2010, 12, 31, 8, 5, 50, 500)));
239 EXPECT_EQ("2010.10.1.65535",
240 ConvertTimeToExtensionVersion(
241 GetTestTime(2010, 10, 1, 23, 59, 59, 999)));
242}
243
[email protected]d592b1bd2013-05-06 06:40:47244TEST(ExtensionFromWebApp, Basic) {
[email protected]ea1a3f62012-11-16 20:34:23245 base::ScopedTempDir extensions_dir;
[email protected]171ab92d2012-10-19 01:16:34246 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
247
[email protected]5ba5dab2010-11-18 02:31:04248 WebApplicationInfo web_app;
[email protected]04338722013-12-24 23:18:05249 web_app.title = base::ASCIIToUTF16("Gearpad");
250 web_app.description =
251 base::ASCIIToUTF16("The best text editor in the universe!");
[email protected]5ba5dab2010-11-18 02:31:04252 web_app.app_url = GURL("http://aaronboodman.com/gearpad/");
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15253 web_app.scope = GURL("http://aaronboodman.com/gearpad/");
[email protected]5ba5dab2010-11-18 02:31:04254
255 const int sizes[] = {16, 48, 128};
Avi Drissman5f0fb8c2018-12-25 23:20:49256 for (size_t i = 0; i < base::size(sizes); ++i) {
[email protected]7d3cbc92013-03-18 22:33:04257 GURL icon_url(
258 web_app.app_url.Resolve(base::StringPrintf("%i.png", sizes[i])));
[email protected]5ba5dab2010-11-18 02:31:04259 web_app.icons.push_back(GetIconInfo(icon_url, sizes[i]));
260 }
261
[email protected]b1912d592012-08-17 22:29:38262 scoped_refptr<Extension> extension = ConvertWebAppToExtension(
Giovanni Ortuño Urquidi1e567fd2018-08-13 07:04:56263 web_app, GetTestTime(1978, 12, 11, 0, 0, 0, 0), extensions_dir.GetPath(),
264 Extension::NO_FLAGS, Manifest::INTERNAL);
[email protected]5ba5dab2010-11-18 02:31:04265 ASSERT_TRUE(extension.get());
266
[email protected]ea1a3f62012-11-16 20:34:23267 base::ScopedTempDir extension_dir;
[email protected]2d57f5d2011-01-13 14:20:12268 EXPECT_TRUE(extension_dir.Set(extension->path()));
[email protected]5ba5dab2010-11-18 02:31:04269
270 EXPECT_TRUE(extension->is_app());
271 EXPECT_TRUE(extension->is_hosted_app());
Giovanni Ortuño Urquidi1e567fd2018-08-13 07:04:56272 EXPECT_TRUE(extension->from_bookmark());
[email protected]c4f459d2012-09-28 04:40:10273 EXPECT_FALSE(extension->is_legacy_packaged_app());
[email protected]5ba5dab2010-11-18 02:31:04274
Giovanni Ortuño Urquidi1e567fd2018-08-13 07:04:56275 EXPECT_FALSE(extension->was_installed_by_default());
276 EXPECT_FALSE(extension->was_installed_by_oem());
277 EXPECT_FALSE(extension->from_webstore());
278 EXPECT_EQ(Manifest::INTERNAL, extension->location());
279
[email protected]f8bbf6b2014-01-30 07:23:27280 EXPECT_EQ("zVvdNZy3Mp7CFU8JVSyXNlDuHdVLbP7fDO3TGVzj/0w=",
[email protected]5ba5dab2010-11-18 02:31:04281 extension->public_key());
[email protected]f8bbf6b2014-01-30 07:23:27282 EXPECT_EQ("oplhagaaipaimkjlbekcdjkffijdockj", extension->id());
Devlin Cronin03bf2d22017-12-20 08:21:05283 EXPECT_EQ("1978.12.11.0", extension->version().GetString());
[email protected]04338722013-12-24 23:18:05284 EXPECT_EQ(base::UTF16ToUTF8(web_app.title), extension->name());
285 EXPECT_EQ(base::UTF16ToUTF8(web_app.description), extension->description());
[email protected]cadac622013-06-11 16:46:36286 EXPECT_EQ(web_app.app_url, AppLaunchInfo::GetFullLaunchURL(extension.get()));
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15287 EXPECT_EQ(web_app.scope, GetScopeURLFromBookmarkApp(extension.get()));
[email protected]076ebeda2014-06-06 21:47:26288 EXPECT_EQ(0u,
rdevlin.cronind630c302015-09-30 20:19:33289 extension->permissions_data()->active_permissions().apis().size());
[email protected]f8bbf6b2014-01-30 07:23:27290 ASSERT_EQ(0u, extension->web_extent().patterns().size());
[email protected]5ba5dab2010-11-18 02:31:04291
[email protected]dc24976f2013-06-02 21:15:09292 EXPECT_EQ(web_app.icons.size(),
293 IconsInfo::GetIcons(extension.get()).map().size());
[email protected]5ba5dab2010-11-18 02:31:04294 for (size_t i = 0; i < web_app.icons.size(); ++i) {
[email protected]7d3cbc92013-03-18 22:33:04295 EXPECT_EQ(base::StringPrintf("icons/%i.png", web_app.icons[i].width),
[email protected]dc24976f2013-06-02 21:15:09296 IconsInfo::GetIcons(extension.get()).Get(
[email protected]702d8b42013-02-27 20:55:50297 web_app.icons[i].width, ExtensionIconSet::MATCH_EXACTLY));
[email protected]dc24976f2013-06-02 21:15:09298 ExtensionResource resource =
299 IconsInfo::GetIconResource(extension.get(),
300 web_app.icons[i].width,
301 ExtensionIconSet::MATCH_EXACTLY);
[email protected]5ba5dab2010-11-18 02:31:04302 ASSERT_TRUE(!resource.empty());
[email protected]7567484142013-07-11 17:36:07303 EXPECT_TRUE(base::PathExists(resource.GetFilePath()));
[email protected]5ba5dab2010-11-18 02:31:04304 }
305}
306
[email protected]d592b1bd2013-05-06 06:40:47307TEST(ExtensionFromWebApp, Minimal) {
[email protected]ea1a3f62012-11-16 20:34:23308 base::ScopedTempDir extensions_dir;
[email protected]171ab92d2012-10-19 01:16:34309 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
310
[email protected]5ba5dab2010-11-18 02:31:04311 WebApplicationInfo web_app;
[email protected]04338722013-12-24 23:18:05312 web_app.title = base::ASCIIToUTF16("Gearpad");
[email protected]5ba5dab2010-11-18 02:31:04313 web_app.app_url = GURL("http://aaronboodman.com/gearpad/");
314
[email protected]b1912d592012-08-17 22:29:38315 scoped_refptr<Extension> extension = ConvertWebAppToExtension(
Giovanni Ortuño Urquidi1e567fd2018-08-13 07:04:56316 web_app, GetTestTime(1978, 12, 11, 0, 0, 0, 0), extensions_dir.GetPath(),
317 Extension::NO_FLAGS, Manifest::INTERNAL);
[email protected]5ba5dab2010-11-18 02:31:04318 ASSERT_TRUE(extension.get());
319
[email protected]ea1a3f62012-11-16 20:34:23320 base::ScopedTempDir extension_dir;
[email protected]2d57f5d2011-01-13 14:20:12321 EXPECT_TRUE(extension_dir.Set(extension->path()));
[email protected]5ba5dab2010-11-18 02:31:04322
323 EXPECT_TRUE(extension->is_app());
324 EXPECT_TRUE(extension->is_hosted_app());
Giovanni Ortuño Urquidi1e567fd2018-08-13 07:04:56325 EXPECT_TRUE(extension->from_bookmark());
[email protected]c4f459d2012-09-28 04:40:10326 EXPECT_FALSE(extension->is_legacy_packaged_app());
[email protected]5ba5dab2010-11-18 02:31:04327
Giovanni Ortuño Urquidi1e567fd2018-08-13 07:04:56328 EXPECT_FALSE(extension->was_installed_by_default());
329 EXPECT_FALSE(extension->was_installed_by_oem());
330 EXPECT_FALSE(extension->from_webstore());
331 EXPECT_EQ(Manifest::INTERNAL, extension->location());
332
[email protected]f8bbf6b2014-01-30 07:23:27333 EXPECT_EQ("zVvdNZy3Mp7CFU8JVSyXNlDuHdVLbP7fDO3TGVzj/0w=",
[email protected]5ba5dab2010-11-18 02:31:04334 extension->public_key());
[email protected]f8bbf6b2014-01-30 07:23:27335 EXPECT_EQ("oplhagaaipaimkjlbekcdjkffijdockj", extension->id());
Devlin Cronin03bf2d22017-12-20 08:21:05336 EXPECT_EQ("1978.12.11.0", extension->version().GetString());
[email protected]04338722013-12-24 23:18:05337 EXPECT_EQ(base::UTF16ToUTF8(web_app.title), extension->name());
[email protected]5ba5dab2010-11-18 02:31:04338 EXPECT_EQ("", extension->description());
[email protected]cadac622013-06-11 16:46:36339 EXPECT_EQ(web_app.app_url, AppLaunchInfo::GetFullLaunchURL(extension.get()));
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15340 EXPECT_TRUE(GetScopeURLFromBookmarkApp(extension.get()).is_empty());
[email protected]dc24976f2013-06-02 21:15:09341 EXPECT_EQ(0u, IconsInfo::GetIcons(extension.get()).map().size());
[email protected]076ebeda2014-06-06 21:47:26342 EXPECT_EQ(0u,
rdevlin.cronind630c302015-09-30 20:19:33343 extension->permissions_data()->active_permissions().apis().size());
[email protected]f8bbf6b2014-01-30 07:23:27344 ASSERT_EQ(0u, extension->web_extent().patterns().size());
[email protected]5ba5dab2010-11-18 02:31:04345}
[email protected]b1912d592012-08-17 22:29:38346
Giovanni Ortuño Urquidi1e567fd2018-08-13 07:04:56347TEST(ExtensionFromWebApp, ExtraInstallationFlags) {
348 base::ScopedTempDir extensions_dir;
349 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
350
351 WebApplicationInfo web_app;
352 web_app.title = base::ASCIIToUTF16("Gearpad");
353 web_app.app_url = GURL("http://aaronboodman.com/gearpad/");
354
355 scoped_refptr<Extension> extension = ConvertWebAppToExtension(
356 web_app, GetTestTime(1978, 12, 11, 0, 0, 0, 0), extensions_dir.GetPath(),
357 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_OEM,
358 Manifest::INTERNAL);
359 ASSERT_TRUE(extension.get());
360
361 EXPECT_TRUE(extension->is_app());
362 EXPECT_TRUE(extension->is_hosted_app());
363 EXPECT_TRUE(extension->from_bookmark());
364 EXPECT_FALSE(extension->is_legacy_packaged_app());
365
366 EXPECT_TRUE(extension->was_installed_by_oem());
367 EXPECT_TRUE(extension->from_webstore());
368 EXPECT_FALSE(extension->was_installed_by_default());
369 EXPECT_EQ(Manifest::INTERNAL, extension->location());
370}
371
372TEST(ExtensionFromWebApp, ExternalPolicyLocation) {
373 base::ScopedTempDir extensions_dir;
374 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
375
376 WebApplicationInfo web_app;
377 web_app.title = base::ASCIIToUTF16("Gearpad");
378 web_app.app_url = GURL("http://aaronboodman.com/gearpad/");
379
380 scoped_refptr<Extension> extension = ConvertWebAppToExtension(
381 web_app, GetTestTime(1978, 12, 11, 0, 0, 0, 0), extensions_dir.GetPath(),
382 Extension::NO_FLAGS, Manifest::EXTERNAL_POLICY);
383 ASSERT_TRUE(extension.get());
384
385 EXPECT_TRUE(extension->is_app());
386 EXPECT_TRUE(extension->is_hosted_app());
387 EXPECT_TRUE(extension->from_bookmark());
388 EXPECT_FALSE(extension->is_legacy_packaged_app());
389
390 EXPECT_EQ(Manifest::EXTERNAL_POLICY, extension->location());
391}
392
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15393// Tests that a scope not ending in "/" works correctly.
394// The tested behavior is unexpected but is working correctly according
395// to the Web Manifest spec. https://github.com/w3c/manifest/issues/554
396TEST(ExtensionFromWebApp, ScopeDoesNotEndInSlash) {
397 base::ScopedTempDir extensions_dir;
398 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
399
400 WebApplicationInfo web_app;
401 web_app.title = base::ASCIIToUTF16("Gearpad");
402 web_app.description =
403 base::ASCIIToUTF16("The best text editor in the universe!");
404 web_app.app_url = GURL("http://aaronboodman.com/gearpad/");
405 web_app.scope = GURL("http://aaronboodman.com/gear");
406
407 scoped_refptr<Extension> extension = ConvertWebAppToExtension(
Giovanni Ortuño Urquidi1e567fd2018-08-13 07:04:56408 web_app, GetTestTime(1978, 12, 11, 0, 0, 0, 0), extensions_dir.GetPath(),
409 Extension::NO_FLAGS, Manifest::INTERNAL);
Giovanni Ortuño Urquidie7e79d452017-08-03 10:16:15410 ASSERT_TRUE(extension.get());
411 EXPECT_EQ(web_app.scope, GetScopeURLFromBookmarkApp(extension.get()));
412}
413
Jay Harrise8e148052019-04-04 22:24:03414// Tests that |file_handler| on the WebAppManifest is correctly converted
415// to |file_handlers| on an extension manifest.
416TEST(ExtensionFromWebApp, FileHandlersAreCorrectlyConverted) {
417 base::ScopedTempDir extensions_dir;
418 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
419
420 WebApplicationInfo web_app;
421 web_app.title = base::ASCIIToUTF16("Graphr");
422 web_app.description = base::ASCIIToUTF16("A magical graphy thing");
Jay Harris35d28222019-05-02 04:50:50423 web_app.app_url = GURL("https://graphr.n/");
424 web_app.scope = GURL("https://graphr.n/");
Jay Harrise8e148052019-04-04 22:24:03425
426 {
427 blink::Manifest::FileHandler file_handler;
Jay Harris35d28222019-05-02 04:50:50428 file_handler.action = GURL("https://graphr.n/open-file/");
Jay Harrise8e148052019-04-04 22:24:03429
430 blink::Manifest::FileFilter graph;
431 graph.name = base::ASCIIToUTF16("Graph");
432 graph.accept.push_back(base::ASCIIToUTF16("text/svg+xml"));
433 graph.accept.push_back(base::ASCIIToUTF16(""));
434 graph.accept.push_back(base::ASCIIToUTF16(".svg"));
Jay Harris35d28222019-05-02 04:50:50435 file_handler.files.push_back(graph);
Jay Harrise8e148052019-04-04 22:24:03436
437 blink::Manifest::FileFilter raw;
438 raw.name = base::ASCIIToUTF16("Raw");
439 raw.accept.push_back(base::ASCIIToUTF16(".csv"));
440 raw.accept.push_back(base::ASCIIToUTF16("text/csv"));
Jay Harris35d28222019-05-02 04:50:50441 file_handler.files.push_back(raw);
Jay Harrise8e148052019-04-04 22:24:03442
443 web_app.file_handler =
444 base::Optional<blink::Manifest::FileHandler>(std::move(file_handler));
445 }
446
447 scoped_refptr<Extension> extension = ConvertWebAppToExtension(
448 web_app, GetTestTime(1978, 12, 11, 0, 0, 0, 0), extensions_dir.GetPath(),
449 Extension::NO_FLAGS, Manifest::INTERNAL);
450
451 ASSERT_TRUE(extension.get());
452
Jay Harrisd3191c02019-08-16 01:23:39453 const std::vector<apps::FileHandlerInfo> file_handler_info =
Jay Harrise8e148052019-04-04 22:24:03454 *extensions::FileHandlers::GetFileHandlers(extension.get());
455
456 EXPECT_EQ(2u, file_handler_info.size());
457
Jay Harris35d28222019-05-02 04:50:50458 EXPECT_EQ("https://graphr.n/open-file/?name=Graph", file_handler_info[0].id);
Jay Harrise8e148052019-04-04 22:24:03459 EXPECT_FALSE(file_handler_info[0].include_directories);
Jay Harrisd3191c02019-08-16 01:23:39460 EXPECT_EQ(apps::file_handler_verbs::kOpenWith, file_handler_info[0].verb);
Jay Harrise8e148052019-04-04 22:24:03461 // Extensions should contain SVG, and only SVG
462 EXPECT_THAT(file_handler_info[0].extensions,
463 testing::UnorderedElementsAre("svg"));
464 // Mime types should contain text/svg+xml and only text/svg+xml
465 EXPECT_THAT(file_handler_info[0].types,
466 testing::UnorderedElementsAre("text/svg+xml"));
467
Jay Harris35d28222019-05-02 04:50:50468 EXPECT_EQ("https://graphr.n/open-file/?name=Raw", file_handler_info[1].id);
Jay Harrise8e148052019-04-04 22:24:03469 EXPECT_FALSE(file_handler_info[1].include_directories);
Jay Harrisd3191c02019-08-16 01:23:39470 EXPECT_EQ(apps::file_handler_verbs::kOpenWith, file_handler_info[1].verb);
Jay Harrise8e148052019-04-04 22:24:03471 // Extensions should contain csv, and only csv
472 EXPECT_THAT(file_handler_info[1].extensions,
473 testing::UnorderedElementsAre("csv"));
474 // Mime types should contain text/csv and only text/csv
475 EXPECT_THAT(file_handler_info[1].types,
476 testing::UnorderedElementsAre("text/csv"));
477}
478
[email protected]b1912d592012-08-17 22:29:38479} // namespace extensions