Commit c5743a11 authored by Jay Harris's avatar Jay Harris Committed by Commit Bot

FileHandler: Updates manifest.file_handler to match the explainer.

Explainer:
https://github.com/WICG/file-handling/blob/master/explainer.md#example

Summary of Changes:
Old way:
{
  "file_handler": {
    "action": "/files",
    "files": {
      "name": "Text",
      "accept": [ "text/plain", ".txt", ".md" ]
    }
  }
}
New way:
{
  "file_handlers": [
    {
      "action": "/files",
      "name": "Text",
      "accept": {
        "text/plain": [ ".txt", ".md" ]
      }
    }
  ]
}

Note: This change is behind the NativeFileSystemAPI and
FileHandlingAPI flags, so this change won't effect any live web APIs.

Bug: 829689
Change-Id: I85ea3abdc22f1b6c89749e051e2ce5dc592357dc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1877497
Commit-Queue: Jay Harris <harrisjay@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarMatt Giuca <mgiuca@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720766}
parent 4b598cd2
......@@ -56,10 +56,10 @@ const char kIconsDirName[] = "icons";
const char kScopeUrlHandlerId[] = "scope";
std::unique_ptr<base::DictionaryValue> CreateFileHandlersForBookmarkApp(
const blink::Manifest::FileHandler& manifest_file_handler) {
const std::vector<blink::Manifest::FileHandler>& manifest_file_handlers) {
base::Value file_handlers(base::Value::Type::DICTIONARY);
for (const auto& handler : manifest_file_handler.files) {
for (const auto& entry : manifest_file_handlers) {
base::Value file_handler(base::Value::Type::DICTIONARY);
file_handler.SetKey(keys::kFileHandlerIncludeDirectories,
base::Value(false));
......@@ -69,15 +69,22 @@ std::unique_ptr<base::DictionaryValue> CreateFileHandlersForBookmarkApp(
base::Value mime_types(base::Value::Type::LIST);
base::Value file_extensions(base::Value::Type::LIST);
for (const auto& acceptsUTF16 : handler.accept) {
std::string acceptsUTF8 = base::UTF16ToUTF8(acceptsUTF16);
if (acceptsUTF8.size() == 0)
for (const auto& it : entry.accept) {
std::string type = base::UTF16ToUTF8(it.first);
if (type.empty())
continue;
if (acceptsUTF8[0] == '.') {
file_extensions.Append(base::Value(acceptsUTF8.substr(1)));
} else {
mime_types.Append(base::Value(acceptsUTF8));
mime_types.Append(base::Value(type));
for (const auto& extensionUTF16 : it.second) {
std::string extension = base::UTF16ToUTF8(extensionUTF16);
if (extension.empty())
continue;
if (extension[0] != '.')
continue;
// Remove the '.' before appending.
file_extensions.Append(base::Value(extension.substr(1)));
}
}
......@@ -85,13 +92,7 @@ std::unique_ptr<base::DictionaryValue> CreateFileHandlersForBookmarkApp(
file_handler.SetKey(keys::kFileHandlerExtensions,
std::move(file_extensions));
// Use '{action}/?name={name}' as the id for the file handler, so we don't
// have to introduce a new field to the extension manifest.
file_handlers.SetKey(
net::AppendQueryParameter(manifest_file_handler.action, "name",
base::UTF16ToUTF8(handler.name))
.spec(),
std::move(file_handler));
file_handlers.SetKey(entry.action.spec(), std::move(file_handler));
}
return base::DictionaryValue::From(
......@@ -215,9 +216,9 @@ scoped_refptr<Extension> ConvertWebAppToExtension(
root->SetString(keys::kAppDisplayMode,
blink::DisplayModeToString(web_app.display_mode));
if (web_app.file_handler) {
if (web_app.file_handlers.size() != 0) {
root->SetDictionary(keys::kFileHandlers, CreateFileHandlersForBookmarkApp(
web_app.file_handler.value()));
web_app.file_handlers));
}
// Add the icons and linked icon information.
......
......@@ -424,24 +424,21 @@ TEST(ExtensionFromWebApp, FileHandlersAreCorrectlyConverted) {
web_app.scope = GURL("https://graphr.n/");
{
blink::Manifest::FileHandler file_handler;
file_handler.action = GURL("https://graphr.n/open-file/");
blink::Manifest::FileFilter graph;
blink::Manifest::FileHandler graph;
graph.action = GURL("https://graphr.n/open-graph/");
graph.name = base::ASCIIToUTF16("Graph");
graph.accept.push_back(base::ASCIIToUTF16("text/svg+xml"));
graph.accept.push_back(base::ASCIIToUTF16(""));
graph.accept.push_back(base::ASCIIToUTF16(".svg"));
file_handler.files.push_back(graph);
blink::Manifest::FileFilter raw;
graph.accept[base::ASCIIToUTF16("text/svg+xml")].push_back(
base::ASCIIToUTF16(""));
graph.accept[base::ASCIIToUTF16("text/svg+xml")].push_back(
base::ASCIIToUTF16(".svg"));
web_app.file_handlers.push_back(graph);
blink::Manifest::FileHandler raw;
raw.action = GURL("https://graphr.n/open-raw/");
raw.name = base::ASCIIToUTF16("Raw");
raw.accept.push_back(base::ASCIIToUTF16(".csv"));
raw.accept.push_back(base::ASCIIToUTF16("text/csv"));
file_handler.files.push_back(raw);
web_app.file_handler =
base::Optional<blink::Manifest::FileHandler>(std::move(file_handler));
raw.accept[base::ASCIIToUTF16("text/csv")].push_back(
base::ASCIIToUTF16(".csv"));
web_app.file_handlers.push_back(raw);
}
scoped_refptr<Extension> extension = ConvertWebAppToExtension(
......@@ -455,7 +452,7 @@ TEST(ExtensionFromWebApp, FileHandlersAreCorrectlyConverted) {
EXPECT_EQ(2u, file_handler_info.size());
EXPECT_EQ("https://graphr.n/open-file/?name=Graph", file_handler_info[0].id);
EXPECT_EQ("https://graphr.n/open-graph/", file_handler_info[0].id);
EXPECT_FALSE(file_handler_info[0].include_directories);
EXPECT_EQ(apps::file_handler_verbs::kOpenWith, file_handler_info[0].verb);
// Extensions should contain SVG, and only SVG
......@@ -465,7 +462,7 @@ TEST(ExtensionFromWebApp, FileHandlersAreCorrectlyConverted) {
EXPECT_THAT(file_handler_info[0].types,
testing::UnorderedElementsAre("text/svg+xml"));
EXPECT_EQ("https://graphr.n/open-file/?name=Raw", file_handler_info[1].id);
EXPECT_EQ("https://graphr.n/open-raw/", file_handler_info[1].id);
EXPECT_FALSE(file_handler_info[1].include_directories);
EXPECT_EQ(apps::file_handler_verbs::kOpenWith, file_handler_info[1].verb);
// Extensions should contain csv, and only csv
......
......@@ -49,17 +49,13 @@ class WebAppFileHandlingBrowserTest
web_app_info->app_url = url;
web_app_info->scope = url.GetWithoutFilename();
web_app_info->title = base::ASCIIToUTF16("A Hosted App");
web_app_info->file_handler = blink::Manifest::FileHandler();
web_app_info->file_handler->action = GetFileHandlerActionURL();
{
std::vector<blink::Manifest::FileFilter> filters;
blink::Manifest::FileFilter text = {
base::ASCIIToUTF16("text"),
{base::ASCIIToUTF16(".txt"), base::ASCIIToUTF16("text/*")}};
filters.push_back(text);
web_app_info->file_handler->files = std::move(filters);
}
blink::Manifest::FileHandler entry;
entry.action = GetFileHandlerActionURL();
entry.name = base::ASCIIToUTF16("text");
entry.accept[base::ASCIIToUTF16("text/*")].push_back(
base::ASCIIToUTF16(".txt"));
web_app_info->file_handlers.push_back(std::move(entry));
return WebAppControllerBrowserTest::InstallWebApp(std::move(web_app_info));
}
......
......@@ -148,8 +148,7 @@ void UpdateWebAppInfoFromManifest(const blink::Manifest& manifest,
if (!web_app_icons.empty())
web_app_info->icons = std::move(web_app_icons);
// Copy across the file handler info.
web_app_info->file_handler = manifest.file_handler;
web_app_info->file_handlers = manifest.file_handlers;
}
std::vector<GURL> GetValidIconUrlsToDownload(
......
......@@ -38,14 +38,12 @@ TEST(WebAppInstallUtils, UpdateWebAppInfoFromManifest) {
base::NullableString16(base::UTF8ToUTF16(kAppShortName), false);
{
blink::Manifest::FileHandler file_handler;
file_handler.action = GURL("http://example.com/open-files");
blink::Manifest::FileFilter file;
file.accept.push_back(base::UTF8ToUTF16(".png"));
file.name = base::UTF8ToUTF16("Images");
file_handler.files.push_back(file);
manifest.file_handler =
base::Optional<blink::Manifest::FileHandler>(std::move(file_handler));
blink::Manifest::FileHandler handler;
handler.action = GURL("http://example.com/open-files");
handler.accept[base::UTF8ToUTF16("image/png")].push_back(
base::UTF8ToUTF16(".png"));
handler.name = base::UTF8ToUTF16("Images");
manifest.file_handlers.push_back(handler);
}
UpdateWebAppInfoFromManifest(manifest, &web_app_info,
......@@ -85,13 +83,13 @@ TEST(WebAppInstallUtils, UpdateWebAppInfoFromManifest) {
EXPECT_EQ(kAppIcon3, web_app_info.icons[1].url);
// Check file handlers were updated
EXPECT_TRUE(web_app_info.file_handler.has_value());
auto file_handler = web_app_info.file_handler.value();
EXPECT_EQ(manifest.file_handler->action, file_handler.action);
EXPECT_EQ(1u, file_handler.files.size());
EXPECT_EQ(base::UTF8ToUTF16("Images"), file_handler.files[0].name);
EXPECT_EQ(1u, file_handler.files[0].accept.size());
EXPECT_EQ(base::UTF8ToUTF16(".png"), file_handler.files[0].accept[0]);
EXPECT_EQ(1u, web_app_info.file_handlers.size());
auto file_handler = web_app_info.file_handlers;
EXPECT_EQ(manifest.file_handlers[0].action, file_handler[0].action);
ASSERT_EQ(file_handler[0].accept.count(base::UTF8ToUTF16("image/png")), 1u);
EXPECT_EQ(file_handler[0].accept[base::UTF8ToUTF16("image/png")][0],
base::UTF8ToUTF16(".png"));
EXPECT_EQ(file_handler[0].name, base::UTF8ToUTF16("Images"));
}
// Tests "scope" is only set for installable sites.
......
......@@ -76,7 +76,7 @@ struct WebApplicationInfo {
bool open_as_window;
// The extensions and mime types the app can handle.
base::Optional<blink::Manifest::FileHandler> file_handler;
std::vector<blink::Manifest::FileHandler> file_handlers;
};
#endif // CHROME_COMMON_WEB_APPLICATION_INFO_H_
......@@ -69,7 +69,7 @@ bool StructTraits<blink::mojom::ManifestDataView, ::blink::Manifest>::Read(
if (!data.ReadShareTarget(&out->share_target))
return false;
if (!data.ReadFileHandler(&out->file_handler))
if (!data.ReadFileHandlers(&out->file_handlers))
return false;
if (!data.ReadRelatedApplications(&out->related_applications))
......@@ -204,7 +204,13 @@ bool StructTraits<blink::mojom::ManifestFileHandlerDataView,
if (!data.ReadAction(&out->action))
return false;
return data.ReadFiles(&out->files);
if (!data.ReadName(&out->name))
return false;
if (!data.ReadAccept(&out->accept))
return false;
return true;
}
} // namespace mojo
......@@ -109,7 +109,8 @@ struct BLINK_COMMON_EXPORT Manifest {
struct BLINK_COMMON_EXPORT FileHandler {
// The URL which will be opened when the file handler is invoked.
GURL action;
std::vector<FileFilter> files;
base::string16 name;
std::map<base::string16, std::vector<base::string16>> accept;
};
// Structure representing a related application.
......@@ -164,11 +165,11 @@ struct BLINK_COMMON_EXPORT Manifest {
// Null if parsing failed or the field was not present.
base::Optional<ShareTarget> share_target;
// Null if parsing failed or the field was not present.
// Empty if parsing failed or the field was not present.
// TODO(harrisjay): This field is non-standard and part of a Chrome
// experiment. See:
// https://github.com/WICG/file-handling/blob/master/explainer.md
base::Optional<FileHandler> file_handler;
std::vector<FileHandler> file_handlers;
// Empty if the parsing failed, the field was not present, empty or all the
// applications inside the array were invalid. The order of the array
......
......@@ -102,9 +102,9 @@ struct BLINK_COMMON_EXPORT
return manifest.share_target;
}
static const base::Optional<::blink::Manifest::FileHandler>& file_handler(
static const std::vector<::blink::Manifest::FileHandler>& file_handlers(
const ::blink::Manifest& manifest) {
return manifest.file_handler;
return manifest.file_handlers;
}
static const std::vector<::blink::Manifest::RelatedApplication>&
......@@ -244,14 +244,20 @@ template <>
struct BLINK_COMMON_EXPORT
StructTraits<blink::mojom::ManifestFileHandlerDataView,
::blink::Manifest::FileHandler> {
static const GURL& action(
const ::blink::Manifest::FileHandler& file_handler) {
return file_handler.action;
static const GURL& action(const ::blink::Manifest::FileHandler& entry) {
return entry.action;
}
static const std::vector<::blink::Manifest::FileFilter>& files(
const ::blink::Manifest::FileHandler& file_handler) {
return file_handler.files;
static const base::string16& name(
const ::blink::Manifest::FileHandler& entry) {
return entry.name;
}
static const std::map<base::string16, std::vector<base::string16>>& accept(
const ::blink::Manifest::FileHandler& entry) {
return entry.accept;
}
static bool Read(blink::mojom::ManifestFileHandlerDataView data,
::blink::Manifest::FileHandler* out);
};
......
......@@ -34,7 +34,7 @@ struct Manifest {
// experiment. See:
// https://github.com/WICG/file-handling/blob/master/explainer.md
// As such, this field should not be exposed to the drive-by web.
ManifestFileHandler? file_handler;
array<ManifestFileHandler> file_handlers;
array<ManifestRelatedApplication> related_applications;
......@@ -152,7 +152,9 @@ struct ManifestShareTarget {
struct ManifestFileHandler {
// The URL that will be opened when the file handler is invoked.
url.mojom.Url action;
array<ManifestFileFilter> files;
mojo_base.mojom.String16? name;
// A mapping of a MIME types to a corresponding list of file extensions.
map<mojo_base.mojom.String16, array<mojo_base.mojom.String16>> accept;
};
// Debug information for a parsed manifest.
......
......@@ -81,9 +81,7 @@ void ManifestParser::Parse() {
if (share_target.has_value())
manifest_->share_target = std::move(*share_target);
auto file_handler = ParseFileHandler(root_object.get());
if (file_handler.has_value())
manifest_->file_handler = std::move(*file_handler);
manifest_->file_handlers = ParseFileHandlers(root_object.get());
manifest_->related_applications = ParseRelatedApplications(root_object.get());
manifest_->prefer_related_applications =
......@@ -627,30 +625,118 @@ ManifestParser::ParseShareTarget(const JSONObject* object) {
return share_target;
}
base::Optional<mojom::blink::ManifestFileHandlerPtr>
ManifestParser::ParseFileHandler(const JSONObject* object) {
const JSONObject* file_handler_object = object->GetJSONObject("file_handler");
if (!file_handler_object)
return base::nullopt;
Vector<mojom::blink::ManifestFileHandlerPtr> ManifestParser::ParseFileHandlers(
const JSONObject* object) {
Vector<mojom::blink::ManifestFileHandlerPtr> result;
if (!object->Get("file_handlers"))
return result;
JSONArray* entry_array = object->GetArray("file_handlers");
if (!entry_array) {
AddErrorInfo("property 'file_handlers' ignored, type array expected.");
return result;
}
for (wtf_size_t i = 0; i < entry_array->size(); ++i) {
JSONObject* json_entry = JSONObject::Cast(entry_array->at(i));
if (!json_entry) {
AddErrorInfo("FileHandler ignored, type object expected.");
continue;
}
base::Optional<mojom::blink::ManifestFileHandlerPtr> entry =
ParseFileHandler(json_entry);
if (!entry)
continue;
result.push_back(std::move(entry.value()));
}
return result;
}
auto file_handler = mojom::blink::ManifestFileHandler::New();
file_handler->action = ParseURL(file_handler_object, "action", manifest_url_,
base::Optional<mojom::blink::ManifestFileHandlerPtr>
ManifestParser::ParseFileHandler(const JSONObject* file_handler) {
mojom::blink::ManifestFileHandlerPtr entry =
mojom::blink::ManifestFileHandler::New();
entry->action = ParseURL(file_handler, "action", manifest_url_,
ParseURLOriginRestrictions::kSameOriginOnly);
if (!file_handler->action.IsValid()) {
AddErrorInfo(
"property 'file_handler' ignored. Property 'action' is "
"invalid.");
if (!entry->action.IsValid()) {
AddErrorInfo("FileHandler ignored. Property 'action' is invalid.");
return base::nullopt;
}
file_handler->files = ParseTargetFiles("files", file_handler_object);
entry->name = ParseString(file_handler, "name", Trim).value_or("");
if (file_handler->files.size() == 0) {
AddErrorInfo("no file handlers were specified.");
entry->accept = ParseFileHandlerAccept(file_handler->GetJSONObject("accept"));
if (entry->accept.IsEmpty()) {
AddErrorInfo("FileHandler ignored. Property 'accept' is invalid.");
return base::nullopt;
}
return file_handler;
return entry;
}
HashMap<String, Vector<String>> ManifestParser::ParseFileHandlerAccept(
const JSONObject* accept) {
HashMap<String, Vector<String>> result;
if (!accept)
return result;
for (wtf_size_t i = 0; i < accept->size(); ++i) {
JSONObject::Entry entry = accept->at(i);
String& mimetype = entry.first;
Vector<String> extensions;
String extension;
JSONArray* extensions_array = JSONArray::Cast(entry.second);
if (extensions_array) {
for (wtf_size_t j = 0; j < extensions_array->size(); ++j) {
JSONValue* value = extensions_array->at(j);
if (!value->AsString(&extension)) {
AddErrorInfo(
"property 'accept' file extension ignored, type string "
"expected.");
continue;
}
if (!ParseFileHandlerAcceptExtension(value, &extension)) {
// Errors are added by ParseFileHandlerAcceptExtension.
continue;
}
extensions.push_back(extension);
}
} else if (ParseFileHandlerAcceptExtension(entry.second, &extension)) {
extensions.push_back(extension);
} else {
// Parsing errors will already have been added.
continue;
}
result.Set(mimetype, std::move(extensions));
}
return result;
}
bool ManifestParser::ParseFileHandlerAcceptExtension(const JSONValue* extension,
String* output) {
if (!extension->AsString(output)) {
AddErrorInfo(
"property 'accept' type ignored. File extensions must be type array or "
"type string.");
return false;
}
if (!output->StartsWith(".")) {
AddErrorInfo(
"property 'accept' file extension ignored, must start with a '.'.");
return false;
}
return true;
}
String ManifestParser::ParseRelatedApplicationPlatform(
......
......@@ -16,6 +16,7 @@
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
......@@ -196,13 +197,34 @@ class MODULES_EXPORT ManifestParser {
base::Optional<mojom::blink::ManifestShareTargetPtr> ParseShareTarget(
const JSONObject* object);
// Parses the 'file_handler' field of a Manifest, as defined in:
// Parses the 'file_handlers' field of a Manifest, as defined in:
// https://github.com/WICG/file-handling/blob/master/explainer.md
// Returns the parsed file handler information. The returned FileHandler is
// null if the field didn't exist, parsing failed, or it was empty.
base::Optional<mojom::blink::ManifestFileHandlerPtr> ParseFileHandler(
// Returns the parsed list of FileHandlers. The returned FileHandlers are
// empty if the field didn't exist, parsing failed, or the input list was
// empty.
Vector<mojom::blink::ManifestFileHandlerPtr> ParseFileHandlers(
const JSONObject* object);
// Parses a FileHandler from an entry in the 'file_handlers' list, as
// defined in: https://github.com/WICG/file-handling/blob/master/explainer.md.
// Returns |base::nullopt| if the FileHandler was invalid, or a
// FileHandler, if parsing succeeded.
base::Optional<mojom::blink::ManifestFileHandlerPtr> ParseFileHandler(
const JSONObject* file_handler_entry);
// Parses the 'accept' field of a FileHandler, as defined in:
// https://github.com/WICG/file-handling/blob/master/explainer.md.
// Returns the parsed accept map. Invalid accept entries are ignored.
HashMap<String, Vector<String>> ParseFileHandlerAccept(
const JSONObject* accept);
// Parses an extension in the 'accept' field of a FileHandler, as defined in:
// https://github.com/WICG/file-handling/blob/master/explainer.md. Returns
// whether the parsing was successful and, if so, populates |output| with the
// parsed extension.
bool ParseFileHandlerAcceptExtension(const JSONValue* extension,
String* ouput);
// Parses the 'platform' field of a related application, as defined in:
// https://w3c.github.io/manifest/#dfn-steps-for-processing-the-platform-member-of-an-application
// Returns the parsed string if any, a null string if the parsing failed.
......
......@@ -45,12 +45,8 @@ TypeConverter<blink::Manifest, blink::mojom::blink::ManifestPtr>::Convert(
input->share_target.To<blink::Manifest::ShareTarget>();
}
if (!input->file_handler.is_null()) {
blink::Manifest::FileHandler file_handler;
file_handler.action = input->file_handler->action;
for (auto& file : input->file_handler->files)
file_handler.files.push_back(file.To<blink::Manifest::FileFilter>());
output.file_handler = std::move(file_handler);
for (auto& entry : input->file_handlers) {
output.file_handlers.push_back(entry.To<blink::Manifest::FileHandler>());
}
for (auto& related_application : input->related_applications) {
......@@ -179,6 +175,25 @@ TypeConverter<blink::Manifest::FileFilter,
return output;
}
blink::Manifest::FileHandler
TypeConverter<blink::Manifest::FileHandler,
blink::mojom::blink::ManifestFileHandlerPtr>::
Convert(const blink::mojom::blink::ManifestFileHandlerPtr& input) {
blink::Manifest::FileHandler output;
if (input.is_null())
return output;
output.name = blink::WebString(input->name).Utf16();
output.action = input->action;
for (const auto& it : input->accept) {
auto& extensions = output.accept[blink::WebString(it.key).Utf16()];
for (const auto& extension : it.value)
extensions.push_back(blink::WebString(extension).Utf16());
}
return output;
}
blink::Manifest::RelatedApplication
TypeConverter<blink::Manifest::RelatedApplication,
blink::mojom::blink::ManifestRelatedApplicationPtr>::
......
......@@ -52,6 +52,13 @@ struct TypeConverter<blink::Manifest::FileFilter,
const blink::mojom::blink::ManifestFileFilterPtr& input);
};
template <>
struct TypeConverter<blink::Manifest::FileHandler,
blink::mojom::blink::ManifestFileHandlerPtr> {
static blink::Manifest::FileHandler Convert(
const blink::mojom::blink::ManifestFileHandlerPtr& input);
};
template <>
struct TypeConverter<blink::Manifest::RelatedApplication,
blink::mojom::blink::ManifestRelatedApplicationPtr> {
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/manifest/manifest_type_converters.h"
#include "base/strings/utf_string_conversions.h"
#include "mojo/public/cpp/bindings/type_converter.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h"
#include "third_party/blink/renderer/modules/manifest/manifest_parser.h"
......@@ -39,31 +40,35 @@ TEST_F(ManifestTypeConvertersTest, NoFileHandlerDoesNotConvert) {
const mojom::blink::ManifestPtr& mojo_manifest = Load(json);
auto manifest = mojo_manifest.To<blink::Manifest>();
EXPECT_FALSE(manifest.file_handler.has_value());
EXPECT_EQ(0u, manifest.file_handlers.size());
}
TEST_F(ManifestTypeConvertersTest, BasicFileHandlerIsCorrectlyConverted) {
const mojom::blink::ManifestPtr& mojo_manifest = Load(
"{"
" \"file_handler\": {"
" \"files\": ["
" \"file_handlers\": ["
" {"
" \"name\": \"name\", "
" \"accept\": \"image/png\""
" \"name\": \"name\","
" \"action\": \"/files\","
" \"accept\": {"
" \"image/png\": ["
" \".png\""
" ]"
" }"
" ], "
" \"action\": \"/files\""
" }"
" ]"
"}");
auto manifest = mojo_manifest.To<blink::Manifest>();
ASSERT_TRUE(manifest.file_handler.has_value());
ASSERT_EQ(manifest.file_handlers.size(), 1u);
EXPECT_EQ(manifest.file_handlers[0].action, "http://example.com/files");
EXPECT_TRUE(base::EqualsASCII(manifest.file_handlers[0].name, "name"));
ASSERT_EQ(manifest.file_handlers[0].accept.size(), 1u);
EXPECT_EQ(manifest.file_handler->action, "http://example.com/files");
ASSERT_EQ(manifest.file_handler->files.size(), 1u);
EXPECT_TRUE(base::EqualsASCII(manifest.file_handler->files[0].name, "name"));
ASSERT_EQ(manifest.file_handler->files[0].accept.size(), 1u);
EXPECT_TRUE(base::EqualsASCII(manifest.file_handler->files[0].accept[0],
"image/png"));
base::string16 mime = base::UTF8ToUTF16("image/png");
ASSERT_EQ(manifest.file_handlers[0].accept.count(mime), 1u);
EXPECT_EQ(manifest.file_handlers[0].accept[mime].size(), 1u);
EXPECT_TRUE(
base::EqualsASCII(manifest.file_handlers[0].accept[mime][0], ".png"));
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment