blob: d38a082e598e4469fee521ea4ecd6da1c1dbf6fc [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/renderer/manifest/manifest_parser.h"
#include "base/strings/string_util.h"
#include "content/public/common/manifest.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
uint32_t ExtractColor(int64_t color) {
return reinterpret_cast<uint32_t&>(color);
}
} // anonymous namespace
class ManifestParserTest : public testing::Test {
protected:
ManifestParserTest() {}
~ManifestParserTest() override {}
Manifest ParseManifestWithURLs(const base::StringPiece& data,
const GURL& document_url,
const GURL& manifest_url) {
ManifestParser parser(data, document_url, manifest_url);
parser.Parse();
errors_ = parser.errors();
return parser.manifest();
}
Manifest ParseManifest(const base::StringPiece& data) {
return ParseManifestWithURLs(
data, default_document_url, default_manifest_url);
}
const std::vector<std::string>& errors() const {
return errors_;
}
unsigned int GetErrorCount() const {
return errors_.size();
}
static const GURL default_document_url;
static const GURL default_manifest_url;
private:
std::vector<std::string> errors_;
DISALLOW_COPY_AND_ASSIGN(ManifestParserTest);
};
const GURL ManifestParserTest::default_document_url(
"http://foo.com/index.html");
const GURL ManifestParserTest::default_manifest_url(
"http://foo.com/manifest.json");
TEST_F(ManifestParserTest, CrashTest) {
// Passing temporary variables should not crash.
ManifestParser parser("{\"start_url\": \"/\"}",
GURL("http://example.com"),
GURL("http://example.com"));
parser.Parse();
// .Parse() should have been call without crashing and succeeded.
EXPECT_EQ(0u, parser.errors().size());
EXPECT_FALSE(parser.manifest().IsEmpty());
}
TEST_F(ManifestParserTest, EmptyStringNull) {
Manifest manifest = ParseManifest("");
// This Manifest is not a valid JSON object, it's a parsing error.
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: Line: 1, column: 1, Unexpected token.",
errors()[0]);
// A parsing error is equivalent to an empty manifest.
ASSERT_TRUE(manifest.IsEmpty());
ASSERT_TRUE(manifest.name.is_null());
ASSERT_TRUE(manifest.short_name.is_null());
ASSERT_TRUE(manifest.start_url.is_empty());
ASSERT_EQ(manifest.display, blink::WebDisplayModeUndefined);
ASSERT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault);
ASSERT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
ASSERT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
ASSERT_TRUE(manifest.gcm_sender_id.is_null());
}
TEST_F(ManifestParserTest, ValidNoContentParses) {
Manifest manifest = ParseManifest("{}");
// Empty Manifest is not a parsing error.
EXPECT_EQ(0u, GetErrorCount());
// Check that all the fields are null in that case.
ASSERT_TRUE(manifest.IsEmpty());
ASSERT_TRUE(manifest.name.is_null());
ASSERT_TRUE(manifest.short_name.is_null());
ASSERT_TRUE(manifest.start_url.is_empty());
ASSERT_EQ(manifest.display, blink::WebDisplayModeUndefined);
ASSERT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault);
ASSERT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
ASSERT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
ASSERT_TRUE(manifest.gcm_sender_id.is_null());
}
TEST_F(ManifestParserTest, MultipleErrorsReporting) {
Manifest manifest = ParseManifest("{ \"name\": 42, \"short_name\": 4,"
"\"orientation\": {}, \"display\": \"foo\","
"\"start_url\": null, \"icons\": {}, \"theme_color\": 42,"
"\"background_color\": 42 }");
EXPECT_EQ(8u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'name' ignored,"
" type string expected.",
errors()[0]);
EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
" type string expected.",
errors()[1]);
EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
" type string expected.",
errors()[2]);
EXPECT_EQ("Manifest parsing error: unknown 'display' value ignored.",
errors()[3]);
EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
" type string expected.",
errors()[4]);
EXPECT_EQ("Manifest parsing error: property 'icons' ignored, "
"type array expected.",
errors()[5]);
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
" type string expected.",
errors()[6]);
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored,"
" type string expected.",
errors()[7]);
}
TEST_F(ManifestParserTest, NameParseRules) {
// Smoke test.
{
Manifest manifest = ParseManifest("{ \"name\": \"foo\" }");
ASSERT_TRUE(base::EqualsASCII(manifest.name.string(), "foo"));
ASSERT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Trim whitespaces.
{
Manifest manifest = ParseManifest("{ \"name\": \" foo \" }");
ASSERT_TRUE(base::EqualsASCII(manifest.name.string(), "foo"));
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if name isn't a string.
{
Manifest manifest = ParseManifest("{ \"name\": {} }");
ASSERT_TRUE(manifest.name.is_null());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'name' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if name isn't a string.
{
Manifest manifest = ParseManifest("{ \"name\": 42 }");
ASSERT_TRUE(manifest.name.is_null());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'name' ignored,"
" type string expected.",
errors()[0]);
}
}
TEST_F(ManifestParserTest, ShortNameParseRules) {
// Smoke test.
{
Manifest manifest = ParseManifest("{ \"short_name\": \"foo\" }");
ASSERT_TRUE(base::EqualsASCII(manifest.short_name.string(), "foo"));
ASSERT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Trim whitespaces.
{
Manifest manifest = ParseManifest("{ \"short_name\": \" foo \" }");
ASSERT_TRUE(base::EqualsASCII(manifest.short_name.string(), "foo"));
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if name isn't a string.
{
Manifest manifest = ParseManifest("{ \"short_name\": {} }");
ASSERT_TRUE(manifest.short_name.is_null());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if name isn't a string.
{
Manifest manifest = ParseManifest("{ \"short_name\": 42 }");
ASSERT_TRUE(manifest.short_name.is_null());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
" type string expected.",
errors()[0]);
}
}
TEST_F(ManifestParserTest, StartURLParseRules) {
// Smoke test.
{
Manifest manifest = ParseManifest("{ \"start_url\": \"land.html\" }");
ASSERT_EQ(manifest.start_url.spec(),
default_document_url.Resolve("land.html").spec());
ASSERT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Whitespaces.
{
Manifest manifest = ParseManifest("{ \"start_url\": \" land.html \" }");
ASSERT_EQ(manifest.start_url.spec(),
default_document_url.Resolve("land.html").spec());
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if property isn't a string.
{
Manifest manifest = ParseManifest("{ \"start_url\": {} }");
ASSERT_TRUE(manifest.start_url.is_empty());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if property isn't a string.
{
Manifest manifest = ParseManifest("{ \"start_url\": 42 }");
ASSERT_TRUE(manifest.start_url.is_empty());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
" type string expected.",
errors()[0]);
}
// Absolute start_url, same origin with document.
{
Manifest manifest =
ParseManifestWithURLs("{ \"start_url\": \"http://foo.com/land.html\" }",
GURL("http://foo.com/manifest.json"),
GURL("http://foo.com/index.html"));
ASSERT_EQ(manifest.start_url.spec(), "http://foo.com/land.html");
EXPECT_EQ(0u, GetErrorCount());
}
// Absolute start_url, cross origin with document.
{
Manifest manifest =
ParseManifestWithURLs("{ \"start_url\": \"http://bar.com/land.html\" }",
GURL("http://foo.com/manifest.json"),
GURL("http://foo.com/index.html"));
ASSERT_TRUE(manifest.start_url.is_empty());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'start_url' ignored, should "
"be same origin as document.",
errors()[0]);
}
// Resolving has to happen based on the manifest_url.
{
Manifest manifest =
ParseManifestWithURLs("{ \"start_url\": \"land.html\" }",
GURL("http://foo.com/landing/manifest.json"),
GURL("http://foo.com/index.html"));
ASSERT_EQ(manifest.start_url.spec(), "http://foo.com/landing/land.html");
EXPECT_EQ(0u, GetErrorCount());
}
}
TEST_F(ManifestParserTest, DisplayParserRules) {
// Smoke test.
{
Manifest manifest = ParseManifest("{ \"display\": \"browser\" }");
EXPECT_EQ(manifest.display, blink::WebDisplayModeBrowser);
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Trim whitespaces.
{
Manifest manifest = ParseManifest("{ \"display\": \" browser \" }");
EXPECT_EQ(manifest.display, blink::WebDisplayModeBrowser);
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if name isn't a string.
{
Manifest manifest = ParseManifest("{ \"display\": {} }");
EXPECT_EQ(manifest.display, blink::WebDisplayModeUndefined);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'display' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if name isn't a string.
{
Manifest manifest = ParseManifest("{ \"display\": 42 }");
EXPECT_EQ(manifest.display, blink::WebDisplayModeUndefined);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'display' ignored,"
" type string expected.",
errors()[0]);
}
// Parse fails if string isn't known.
{
Manifest manifest = ParseManifest("{ \"display\": \"browser_something\" }");
EXPECT_EQ(manifest.display, blink::WebDisplayModeUndefined);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: unknown 'display' value ignored.",
errors()[0]);
}
// Accept 'fullscreen'.
{
Manifest manifest = ParseManifest("{ \"display\": \"fullscreen\" }");
EXPECT_EQ(manifest.display, blink::WebDisplayModeFullscreen);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept 'fullscreen'.
{
Manifest manifest = ParseManifest("{ \"display\": \"standalone\" }");
EXPECT_EQ(manifest.display, blink::WebDisplayModeStandalone);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept 'minimal-ui'.
{
Manifest manifest = ParseManifest("{ \"display\": \"minimal-ui\" }");
EXPECT_EQ(manifest.display, blink::WebDisplayModeMinimalUi);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept 'browser'.
{
Manifest manifest = ParseManifest("{ \"display\": \"browser\" }");
EXPECT_EQ(manifest.display, blink::WebDisplayModeBrowser);
EXPECT_EQ(0u, GetErrorCount());
}
// Case insensitive.
{
Manifest manifest = ParseManifest("{ \"display\": \"BROWSER\" }");
EXPECT_EQ(manifest.display, blink::WebDisplayModeBrowser);
EXPECT_EQ(0u, GetErrorCount());
}
}
TEST_F(ManifestParserTest, OrientationParserRules) {
// Smoke test.
{
Manifest manifest = ParseManifest("{ \"orientation\": \"natural\" }");
EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockNatural);
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Trim whitespaces.
{
Manifest manifest = ParseManifest("{ \"orientation\": \"natural\" }");
EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockNatural);
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if name isn't a string.
{
Manifest manifest = ParseManifest("{ \"orientation\": {} }");
EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if name isn't a string.
{
Manifest manifest = ParseManifest("{ \"orientation\": 42 }");
EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
" type string expected.",
errors()[0]);
}
// Parse fails if string isn't known.
{
Manifest manifest = ParseManifest("{ \"orientation\": \"naturalish\" }");
EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: unknown 'orientation' value ignored.",
errors()[0]);
}
// Accept 'any'.
{
Manifest manifest = ParseManifest("{ \"orientation\": \"any\" }");
EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockAny);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept 'natural'.
{
Manifest manifest = ParseManifest("{ \"orientation\": \"natural\" }");
EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockNatural);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept 'landscape'.
{
Manifest manifest = ParseManifest("{ \"orientation\": \"landscape\" }");
EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockLandscape);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept 'landscape-primary'.
{
Manifest manifest =
ParseManifest("{ \"orientation\": \"landscape-primary\" }");
EXPECT_EQ(manifest.orientation,
blink::WebScreenOrientationLockLandscapePrimary);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept 'landscape-secondary'.
{
Manifest manifest =
ParseManifest("{ \"orientation\": \"landscape-secondary\" }");
EXPECT_EQ(manifest.orientation,
blink::WebScreenOrientationLockLandscapeSecondary);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept 'portrait'.
{
Manifest manifest = ParseManifest("{ \"orientation\": \"portrait\" }");
EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockPortrait);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept 'portrait-primary'.
{
Manifest manifest =
ParseManifest("{ \"orientation\": \"portrait-primary\" }");
EXPECT_EQ(manifest.orientation,
blink::WebScreenOrientationLockPortraitPrimary);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept 'portrait-secondary'.
{
Manifest manifest =
ParseManifest("{ \"orientation\": \"portrait-secondary\" }");
EXPECT_EQ(manifest.orientation,
blink::WebScreenOrientationLockPortraitSecondary);
EXPECT_EQ(0u, GetErrorCount());
}
// Case insensitive.
{
Manifest manifest = ParseManifest("{ \"orientation\": \"LANDSCAPE\" }");
EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockLandscape);
EXPECT_EQ(0u, GetErrorCount());
}
}
TEST_F(ManifestParserTest, IconsParseRules) {
// Smoke test: if no icon, empty list.
{
Manifest manifest = ParseManifest("{ \"icons\": [] }");
EXPECT_EQ(manifest.icons.size(), 0u);
EXPECT_TRUE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Smoke test: if empty icon, empty list.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {} ] }");
EXPECT_EQ(manifest.icons.size(), 0u);
EXPECT_TRUE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Smoke test: icon with invalid src, empty list.
{
Manifest manifest = ParseManifest("{ \"icons\": [ { \"icons\": [] } ] }");
EXPECT_EQ(manifest.icons.size(), 0u);
EXPECT_TRUE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Smoke test: if icon with empty src, it will be present in the list.
{
Manifest manifest = ParseManifest("{ \"icons\": [ { \"src\": \"\" } ] }");
EXPECT_EQ(manifest.icons.size(), 1u);
EXPECT_EQ(manifest.icons[0].src.spec(), "http://foo.com/index.html");
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Smoke test: if one icons with valid src, it will be present in the list.
{
Manifest manifest =
ParseManifest("{ \"icons\": [{ \"src\": \"foo.jpg\" }] }");
EXPECT_EQ(manifest.icons.size(), 1u);
EXPECT_EQ(manifest.icons[0].src.spec(), "http://foo.com/foo.jpg");
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
}
TEST_F(ManifestParserTest, IconSrcParseRules) {
// Smoke test.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"foo.png\" } ] }");
EXPECT_EQ(manifest.icons[0].src.spec(),
default_document_url.Resolve("foo.png").spec());
EXPECT_EQ(0u, GetErrorCount());
}
// Whitespaces.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \" foo.png \" } ] }");
EXPECT_EQ(manifest.icons[0].src.spec(),
default_document_url.Resolve("foo.png").spec());
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if property isn't a string.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": {} } ] }");
EXPECT_TRUE(manifest.icons.empty());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'src' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if property isn't a string.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": 42 } ] }");
EXPECT_TRUE(manifest.icons.empty());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'src' ignored,"
" type string expected.",
errors()[0]);
}
// Resolving has to happen based on the document_url.
{
Manifest manifest = ParseManifestWithURLs(
"{ \"icons\": [ {\"src\": \"icons/foo.png\" } ] }",
GURL("http://foo.com/landing/index.html"),
default_manifest_url);
EXPECT_EQ(manifest.icons[0].src.spec(),
"http://foo.com/landing/icons/foo.png");
EXPECT_EQ(0u, GetErrorCount());
}
}
TEST_F(ManifestParserTest, IconTypeParseRules) {
// Smoke test.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": \"foo\" } ] }");
EXPECT_TRUE(base::EqualsASCII(manifest.icons[0].type.string(), "foo"));
EXPECT_EQ(0u, GetErrorCount());
}
// Trim whitespaces.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
" \"type\": \" foo \" } ] }");
EXPECT_TRUE(base::EqualsASCII(manifest.icons[0].type.string(), "foo"));
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if property isn't a string.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": {} } ] }");
EXPECT_TRUE(manifest.icons[0].type.is_null());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'type' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if property isn't a string.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": 42 } ] }");
EXPECT_TRUE(manifest.icons[0].type.is_null());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'type' ignored,"
" type string expected.",
errors()[0]);
}
}
TEST_F(ManifestParserTest, IconDensityParseRules) {
// Smoke test.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 42 } ] }");
EXPECT_EQ(manifest.icons[0].density, 42);
EXPECT_EQ(0u, GetErrorCount());
}
// Decimal value.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 2.5 } ] }");
EXPECT_EQ(manifest.icons[0].density, 2.5);
EXPECT_EQ(0u, GetErrorCount());
}
// Parse fail if it isn't a float.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": {} } ] }");
EXPECT_EQ(manifest.icons[0].density, Manifest::Icon::kDefaultDensity);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
"must be float greater than 0.",
errors()[0]);
}
// Parse fail if it isn't a float.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\":\"2\" } ] }");
EXPECT_EQ(manifest.icons[0].density, Manifest::Icon::kDefaultDensity);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
"must be float greater than 0.",
errors()[0]);
}
// Edge case: 1.0.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 1.00 } ] }");
EXPECT_EQ(manifest.icons[0].density, 1);
EXPECT_EQ(0u, GetErrorCount());
}
// Edge case: values between 0.0 and 1.0 are allowed.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 0.42 } ] }");
EXPECT_EQ(manifest.icons[0].density, 0.42);
EXPECT_EQ(0u, GetErrorCount());
}
// 0 is an invalid value.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 0.0 } ] }");
EXPECT_EQ(manifest.icons[0].density, Manifest::Icon::kDefaultDensity);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
"must be float greater than 0.",
errors()[0]);
}
// Negative values are invalid.
{
Manifest manifest =
ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": -2.5 } ] }");
EXPECT_EQ(manifest.icons[0].density, Manifest::Icon::kDefaultDensity);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
"must be float greater than 0.",
errors()[0]);
}
}
TEST_F(ManifestParserTest, IconSizesParseRules) {
// Smoke test.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \"42x42\" } ] }");
EXPECT_EQ(manifest.icons[0].sizes.size(), 1u);
EXPECT_EQ(0u, GetErrorCount());
}
// Trim whitespaces.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \" 42x42 \" } ] }");
EXPECT_EQ(manifest.icons[0].sizes.size(), 1u);
EXPECT_EQ(0u, GetErrorCount());
}
// Ignore sizes if property isn't a string.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": {} } ] }");
EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'sizes' ignored,"
" type string expected.",
errors()[0]);
}
// Ignore sizes if property isn't a string.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": 42 } ] }");
EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'sizes' ignored,"
" type string expected.",
errors()[0]);
}
// Smoke test: value correctly parsed.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \"42x42 48x48\" } ] }");
EXPECT_EQ(manifest.icons[0].sizes[0], gfx::Size(42, 42));
EXPECT_EQ(manifest.icons[0].sizes[1], gfx::Size(48, 48));
EXPECT_EQ(0u, GetErrorCount());
}
// <WIDTH>'x'<HEIGHT> and <WIDTH>'X'<HEIGHT> are equivalent.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \"42X42 48X48\" } ] }");
EXPECT_EQ(manifest.icons[0].sizes[0], gfx::Size(42, 42));
EXPECT_EQ(manifest.icons[0].sizes[1], gfx::Size(48, 48));
EXPECT_EQ(0u, GetErrorCount());
}
// Twice the same value is parsed twice.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \"42X42 42x42\" } ] }");
EXPECT_EQ(manifest.icons[0].sizes[0], gfx::Size(42, 42));
EXPECT_EQ(manifest.icons[0].sizes[1], gfx::Size(42, 42));
EXPECT_EQ(0u, GetErrorCount());
}
// Width or height can't start with 0.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \"004X007 042x00\" } ] }");
EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: found icon with no valid size.",
errors()[0]);
}
// Width and height MUST contain digits.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \"e4X1.0 55ax1e10\" } ] }");
EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: found icon with no valid size.",
errors()[0]);
}
// 'any' is correctly parsed and transformed to gfx::Size(0,0).
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \"any AnY ANY aNy\" } ] }");
gfx::Size any = gfx::Size(0, 0);
EXPECT_EQ(manifest.icons[0].sizes.size(), 4u);
EXPECT_EQ(manifest.icons[0].sizes[0], any);
EXPECT_EQ(manifest.icons[0].sizes[1], any);
EXPECT_EQ(manifest.icons[0].sizes[2], any);
EXPECT_EQ(manifest.icons[0].sizes[3], any);
EXPECT_EQ(0u, GetErrorCount());
}
// Some invalid width/height combinations.
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \"x 40xx 1x2x3 x42 42xx42\" } ] }");
gfx::Size any = gfx::Size(0, 0);
EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: found icon with no valid size.",
errors()[0]);
}
}
TEST_F(ManifestParserTest, RelatedApplicationsParseRules) {
// If no application, empty list.
{
Manifest manifest = ParseManifest(
"{ \"related_applications\": []}");
EXPECT_EQ(manifest.related_applications.size(), 0u);
EXPECT_TRUE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// If empty application, empty list.
{
Manifest manifest = ParseManifest(
"{ \"related_applications\": [{}]}");
EXPECT_EQ(manifest.related_applications.size(), 0u);
EXPECT_TRUE(manifest.IsEmpty());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
"related application ignored.",
errors()[0]);
}
// If invalid platform, application is ignored.
{
Manifest manifest = ParseManifest(
"{ \"related_applications\": [{\"platform\": 123}]}");
EXPECT_EQ(manifest.related_applications.size(), 0u);
EXPECT_TRUE(manifest.IsEmpty());
EXPECT_EQ(2u, GetErrorCount());
EXPECT_EQ(
"Manifest parsing error: property 'platform' ignored, type string "
"expected.",
errors()[0]);
EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
"related application ignored.",
errors()[1]);
}
// If missing platform, application is ignored.
{
Manifest manifest = ParseManifest(
"{ \"related_applications\": [{\"id\": \"foo\"}]}");
EXPECT_EQ(manifest.related_applications.size(), 0u);
EXPECT_TRUE(manifest.IsEmpty());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
"related application ignored.",
errors()[0]);
}
// If missing id and url, application is ignored.
{
Manifest manifest = ParseManifest(
"{ \"related_applications\": [{\"platform\": \"play\"}]}");
EXPECT_EQ(manifest.related_applications.size(), 0u);
EXPECT_TRUE(manifest.IsEmpty());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: one of 'url' or 'id' is required, "
"related application ignored.",
errors()[0]);
}
// Valid application, with url.
{
Manifest manifest = ParseManifest(
"{ \"related_applications\": ["
"{\"platform\": \"play\", \"url\": \"http://www.foo.com\"}]}");
EXPECT_EQ(manifest.related_applications.size(), 1u);
EXPECT_TRUE(base::EqualsASCII(
manifest.related_applications[0].platform.string(),
"play"));
EXPECT_EQ(manifest.related_applications[0].url.spec(),
"http://www.foo.com/");
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Valid application, with id.
{
Manifest manifest = ParseManifest(
"{ \"related_applications\": ["
"{\"platform\": \"itunes\", \"id\": \"foo\"}]}");
EXPECT_EQ(manifest.related_applications.size(), 1u);
EXPECT_TRUE(base::EqualsASCII(
manifest.related_applications[0].platform.string(),
"itunes"));
EXPECT_TRUE(base::EqualsASCII(manifest.related_applications[0].id.string(),
"foo"));
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// All valid applications are in list.
{
Manifest manifest = ParseManifest(
"{ \"related_applications\": ["
"{\"platform\": \"play\", \"id\": \"foo\"},"
"{\"platform\": \"itunes\", \"id\": \"bar\"}]}");
EXPECT_EQ(manifest.related_applications.size(), 2u);
EXPECT_TRUE(base::EqualsASCII(
manifest.related_applications[0].platform.string(),
"play"));
EXPECT_TRUE(base::EqualsASCII(manifest.related_applications[0].id.string(),
"foo"));
EXPECT_TRUE(base::EqualsASCII(
manifest.related_applications[1].platform.string(),
"itunes"));
EXPECT_TRUE(base::EqualsASCII(manifest.related_applications[1].id.string(),
"bar"));
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Two invalid applications and one valid. Only the valid application should
// be in the list.
{
Manifest manifest = ParseManifest(
"{ \"related_applications\": ["
"{\"platform\": \"itunes\"},"
"{\"platform\": \"play\", \"id\": \"foo\"},"
"{}]}");
EXPECT_EQ(manifest.related_applications.size(), 1u);
EXPECT_TRUE(base::EqualsASCII(
manifest.related_applications[0].platform.string(),
"play"));
EXPECT_TRUE(base::EqualsASCII(manifest.related_applications[0].id.string(),
"foo"));
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(2u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: one of 'url' or 'id' is required, "
"related application ignored.",
errors()[0]);
EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
"related application ignored.",
errors()[1]);
}
}
TEST_F(ManifestParserTest, ParsePreferRelatedApplicationsParseRules) {
// Smoke test.
{
Manifest manifest =
ParseManifest("{ \"prefer_related_applications\": true }");
EXPECT_TRUE(manifest.prefer_related_applications);
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if the property isn't a boolean.
{
Manifest manifest =
ParseManifest("{ \"prefer_related_applications\": {} }");
EXPECT_FALSE(manifest.prefer_related_applications);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ(
"Manifest parsing error: property 'prefer_related_applications' "
"ignored, type boolean expected.",
errors()[0]);
}
{
Manifest manifest = ParseManifest(
"{ \"prefer_related_applications\": \"true\" }");
EXPECT_FALSE(manifest.prefer_related_applications);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ(
"Manifest parsing error: property 'prefer_related_applications' "
"ignored, type boolean expected.",
errors()[0]);
}
{
Manifest manifest = ParseManifest("{ \"prefer_related_applications\": 1 }");
EXPECT_FALSE(manifest.prefer_related_applications);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ(
"Manifest parsing error: property 'prefer_related_applications' "
"ignored, type boolean expected.",
errors()[0]);
}
// "False" should set the boolean false without throwing errors.
{
Manifest manifest =
ParseManifest("{ \"prefer_related_applications\": false }");
EXPECT_FALSE(manifest.prefer_related_applications);
EXPECT_EQ(0u, GetErrorCount());
}
}
TEST_F(ManifestParserTest, ThemeColorParserRules) {
// Smoke test.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"#FF0000\" }");
EXPECT_EQ(ExtractColor(manifest.theme_color), 0xFFFF0000u);
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Trim whitespaces.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \" blue \" }");
EXPECT_EQ(ExtractColor(manifest.theme_color), 0xFF0000FFu);
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if theme_color isn't a string.
{
Manifest manifest = ParseManifest("{ \"theme_color\": {} }");
EXPECT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if theme_color isn't a string.
{
Manifest manifest = ParseManifest("{ \"theme_color\": false }");
EXPECT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if theme_color isn't a string.
{
Manifest manifest = ParseManifest("{ \"theme_color\": null }");
EXPECT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if theme_color isn't a string.
{
Manifest manifest = ParseManifest("{ \"theme_color\": [] }");
EXPECT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if theme_color isn't a string.
{
Manifest manifest = ParseManifest("{ \"theme_color\": 42 }");
EXPECT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
" type string expected.",
errors()[0]);
}
// Parse fails if string is not in a known format.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"foo(bar)\" }");
EXPECT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
" 'foo(bar)' is not a valid color.",
errors()[0]);
}
// Parse fails if string is not in a known format.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"bleu\" }");
EXPECT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored, 'bleu'"
" is not a valid color.",
errors()[0]);
}
// Parse fails if string is not in a known format.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"FF00FF\" }");
EXPECT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored, 'FF00FF'"
" is not a valid color.",
errors()[0]);
}
// Parse fails if multiple values for theme_color are given.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"#ABC #DEF\" }");
EXPECT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored, "
"'#ABC #DEF' is not a valid color.",
errors()[0]);
}
// Parse fails if multiple values for theme_color are given.
{
Manifest manifest = ParseManifest(
"{ \"theme_color\": \"#AABBCC #DDEEFF\" }");
EXPECT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored, "
"'#AABBCC #DDEEFF' is not a valid color.",
errors()[0]);
}
// Accept CSS color keyword format.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"blue\" }");
EXPECT_EQ(ExtractColor(manifest.theme_color), 0xFF0000FFu);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept CSS color keyword format.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"chartreuse\" }");
EXPECT_EQ(ExtractColor(manifest.theme_color), 0xFF7FFF00u);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept CSS RGB format.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"#FFF\" }");
EXPECT_EQ(ExtractColor(manifest.theme_color), 0xFFFFFFFFu);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept CSS RGB format.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"#ABC\" }");
EXPECT_EQ(ExtractColor(manifest.theme_color), 0xFFAABBCCu);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept CSS RRGGBB format.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"#FF0000\" }");
EXPECT_EQ(ExtractColor(manifest.theme_color), 0xFFFF0000u);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept translucent colors.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"rgba(255,0,0,"
"0.4)\" }");
EXPECT_EQ(ExtractColor(manifest.theme_color), 0x66FF0000u);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept transparent colors.
{
Manifest manifest = ParseManifest("{ \"theme_color\": \"rgba(0,0,0,0)\" }");
EXPECT_EQ(ExtractColor(manifest.theme_color), 0x00000000u);
EXPECT_EQ(0u, GetErrorCount());
}
}
TEST_F(ManifestParserTest, BackgroundColorParserRules) {
// Smoke test.
{
Manifest manifest = ParseManifest("{ \"background_color\": \"#FF0000\" }");
EXPECT_EQ(ExtractColor(manifest.background_color), 0xFFFF0000u);
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
// Trim whitespaces.
{
Manifest manifest = ParseManifest(
"{ \"background_color\": \" blue \" }");
EXPECT_EQ(ExtractColor(manifest.background_color), 0xFF0000FFu);
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if background_color isn't a string.
{
Manifest manifest = ParseManifest("{ \"background_color\": {} }");
EXPECT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if background_color isn't a string.
{
Manifest manifest = ParseManifest("{ \"background_color\": false }");
EXPECT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if background_color isn't a string.
{
Manifest manifest = ParseManifest("{ \"background_color\": null }");
EXPECT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if background_color isn't a string.
{
Manifest manifest = ParseManifest("{ \"background_color\": [] }");
EXPECT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored,"
" type string expected.",
errors()[0]);
}
// Don't parse if background_color isn't a string.
{
Manifest manifest = ParseManifest("{ \"background_color\": 42 }");
EXPECT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored,"
" type string expected.",
errors()[0]);
}
// Parse fails if string is not in a known format.
{
Manifest manifest = ParseManifest("{ \"background_color\": \"foo(bar)\" }");
EXPECT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored,"
" 'foo(bar)' is not a valid color.",
errors()[0]);
}
// Parse fails if string is not in a known format.
{
Manifest manifest = ParseManifest("{ \"background_color\": \"bleu\" }");
EXPECT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored,"
" 'bleu' is not a valid color.",
errors()[0]);
}
// Parse fails if string is not in a known format.
{
Manifest manifest = ParseManifest("{ \"background_color\": \"FF00FF\" }");
EXPECT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored,"
" 'FF00FF' is not a valid color.",
errors()[0]);
}
// Parse fails if multiple values for background_color are given.
{
Manifest manifest = ParseManifest(
"{ \"background_color\": \"#ABC #DEF\" }");
EXPECT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored, "
"'#ABC #DEF' is not a valid color.",
errors()[0]);
}
// Parse fails if multiple values for background_color are given.
{
Manifest manifest = ParseManifest(
"{ \"background_color\": \"#AABBCC #DDEEFF\" }");
EXPECT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'background_color' ignored, "
"'#AABBCC #DDEEFF' is not a valid color.",
errors()[0]);
}
// Accept CSS color keyword format.
{
Manifest manifest = ParseManifest("{ \"background_color\": \"blue\" }");
EXPECT_EQ(ExtractColor(manifest.background_color), 0xFF0000FFu);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept CSS color keyword format.
{
Manifest manifest = ParseManifest(
"{ \"background_color\": \"chartreuse\" }");
EXPECT_EQ(ExtractColor(manifest.background_color), 0xFF7FFF00u);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept CSS RGB format.
{
Manifest manifest = ParseManifest("{ \"background_color\": \"#FFF\" }");
EXPECT_EQ(ExtractColor(manifest.background_color), 0xFFFFFFFFu);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept CSS RGB format.
{
Manifest manifest = ParseManifest("{ \"background_color\": \"#ABC\" }");
EXPECT_EQ(ExtractColor(manifest.background_color), 0xFFAABBCCu);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept CSS RRGGBB format.
{
Manifest manifest = ParseManifest("{ \"background_color\": \"#FF0000\" }");
EXPECT_EQ(ExtractColor(manifest.background_color), 0xFFFF0000u);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept translucent colors.
{
Manifest manifest = ParseManifest("{ \"background_color\": \"rgba(255,0,0,"
"0.4)\" }");
EXPECT_EQ(ExtractColor(manifest.background_color), 0x66FF0000u);
EXPECT_EQ(0u, GetErrorCount());
}
// Accept transparent colors.
{
Manifest manifest = ParseManifest("{ \"background_color\": \"rgba(0,0,0,"
"0)\" }");
EXPECT_EQ(ExtractColor(manifest.background_color), 0x00000000u);
EXPECT_EQ(0u, GetErrorCount());
}
}
TEST_F(ManifestParserTest, GCMSenderIDParseRules) {
// Smoke test.
{
Manifest manifest = ParseManifest("{ \"gcm_sender_id\": \"foo\" }");
EXPECT_TRUE(base::EqualsASCII(manifest.gcm_sender_id.string(), "foo"));
EXPECT_EQ(0u, GetErrorCount());
}
// Trim whitespaces.
{
Manifest manifest = ParseManifest("{ \"gcm_sender_id\": \" foo \" }");
EXPECT_TRUE(base::EqualsASCII(manifest.gcm_sender_id.string(), "foo"));
EXPECT_EQ(0u, GetErrorCount());
}
// Don't parse if the property isn't a string.
{
Manifest manifest = ParseManifest("{ \"gcm_sender_id\": {} }");
EXPECT_TRUE(manifest.gcm_sender_id.is_null());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'gcm_sender_id' ignored,"
" type string expected.",
errors()[0]);
}
{
Manifest manifest = ParseManifest("{ \"gcm_sender_id\": 42 }");
EXPECT_TRUE(manifest.gcm_sender_id.is_null());
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("Manifest parsing error: property 'gcm_sender_id' ignored,"
" type string expected.",
errors()[0]);
}
}
} // namespace content