1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/manifest/manifest_parser.h"
7 #include "base/strings/string_util.h"
8 #include "content/public/common/manifest.h"
9 #include "testing/gtest/include/gtest/gtest.h"
13 class ManifestParserTest
: public testing::Test
{
15 ManifestParserTest() {}
16 ~ManifestParserTest() override
{}
18 Manifest
ParseManifestWithURLs(const base::StringPiece
& data
,
19 const GURL
& document_url
,
20 const GURL
& manifest_url
) {
21 ManifestParser
parser(data
, document_url
, manifest_url
);
23 errors_
= parser
.errors();
24 return parser
.manifest();
27 Manifest
ParseManifest(const base::StringPiece
& data
) {
28 return ParseManifestWithURLs(
29 data
, default_document_url
, default_manifest_url
);
32 const std::vector
<std::string
>& errors() const {
36 unsigned int GetErrorCount() const {
37 return errors_
.size();
40 static const GURL default_document_url
;
41 static const GURL default_manifest_url
;
44 std::vector
<std::string
> errors_
;
46 DISALLOW_COPY_AND_ASSIGN(ManifestParserTest
);
49 const GURL
ManifestParserTest::default_document_url(
50 "http://foo.com/index.html");
51 const GURL
ManifestParserTest::default_manifest_url(
52 "http://foo.com/manifest.json");
54 TEST_F(ManifestParserTest
, CrashTest
) {
55 // Passing temporary variables should not crash.
56 ManifestParser
parser("{\"start_url\": \"/\"}",
57 GURL("http://example.com"),
58 GURL("http://example.com"));
61 // .Parse() should have been call without crashing and succeeded.
62 EXPECT_EQ(0u, parser
.errors().size());
63 EXPECT_FALSE(parser
.manifest().IsEmpty());
66 TEST_F(ManifestParserTest
, EmptyStringNull
) {
67 Manifest manifest
= ParseManifest("");
69 // This Manifest is not a valid JSON object, it's a parsing error.
70 EXPECT_EQ(1u, GetErrorCount());
71 EXPECT_EQ("Manifest parsing error: Line: 1, column: 1, Unexpected token.",
74 // A parsing error is equivalent to an empty manifest.
75 ASSERT_TRUE(manifest
.IsEmpty());
76 ASSERT_TRUE(manifest
.name
.is_null());
77 ASSERT_TRUE(manifest
.short_name
.is_null());
78 ASSERT_TRUE(manifest
.start_url
.is_empty());
79 ASSERT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_UNSPECIFIED
);
80 ASSERT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockDefault
);
81 ASSERT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
82 ASSERT_TRUE(manifest
.gcm_sender_id
.is_null());
85 TEST_F(ManifestParserTest
, ValidNoContentParses
) {
86 Manifest manifest
= ParseManifest("{}");
88 // Empty Manifest is not a parsing error.
89 EXPECT_EQ(0u, GetErrorCount());
91 // Check that all the fields are null in that case.
92 ASSERT_TRUE(manifest
.IsEmpty());
93 ASSERT_TRUE(manifest
.name
.is_null());
94 ASSERT_TRUE(manifest
.short_name
.is_null());
95 ASSERT_TRUE(manifest
.start_url
.is_empty());
96 ASSERT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_UNSPECIFIED
);
97 ASSERT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockDefault
);
98 ASSERT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
99 ASSERT_TRUE(manifest
.gcm_sender_id
.is_null());
102 TEST_F(ManifestParserTest
, MultipleErrorsReporting
) {
103 Manifest manifest
= ParseManifest("{ \"name\": 42, \"short_name\": 4,"
104 "\"orientation\": {}, \"display\": \"foo\","
105 "\"start_url\": null, \"icons\": {}, \"theme_color\": 42 }");
107 EXPECT_EQ(7u, GetErrorCount());
109 EXPECT_EQ("Manifest parsing error: property 'name' ignored,"
110 " type string expected.",
112 EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
113 " type string expected.",
115 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
116 " type string expected.",
118 EXPECT_EQ("Manifest parsing error: unknown 'display' value ignored.",
120 EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
121 " type string expected.",
123 EXPECT_EQ("Manifest parsing error: property 'icons' ignored, "
124 "type array expected.",
126 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
127 " type string expected.",
131 TEST_F(ManifestParserTest
, NameParseRules
) {
134 Manifest manifest
= ParseManifest("{ \"name\": \"foo\" }");
135 ASSERT_TRUE(base::EqualsASCII(manifest
.name
.string(), "foo"));
136 ASSERT_FALSE(manifest
.IsEmpty());
137 EXPECT_EQ(0u, GetErrorCount());
142 Manifest manifest
= ParseManifest("{ \"name\": \" foo \" }");
143 ASSERT_TRUE(base::EqualsASCII(manifest
.name
.string(), "foo"));
144 EXPECT_EQ(0u, GetErrorCount());
147 // Don't parse if name isn't a string.
149 Manifest manifest
= ParseManifest("{ \"name\": {} }");
150 ASSERT_TRUE(manifest
.name
.is_null());
151 EXPECT_EQ(1u, GetErrorCount());
152 EXPECT_EQ("Manifest parsing error: property 'name' ignored,"
153 " type string expected.",
157 // Don't parse if name isn't a string.
159 Manifest manifest
= ParseManifest("{ \"name\": 42 }");
160 ASSERT_TRUE(manifest
.name
.is_null());
161 EXPECT_EQ(1u, GetErrorCount());
162 EXPECT_EQ("Manifest parsing error: property 'name' ignored,"
163 " type string expected.",
168 TEST_F(ManifestParserTest
, ShortNameParseRules
) {
171 Manifest manifest
= ParseManifest("{ \"short_name\": \"foo\" }");
172 ASSERT_TRUE(base::EqualsASCII(manifest
.short_name
.string(), "foo"));
173 ASSERT_FALSE(manifest
.IsEmpty());
174 EXPECT_EQ(0u, GetErrorCount());
179 Manifest manifest
= ParseManifest("{ \"short_name\": \" foo \" }");
180 ASSERT_TRUE(base::EqualsASCII(manifest
.short_name
.string(), "foo"));
181 EXPECT_EQ(0u, GetErrorCount());
184 // Don't parse if name isn't a string.
186 Manifest manifest
= ParseManifest("{ \"short_name\": {} }");
187 ASSERT_TRUE(manifest
.short_name
.is_null());
188 EXPECT_EQ(1u, GetErrorCount());
189 EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
190 " type string expected.",
194 // Don't parse if name isn't a string.
196 Manifest manifest
= ParseManifest("{ \"short_name\": 42 }");
197 ASSERT_TRUE(manifest
.short_name
.is_null());
198 EXPECT_EQ(1u, GetErrorCount());
199 EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
200 " type string expected.",
205 TEST_F(ManifestParserTest
, StartURLParseRules
) {
208 Manifest manifest
= ParseManifest("{ \"start_url\": \"land.html\" }");
209 ASSERT_EQ(manifest
.start_url
.spec(),
210 default_document_url
.Resolve("land.html").spec());
211 ASSERT_FALSE(manifest
.IsEmpty());
212 EXPECT_EQ(0u, GetErrorCount());
217 Manifest manifest
= ParseManifest("{ \"start_url\": \" land.html \" }");
218 ASSERT_EQ(manifest
.start_url
.spec(),
219 default_document_url
.Resolve("land.html").spec());
220 EXPECT_EQ(0u, GetErrorCount());
223 // Don't parse if property isn't a string.
225 Manifest manifest
= ParseManifest("{ \"start_url\": {} }");
226 ASSERT_TRUE(manifest
.start_url
.is_empty());
227 EXPECT_EQ(1u, GetErrorCount());
228 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
229 " type string expected.",
233 // Don't parse if property isn't a string.
235 Manifest manifest
= ParseManifest("{ \"start_url\": 42 }");
236 ASSERT_TRUE(manifest
.start_url
.is_empty());
237 EXPECT_EQ(1u, GetErrorCount());
238 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
239 " type string expected.",
243 // Absolute start_url, same origin with document.
246 ParseManifestWithURLs("{ \"start_url\": \"http://foo.com/land.html\" }",
247 GURL("http://foo.com/manifest.json"),
248 GURL("http://foo.com/index.html"));
249 ASSERT_EQ(manifest
.start_url
.spec(), "http://foo.com/land.html");
250 EXPECT_EQ(0u, GetErrorCount());
253 // Absolute start_url, cross origin with document.
256 ParseManifestWithURLs("{ \"start_url\": \"http://bar.com/land.html\" }",
257 GURL("http://foo.com/manifest.json"),
258 GURL("http://foo.com/index.html"));
259 ASSERT_TRUE(manifest
.start_url
.is_empty());
260 EXPECT_EQ(1u, GetErrorCount());
261 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored, should "
262 "be same origin as document.",
266 // Resolving has to happen based on the manifest_url.
269 ParseManifestWithURLs("{ \"start_url\": \"land.html\" }",
270 GURL("http://foo.com/landing/manifest.json"),
271 GURL("http://foo.com/index.html"));
272 ASSERT_EQ(manifest
.start_url
.spec(), "http://foo.com/landing/land.html");
273 EXPECT_EQ(0u, GetErrorCount());
277 TEST_F(ManifestParserTest
, DisplayParserRules
) {
280 Manifest manifest
= ParseManifest("{ \"display\": \"browser\" }");
281 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_BROWSER
);
282 EXPECT_FALSE(manifest
.IsEmpty());
283 EXPECT_EQ(0u, GetErrorCount());
288 Manifest manifest
= ParseManifest("{ \"display\": \" browser \" }");
289 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_BROWSER
);
290 EXPECT_EQ(0u, GetErrorCount());
293 // Don't parse if name isn't a string.
295 Manifest manifest
= ParseManifest("{ \"display\": {} }");
296 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_UNSPECIFIED
);
297 EXPECT_EQ(1u, GetErrorCount());
298 EXPECT_EQ("Manifest parsing error: property 'display' ignored,"
299 " type string expected.",
303 // Don't parse if name isn't a string.
305 Manifest manifest
= ParseManifest("{ \"display\": 42 }");
306 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_UNSPECIFIED
);
307 EXPECT_EQ(1u, GetErrorCount());
308 EXPECT_EQ("Manifest parsing error: property 'display' ignored,"
309 " type string expected.",
313 // Parse fails if string isn't known.
315 Manifest manifest
= ParseManifest("{ \"display\": \"browser_something\" }");
316 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_UNSPECIFIED
);
317 EXPECT_EQ(1u, GetErrorCount());
318 EXPECT_EQ("Manifest parsing error: unknown 'display' value ignored.",
322 // Accept 'fullscreen'.
324 Manifest manifest
= ParseManifest("{ \"display\": \"fullscreen\" }");
325 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_FULLSCREEN
);
326 EXPECT_EQ(0u, GetErrorCount());
329 // Accept 'fullscreen'.
331 Manifest manifest
= ParseManifest("{ \"display\": \"standalone\" }");
332 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_STANDALONE
);
333 EXPECT_EQ(0u, GetErrorCount());
336 // Accept 'minimal-ui'.
338 Manifest manifest
= ParseManifest("{ \"display\": \"minimal-ui\" }");
339 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_MINIMAL_UI
);
340 EXPECT_EQ(0u, GetErrorCount());
345 Manifest manifest
= ParseManifest("{ \"display\": \"browser\" }");
346 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_BROWSER
);
347 EXPECT_EQ(0u, GetErrorCount());
352 Manifest manifest
= ParseManifest("{ \"display\": \"BROWSER\" }");
353 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_BROWSER
);
354 EXPECT_EQ(0u, GetErrorCount());
358 TEST_F(ManifestParserTest
, OrientationParserRules
) {
361 Manifest manifest
= ParseManifest("{ \"orientation\": \"natural\" }");
362 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockNatural
);
363 EXPECT_FALSE(manifest
.IsEmpty());
364 EXPECT_EQ(0u, GetErrorCount());
369 Manifest manifest
= ParseManifest("{ \"orientation\": \"natural\" }");
370 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockNatural
);
371 EXPECT_EQ(0u, GetErrorCount());
374 // Don't parse if name isn't a string.
376 Manifest manifest
= ParseManifest("{ \"orientation\": {} }");
377 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockDefault
);
378 EXPECT_EQ(1u, GetErrorCount());
379 EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
380 " type string expected.",
384 // Don't parse if name isn't a string.
386 Manifest manifest
= ParseManifest("{ \"orientation\": 42 }");
387 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockDefault
);
388 EXPECT_EQ(1u, GetErrorCount());
389 EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
390 " type string expected.",
394 // Parse fails if string isn't known.
396 Manifest manifest
= ParseManifest("{ \"orientation\": \"naturalish\" }");
397 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockDefault
);
398 EXPECT_EQ(1u, GetErrorCount());
399 EXPECT_EQ("Manifest parsing error: unknown 'orientation' value ignored.",
405 Manifest manifest
= ParseManifest("{ \"orientation\": \"any\" }");
406 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockAny
);
407 EXPECT_EQ(0u, GetErrorCount());
412 Manifest manifest
= ParseManifest("{ \"orientation\": \"natural\" }");
413 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockNatural
);
414 EXPECT_EQ(0u, GetErrorCount());
417 // Accept 'landscape'.
419 Manifest manifest
= ParseManifest("{ \"orientation\": \"landscape\" }");
420 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockLandscape
);
421 EXPECT_EQ(0u, GetErrorCount());
424 // Accept 'landscape-primary'.
427 ParseManifest("{ \"orientation\": \"landscape-primary\" }");
428 EXPECT_EQ(manifest
.orientation
,
429 blink::WebScreenOrientationLockLandscapePrimary
);
430 EXPECT_EQ(0u, GetErrorCount());
433 // Accept 'landscape-secondary'.
436 ParseManifest("{ \"orientation\": \"landscape-secondary\" }");
437 EXPECT_EQ(manifest
.orientation
,
438 blink::WebScreenOrientationLockLandscapeSecondary
);
439 EXPECT_EQ(0u, GetErrorCount());
442 // Accept 'portrait'.
444 Manifest manifest
= ParseManifest("{ \"orientation\": \"portrait\" }");
445 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockPortrait
);
446 EXPECT_EQ(0u, GetErrorCount());
449 // Accept 'portrait-primary'.
452 ParseManifest("{ \"orientation\": \"portrait-primary\" }");
453 EXPECT_EQ(manifest
.orientation
,
454 blink::WebScreenOrientationLockPortraitPrimary
);
455 EXPECT_EQ(0u, GetErrorCount());
458 // Accept 'portrait-secondary'.
461 ParseManifest("{ \"orientation\": \"portrait-secondary\" }");
462 EXPECT_EQ(manifest
.orientation
,
463 blink::WebScreenOrientationLockPortraitSecondary
);
464 EXPECT_EQ(0u, GetErrorCount());
469 Manifest manifest
= ParseManifest("{ \"orientation\": \"LANDSCAPE\" }");
470 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockLandscape
);
471 EXPECT_EQ(0u, GetErrorCount());
475 TEST_F(ManifestParserTest
, IconsParseRules
) {
476 // Smoke test: if no icon, empty list.
478 Manifest manifest
= ParseManifest("{ \"icons\": [] }");
479 EXPECT_EQ(manifest
.icons
.size(), 0u);
480 EXPECT_TRUE(manifest
.IsEmpty());
481 EXPECT_EQ(0u, GetErrorCount());
484 // Smoke test: if empty icon, empty list.
486 Manifest manifest
= ParseManifest("{ \"icons\": [ {} ] }");
487 EXPECT_EQ(manifest
.icons
.size(), 0u);
488 EXPECT_TRUE(manifest
.IsEmpty());
489 EXPECT_EQ(0u, GetErrorCount());
492 // Smoke test: icon with invalid src, empty list.
494 Manifest manifest
= ParseManifest("{ \"icons\": [ { \"icons\": [] } ] }");
495 EXPECT_EQ(manifest
.icons
.size(), 0u);
496 EXPECT_TRUE(manifest
.IsEmpty());
497 EXPECT_EQ(0u, GetErrorCount());
500 // Smoke test: if icon with empty src, it will be present in the list.
502 Manifest manifest
= ParseManifest("{ \"icons\": [ { \"src\": \"\" } ] }");
503 EXPECT_EQ(manifest
.icons
.size(), 1u);
504 EXPECT_EQ(manifest
.icons
[0].src
.spec(), "http://foo.com/index.html");
505 EXPECT_FALSE(manifest
.IsEmpty());
506 EXPECT_EQ(0u, GetErrorCount());
509 // Smoke test: if one icons with valid src, it will be present in the list.
512 ParseManifest("{ \"icons\": [{ \"src\": \"foo.jpg\" }] }");
513 EXPECT_EQ(manifest
.icons
.size(), 1u);
514 EXPECT_EQ(manifest
.icons
[0].src
.spec(), "http://foo.com/foo.jpg");
515 EXPECT_FALSE(manifest
.IsEmpty());
516 EXPECT_EQ(0u, GetErrorCount());
520 TEST_F(ManifestParserTest
, IconSrcParseRules
) {
524 ParseManifest("{ \"icons\": [ {\"src\": \"foo.png\" } ] }");
525 EXPECT_EQ(manifest
.icons
[0].src
.spec(),
526 default_document_url
.Resolve("foo.png").spec());
527 EXPECT_EQ(0u, GetErrorCount());
533 ParseManifest("{ \"icons\": [ {\"src\": \" foo.png \" } ] }");
534 EXPECT_EQ(manifest
.icons
[0].src
.spec(),
535 default_document_url
.Resolve("foo.png").spec());
536 EXPECT_EQ(0u, GetErrorCount());
539 // Don't parse if property isn't a string.
541 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": {} } ] }");
542 EXPECT_TRUE(manifest
.icons
.empty());
543 EXPECT_EQ(1u, GetErrorCount());
544 EXPECT_EQ("Manifest parsing error: property 'src' ignored,"
545 " type string expected.",
549 // Don't parse if property isn't a string.
551 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": 42 } ] }");
552 EXPECT_TRUE(manifest
.icons
.empty());
553 EXPECT_EQ(1u, GetErrorCount());
554 EXPECT_EQ("Manifest parsing error: property 'src' ignored,"
555 " type string expected.",
559 // Resolving has to happen based on the document_url.
561 Manifest manifest
= ParseManifestWithURLs(
562 "{ \"icons\": [ {\"src\": \"icons/foo.png\" } ] }",
563 GURL("http://foo.com/landing/index.html"),
564 default_manifest_url
);
565 EXPECT_EQ(manifest
.icons
[0].src
.spec(),
566 "http://foo.com/landing/icons/foo.png");
567 EXPECT_EQ(0u, GetErrorCount());
571 TEST_F(ManifestParserTest
, IconTypeParseRules
) {
575 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": \"foo\" } ] }");
576 EXPECT_TRUE(base::EqualsASCII(manifest
.icons
[0].type
.string(), "foo"));
577 EXPECT_EQ(0u, GetErrorCount());
582 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
583 " \"type\": \" foo \" } ] }");
584 EXPECT_TRUE(base::EqualsASCII(manifest
.icons
[0].type
.string(), "foo"));
585 EXPECT_EQ(0u, GetErrorCount());
588 // Don't parse if property isn't a string.
591 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": {} } ] }");
592 EXPECT_TRUE(manifest
.icons
[0].type
.is_null());
593 EXPECT_EQ(1u, GetErrorCount());
594 EXPECT_EQ("Manifest parsing error: property 'type' ignored,"
595 " type string expected.",
599 // Don't parse if property isn't a string.
602 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": 42 } ] }");
603 EXPECT_TRUE(manifest
.icons
[0].type
.is_null());
604 EXPECT_EQ(1u, GetErrorCount());
605 EXPECT_EQ("Manifest parsing error: property 'type' ignored,"
606 " type string expected.",
611 TEST_F(ManifestParserTest
, IconDensityParseRules
) {
615 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 42 } ] }");
616 EXPECT_EQ(manifest
.icons
[0].density
, 42);
617 EXPECT_EQ(0u, GetErrorCount());
623 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 2.5 } ] }");
624 EXPECT_EQ(manifest
.icons
[0].density
, 2.5);
625 EXPECT_EQ(0u, GetErrorCount());
628 // Parse fail if it isn't a float.
631 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": {} } ] }");
632 EXPECT_EQ(manifest
.icons
[0].density
, Manifest::Icon::kDefaultDensity
);
633 EXPECT_EQ(1u, GetErrorCount());
634 EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
635 "must be float greater than 0.",
639 // Parse fail if it isn't a float.
642 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\":\"2\" } ] }");
643 EXPECT_EQ(manifest
.icons
[0].density
, Manifest::Icon::kDefaultDensity
);
644 EXPECT_EQ(1u, GetErrorCount());
645 EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
646 "must be float greater than 0.",
653 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 1.00 } ] }");
654 EXPECT_EQ(manifest
.icons
[0].density
, 1);
655 EXPECT_EQ(0u, GetErrorCount());
658 // Edge case: values between 0.0 and 1.0 are allowed.
661 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 0.42 } ] }");
662 EXPECT_EQ(manifest
.icons
[0].density
, 0.42);
663 EXPECT_EQ(0u, GetErrorCount());
666 // 0 is an invalid value.
669 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 0.0 } ] }");
670 EXPECT_EQ(manifest
.icons
[0].density
, Manifest::Icon::kDefaultDensity
);
671 EXPECT_EQ(1u, GetErrorCount());
672 EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
673 "must be float greater than 0.",
677 // Negative values are invalid.
680 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": -2.5 } ] }");
681 EXPECT_EQ(manifest
.icons
[0].density
, Manifest::Icon::kDefaultDensity
);
682 EXPECT_EQ(1u, GetErrorCount());
683 EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
684 "must be float greater than 0.",
689 TEST_F(ManifestParserTest
, IconSizesParseRules
) {
692 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
693 "\"sizes\": \"42x42\" } ] }");
694 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 1u);
695 EXPECT_EQ(0u, GetErrorCount());
700 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
701 "\"sizes\": \" 42x42 \" } ] }");
702 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 1u);
703 EXPECT_EQ(0u, GetErrorCount());
706 // Ignore sizes if property isn't a string.
708 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
709 "\"sizes\": {} } ] }");
710 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 0u);
711 EXPECT_EQ(1u, GetErrorCount());
712 EXPECT_EQ("Manifest parsing error: property 'sizes' ignored,"
713 " type string expected.",
717 // Ignore sizes if property isn't a string.
719 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
720 "\"sizes\": 42 } ] }");
721 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 0u);
722 EXPECT_EQ(1u, GetErrorCount());
723 EXPECT_EQ("Manifest parsing error: property 'sizes' ignored,"
724 " type string expected.",
728 // Smoke test: value correctly parsed.
730 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
731 "\"sizes\": \"42x42 48x48\" } ] }");
732 EXPECT_EQ(manifest
.icons
[0].sizes
[0], gfx::Size(42, 42));
733 EXPECT_EQ(manifest
.icons
[0].sizes
[1], gfx::Size(48, 48));
734 EXPECT_EQ(0u, GetErrorCount());
737 // <WIDTH>'x'<HEIGHT> and <WIDTH>'X'<HEIGHT> are equivalent.
739 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
740 "\"sizes\": \"42X42 48X48\" } ] }");
741 EXPECT_EQ(manifest
.icons
[0].sizes
[0], gfx::Size(42, 42));
742 EXPECT_EQ(manifest
.icons
[0].sizes
[1], gfx::Size(48, 48));
743 EXPECT_EQ(0u, GetErrorCount());
746 // Twice the same value is parsed twice.
748 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
749 "\"sizes\": \"42X42 42x42\" } ] }");
750 EXPECT_EQ(manifest
.icons
[0].sizes
[0], gfx::Size(42, 42));
751 EXPECT_EQ(manifest
.icons
[0].sizes
[1], gfx::Size(42, 42));
752 EXPECT_EQ(0u, GetErrorCount());
755 // Width or height can't start with 0.
757 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
758 "\"sizes\": \"004X007 042x00\" } ] }");
759 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 0u);
760 EXPECT_EQ(1u, GetErrorCount());
761 EXPECT_EQ("Manifest parsing error: found icon with no valid size.",
765 // Width and height MUST contain digits.
767 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
768 "\"sizes\": \"e4X1.0 55ax1e10\" } ] }");
769 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 0u);
770 EXPECT_EQ(1u, GetErrorCount());
771 EXPECT_EQ("Manifest parsing error: found icon with no valid size.",
775 // 'any' is correctly parsed and transformed to gfx::Size(0,0).
777 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
778 "\"sizes\": \"any AnY ANY aNy\" } ] }");
779 gfx::Size any
= gfx::Size(0, 0);
780 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 4u);
781 EXPECT_EQ(manifest
.icons
[0].sizes
[0], any
);
782 EXPECT_EQ(manifest
.icons
[0].sizes
[1], any
);
783 EXPECT_EQ(manifest
.icons
[0].sizes
[2], any
);
784 EXPECT_EQ(manifest
.icons
[0].sizes
[3], any
);
785 EXPECT_EQ(0u, GetErrorCount());
788 // Some invalid width/height combinations.
790 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
791 "\"sizes\": \"x 40xx 1x2x3 x42 42xx42\" } ] }");
792 gfx::Size any
= gfx::Size(0, 0);
793 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 0u);
794 EXPECT_EQ(1u, GetErrorCount());
795 EXPECT_EQ("Manifest parsing error: found icon with no valid size.",
800 TEST_F(ManifestParserTest
, RelatedApplicationsParseRules
) {
801 // If no application, empty list.
803 Manifest manifest
= ParseManifest(
804 "{ \"related_applications\": []}");
805 EXPECT_EQ(manifest
.related_applications
.size(), 0u);
806 EXPECT_TRUE(manifest
.IsEmpty());
807 EXPECT_EQ(0u, GetErrorCount());
810 // If empty application, empty list.
812 Manifest manifest
= ParseManifest(
813 "{ \"related_applications\": [{}]}");
814 EXPECT_EQ(manifest
.related_applications
.size(), 0u);
815 EXPECT_TRUE(manifest
.IsEmpty());
816 EXPECT_EQ(1u, GetErrorCount());
817 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
818 "related application ignored.",
822 // If invalid platform, application is ignored.
824 Manifest manifest
= ParseManifest(
825 "{ \"related_applications\": [{\"platform\": 123}]}");
826 EXPECT_EQ(manifest
.related_applications
.size(), 0u);
827 EXPECT_TRUE(manifest
.IsEmpty());
828 EXPECT_EQ(2u, GetErrorCount());
830 "Manifest parsing error: property 'platform' ignored, type string "
833 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
834 "related application ignored.",
838 // If missing platform, application is ignored.
840 Manifest manifest
= ParseManifest(
841 "{ \"related_applications\": [{\"id\": \"foo\"}]}");
842 EXPECT_EQ(manifest
.related_applications
.size(), 0u);
843 EXPECT_TRUE(manifest
.IsEmpty());
844 EXPECT_EQ(1u, GetErrorCount());
845 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
846 "related application ignored.",
850 // If missing id and url, application is ignored.
852 Manifest manifest
= ParseManifest(
853 "{ \"related_applications\": [{\"platform\": \"play\"}]}");
854 EXPECT_EQ(manifest
.related_applications
.size(), 0u);
855 EXPECT_TRUE(manifest
.IsEmpty());
856 EXPECT_EQ(1u, GetErrorCount());
857 EXPECT_EQ("Manifest parsing error: one of 'url' or 'id' is required, "
858 "related application ignored.",
862 // Valid application, with url.
864 Manifest manifest
= ParseManifest(
865 "{ \"related_applications\": ["
866 "{\"platform\": \"play\", \"url\": \"http://www.foo.com\"}]}");
867 EXPECT_EQ(manifest
.related_applications
.size(), 1u);
868 EXPECT_TRUE(base::EqualsASCII(
869 manifest
.related_applications
[0].platform
.string(),
871 EXPECT_EQ(manifest
.related_applications
[0].url
.spec(),
872 "http://www.foo.com/");
873 EXPECT_FALSE(manifest
.IsEmpty());
874 EXPECT_EQ(0u, GetErrorCount());
877 // Valid application, with id.
879 Manifest manifest
= ParseManifest(
880 "{ \"related_applications\": ["
881 "{\"platform\": \"itunes\", \"id\": \"foo\"}]}");
882 EXPECT_EQ(manifest
.related_applications
.size(), 1u);
883 EXPECT_TRUE(base::EqualsASCII(
884 manifest
.related_applications
[0].platform
.string(),
886 EXPECT_TRUE(base::EqualsASCII(manifest
.related_applications
[0].id
.string(),
888 EXPECT_FALSE(manifest
.IsEmpty());
889 EXPECT_EQ(0u, GetErrorCount());
892 // All valid applications are in list.
894 Manifest manifest
= ParseManifest(
895 "{ \"related_applications\": ["
896 "{\"platform\": \"play\", \"id\": \"foo\"},"
897 "{\"platform\": \"itunes\", \"id\": \"bar\"}]}");
898 EXPECT_EQ(manifest
.related_applications
.size(), 2u);
899 EXPECT_TRUE(base::EqualsASCII(
900 manifest
.related_applications
[0].platform
.string(),
902 EXPECT_TRUE(base::EqualsASCII(manifest
.related_applications
[0].id
.string(),
904 EXPECT_TRUE(base::EqualsASCII(
905 manifest
.related_applications
[1].platform
.string(),
907 EXPECT_TRUE(base::EqualsASCII(manifest
.related_applications
[1].id
.string(),
909 EXPECT_FALSE(manifest
.IsEmpty());
910 EXPECT_EQ(0u, GetErrorCount());
913 // Two invalid applications and one valid. Only the valid application should
916 Manifest manifest
= ParseManifest(
917 "{ \"related_applications\": ["
918 "{\"platform\": \"itunes\"},"
919 "{\"platform\": \"play\", \"id\": \"foo\"},"
921 EXPECT_EQ(manifest
.related_applications
.size(), 1u);
922 EXPECT_TRUE(base::EqualsASCII(
923 manifest
.related_applications
[0].platform
.string(),
925 EXPECT_TRUE(base::EqualsASCII(manifest
.related_applications
[0].id
.string(),
927 EXPECT_FALSE(manifest
.IsEmpty());
928 EXPECT_EQ(2u, GetErrorCount());
929 EXPECT_EQ("Manifest parsing error: one of 'url' or 'id' is required, "
930 "related application ignored.",
932 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
933 "related application ignored.",
938 TEST_F(ManifestParserTest
, ParsePreferRelatedApplicationsParseRules
) {
942 ParseManifest("{ \"prefer_related_applications\": true }");
943 EXPECT_TRUE(manifest
.prefer_related_applications
);
944 EXPECT_EQ(0u, GetErrorCount());
947 // Don't parse if the property isn't a boolean.
950 ParseManifest("{ \"prefer_related_applications\": {} }");
951 EXPECT_FALSE(manifest
.prefer_related_applications
);
952 EXPECT_EQ(1u, GetErrorCount());
954 "Manifest parsing error: property 'prefer_related_applications' "
955 "ignored, type boolean expected.",
959 Manifest manifest
= ParseManifest(
960 "{ \"prefer_related_applications\": \"true\" }");
961 EXPECT_FALSE(manifest
.prefer_related_applications
);
962 EXPECT_EQ(1u, GetErrorCount());
964 "Manifest parsing error: property 'prefer_related_applications' "
965 "ignored, type boolean expected.",
969 Manifest manifest
= ParseManifest("{ \"prefer_related_applications\": 1 }");
970 EXPECT_FALSE(manifest
.prefer_related_applications
);
971 EXPECT_EQ(1u, GetErrorCount());
973 "Manifest parsing error: property 'prefer_related_applications' "
974 "ignored, type boolean expected.",
978 // "False" should set the boolean false without throwing errors.
981 ParseManifest("{ \"prefer_related_applications\": false }");
982 EXPECT_FALSE(manifest
.prefer_related_applications
);
983 EXPECT_EQ(0u, GetErrorCount());
987 TEST_F(ManifestParserTest
, ThemeColorParserRules
) {
990 Manifest manifest
= ParseManifest("{ \"theme_color\": \"#FF0000\" }");
991 EXPECT_EQ(manifest
.theme_color
, 0xFFFF0000);
992 EXPECT_FALSE(manifest
.IsEmpty());
993 EXPECT_EQ(0u, GetErrorCount());
998 Manifest manifest
= ParseManifest("{ \"theme_color\": \" blue \" }");
999 EXPECT_EQ(manifest
.theme_color
, 0xFF0000FF);
1000 EXPECT_EQ(0u, GetErrorCount());
1003 // Don't parse if theme_color isn't a string.
1005 Manifest manifest
= ParseManifest("{ \"theme_color\": {} }");
1006 EXPECT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
1007 EXPECT_EQ(1u, GetErrorCount());
1008 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
1009 " type string expected.",
1013 // Don't parse if theme_color isn't a string.
1015 Manifest manifest
= ParseManifest("{ \"theme_color\": false }");
1016 EXPECT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
1017 EXPECT_EQ(1u, GetErrorCount());
1018 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
1019 " type string expected.",
1023 // Don't parse if theme_color isn't a string.
1025 Manifest manifest
= ParseManifest("{ \"theme_color\": null }");
1026 EXPECT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
1027 EXPECT_EQ(1u, GetErrorCount());
1028 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
1029 " type string expected.",
1033 // Don't parse if theme_color isn't a string.
1035 Manifest manifest
= ParseManifest("{ \"theme_color\": [] }");
1036 EXPECT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
1037 EXPECT_EQ(1u, GetErrorCount());
1038 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
1039 " type string expected.",
1043 // Don't parse if theme_color isn't a string.
1045 Manifest manifest
= ParseManifest("{ \"theme_color\": 42 }");
1046 EXPECT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
1047 EXPECT_EQ(1u, GetErrorCount());
1048 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
1049 " type string expected.",
1053 // Parse fails if string is not in a known format.
1055 Manifest manifest
= ParseManifest("{ \"theme_color\": \"foo(bar)\" }");
1056 EXPECT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
1057 EXPECT_EQ(1u, GetErrorCount());
1058 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
1059 " 'foo(bar)' is not a valid color.",
1063 // Parse fails if string is not in a known format.
1065 Manifest manifest
= ParseManifest("{ \"theme_color\": \"bleu\" }");
1066 EXPECT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
1067 EXPECT_EQ(1u, GetErrorCount());
1068 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored, 'bleu'"
1069 " is not a valid color.",
1073 // Parse fails if string is not in a known format.
1075 Manifest manifest
= ParseManifest("{ \"theme_color\": \"FF00FF\" }");
1076 EXPECT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
1077 EXPECT_EQ(1u, GetErrorCount());
1078 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored, 'FF00FF'"
1079 " is not a valid color.",
1083 // Parse fails if multiple values for theme_color are given.
1085 Manifest manifest
= ParseManifest("{ \"theme_color\": \"#ABC #DEF\" }");
1086 EXPECT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
1087 EXPECT_EQ(1u, GetErrorCount());
1088 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored, "
1089 "'#ABC #DEF' is not a valid color.",
1093 // Parse fails if multiple values for theme_color are given.
1095 Manifest manifest
= ParseManifest(
1096 "{ \"theme_color\": \"#AABBCC #DDEEFF\" }");
1097 EXPECT_EQ(manifest
.theme_color
, Manifest::kInvalidOrMissingThemeColor
);
1098 EXPECT_EQ(1u, GetErrorCount());
1099 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored, "
1100 "'#AABBCC #DDEEFF' is not a valid color.",
1104 // Accept CSS color keyword format.
1106 Manifest manifest
= ParseManifest("{ \"theme_color\": \"blue\" }");
1107 EXPECT_EQ(manifest
.theme_color
, 0xFF0000FF);
1108 EXPECT_EQ(0u, GetErrorCount());
1111 // Accept CSS color keyword format.
1113 Manifest manifest
= ParseManifest("{ \"theme_color\": \"chartreuse\" }");
1114 EXPECT_EQ(manifest
.theme_color
, 0xFF7FFF00);
1115 EXPECT_EQ(0u, GetErrorCount());
1118 // Accept CSS RGB format.
1120 Manifest manifest
= ParseManifest("{ \"theme_color\": \"#FFF\" }");
1121 EXPECT_EQ(manifest
.theme_color
, 0xFFFFFFFF);
1122 EXPECT_EQ(0u, GetErrorCount());
1125 // Accept CSS RGB format.
1127 Manifest manifest
= ParseManifest("{ \"theme_color\": \"#ABC\" }");
1128 EXPECT_EQ(manifest
.theme_color
, 0xFFAABBCC);
1129 EXPECT_EQ(0u, GetErrorCount());
1132 // Accept CSS RRGGBB format.
1134 Manifest manifest
= ParseManifest("{ \"theme_color\": \"#FF0000\" }");
1135 EXPECT_EQ(manifest
.theme_color
, 0xFFFF0000);
1136 EXPECT_EQ(0u, GetErrorCount());
1140 TEST_F(ManifestParserTest
, GCMSenderIDParseRules
) {
1143 Manifest manifest
= ParseManifest("{ \"gcm_sender_id\": \"foo\" }");
1144 EXPECT_TRUE(base::EqualsASCII(manifest
.gcm_sender_id
.string(), "foo"));
1145 EXPECT_EQ(0u, GetErrorCount());
1148 // Trim whitespaces.
1150 Manifest manifest
= ParseManifest("{ \"gcm_sender_id\": \" foo \" }");
1151 EXPECT_TRUE(base::EqualsASCII(manifest
.gcm_sender_id
.string(), "foo"));
1152 EXPECT_EQ(0u, GetErrorCount());
1155 // Don't parse if the property isn't a string.
1157 Manifest manifest
= ParseManifest("{ \"gcm_sender_id\": {} }");
1158 EXPECT_TRUE(manifest
.gcm_sender_id
.is_null());
1159 EXPECT_EQ(1u, GetErrorCount());
1160 EXPECT_EQ("Manifest parsing error: property 'gcm_sender_id' ignored,"
1161 " type string expected.",
1165 Manifest manifest
= ParseManifest("{ \"gcm_sender_id\": 42 }");
1166 EXPECT_TRUE(manifest
.gcm_sender_id
.is_null());
1167 EXPECT_EQ(1u, GetErrorCount());
1168 EXPECT_EQ("Manifest parsing error: property 'gcm_sender_id' ignored,"
1169 " type string expected.",
1174 } // namespace content