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_TRUE(manifest
.gcm_sender_id
.is_null());
84 TEST_F(ManifestParserTest
, ValidNoContentParses
) {
85 Manifest manifest
= ParseManifest("{}");
87 // Empty Manifest is not a parsing error.
88 EXPECT_EQ(0u, GetErrorCount());
90 // Check that all the fields are null in that case.
91 ASSERT_TRUE(manifest
.IsEmpty());
92 ASSERT_TRUE(manifest
.name
.is_null());
93 ASSERT_TRUE(manifest
.short_name
.is_null());
94 ASSERT_TRUE(manifest
.start_url
.is_empty());
95 ASSERT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_UNSPECIFIED
);
96 ASSERT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockDefault
);
97 ASSERT_TRUE(manifest
.gcm_sender_id
.is_null());
100 TEST_F(ManifestParserTest
, MultipleErrorsReporting
) {
101 Manifest manifest
= ParseManifest("{ \"name\": 42, \"short_name\": 4,"
102 "\"orientation\": {}, \"display\": \"foo\", \"start_url\": null,"
105 EXPECT_EQ(6u, GetErrorCount());
107 EXPECT_EQ("Manifest parsing error: property 'name' ignored,"
108 " type string expected.",
110 EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
111 " type string expected.",
113 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
114 " type string expected.",
116 EXPECT_EQ("Manifest parsing error: unknown 'display' value ignored.",
118 EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
119 " type string expected.",
121 EXPECT_EQ("Manifest parsing error: property 'icons' ignored, "
122 "type array expected.",
126 TEST_F(ManifestParserTest
, NameParseRules
) {
129 Manifest manifest
= ParseManifest("{ \"name\": \"foo\" }");
130 ASSERT_TRUE(EqualsASCII(manifest
.name
.string(), "foo"));
131 ASSERT_FALSE(manifest
.IsEmpty());
132 EXPECT_EQ(0u, GetErrorCount());
137 Manifest manifest
= ParseManifest("{ \"name\": \" foo \" }");
138 ASSERT_TRUE(EqualsASCII(manifest
.name
.string(), "foo"));
139 EXPECT_EQ(0u, GetErrorCount());
142 // Don't parse if name isn't a string.
144 Manifest manifest
= ParseManifest("{ \"name\": {} }");
145 ASSERT_TRUE(manifest
.name
.is_null());
146 EXPECT_EQ(1u, GetErrorCount());
147 EXPECT_EQ("Manifest parsing error: property 'name' ignored,"
148 " type string expected.",
152 // Don't parse if name isn't a string.
154 Manifest manifest
= ParseManifest("{ \"name\": 42 }");
155 ASSERT_TRUE(manifest
.name
.is_null());
156 EXPECT_EQ(1u, GetErrorCount());
157 EXPECT_EQ("Manifest parsing error: property 'name' ignored,"
158 " type string expected.",
163 TEST_F(ManifestParserTest
, ShortNameParseRules
) {
166 Manifest manifest
= ParseManifest("{ \"short_name\": \"foo\" }");
167 ASSERT_TRUE(EqualsASCII(manifest
.short_name
.string(), "foo"));
168 ASSERT_FALSE(manifest
.IsEmpty());
169 EXPECT_EQ(0u, GetErrorCount());
174 Manifest manifest
= ParseManifest("{ \"short_name\": \" foo \" }");
175 ASSERT_TRUE(EqualsASCII(manifest
.short_name
.string(), "foo"));
176 EXPECT_EQ(0u, GetErrorCount());
179 // Don't parse if name isn't a string.
181 Manifest manifest
= ParseManifest("{ \"short_name\": {} }");
182 ASSERT_TRUE(manifest
.short_name
.is_null());
183 EXPECT_EQ(1u, GetErrorCount());
184 EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
185 " type string expected.",
189 // Don't parse if name isn't a string.
191 Manifest manifest
= ParseManifest("{ \"short_name\": 42 }");
192 ASSERT_TRUE(manifest
.short_name
.is_null());
193 EXPECT_EQ(1u, GetErrorCount());
194 EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
195 " type string expected.",
200 TEST_F(ManifestParserTest
, StartURLParseRules
) {
203 Manifest manifest
= ParseManifest("{ \"start_url\": \"land.html\" }");
204 ASSERT_EQ(manifest
.start_url
.spec(),
205 default_document_url
.Resolve("land.html").spec());
206 ASSERT_FALSE(manifest
.IsEmpty());
207 EXPECT_EQ(0u, GetErrorCount());
212 Manifest manifest
= ParseManifest("{ \"start_url\": \" land.html \" }");
213 ASSERT_EQ(manifest
.start_url
.spec(),
214 default_document_url
.Resolve("land.html").spec());
215 EXPECT_EQ(0u, GetErrorCount());
218 // Don't parse if property isn't a string.
220 Manifest manifest
= ParseManifest("{ \"start_url\": {} }");
221 ASSERT_TRUE(manifest
.start_url
.is_empty());
222 EXPECT_EQ(1u, GetErrorCount());
223 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
224 " type string expected.",
228 // Don't parse if property isn't a string.
230 Manifest manifest
= ParseManifest("{ \"start_url\": 42 }");
231 ASSERT_TRUE(manifest
.start_url
.is_empty());
232 EXPECT_EQ(1u, GetErrorCount());
233 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
234 " type string expected.",
238 // Absolute start_url, same origin with document.
241 ParseManifestWithURLs("{ \"start_url\": \"http://foo.com/land.html\" }",
242 GURL("http://foo.com/manifest.json"),
243 GURL("http://foo.com/index.html"));
244 ASSERT_EQ(manifest
.start_url
.spec(), "http://foo.com/land.html");
245 EXPECT_EQ(0u, GetErrorCount());
248 // Absolute start_url, cross origin with document.
251 ParseManifestWithURLs("{ \"start_url\": \"http://bar.com/land.html\" }",
252 GURL("http://foo.com/manifest.json"),
253 GURL("http://foo.com/index.html"));
254 ASSERT_TRUE(manifest
.start_url
.is_empty());
255 EXPECT_EQ(1u, GetErrorCount());
256 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored, should "
257 "be same origin as document.",
261 // Resolving has to happen based on the manifest_url.
264 ParseManifestWithURLs("{ \"start_url\": \"land.html\" }",
265 GURL("http://foo.com/landing/manifest.json"),
266 GURL("http://foo.com/index.html"));
267 ASSERT_EQ(manifest
.start_url
.spec(), "http://foo.com/landing/land.html");
268 EXPECT_EQ(0u, GetErrorCount());
272 TEST_F(ManifestParserTest
, DisplayParserRules
) {
275 Manifest manifest
= ParseManifest("{ \"display\": \"browser\" }");
276 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_BROWSER
);
277 EXPECT_FALSE(manifest
.IsEmpty());
278 EXPECT_EQ(0u, GetErrorCount());
283 Manifest manifest
= ParseManifest("{ \"display\": \" browser \" }");
284 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_BROWSER
);
285 EXPECT_EQ(0u, GetErrorCount());
288 // Don't parse if name isn't a string.
290 Manifest manifest
= ParseManifest("{ \"display\": {} }");
291 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_UNSPECIFIED
);
292 EXPECT_EQ(1u, GetErrorCount());
293 EXPECT_EQ("Manifest parsing error: property 'display' ignored,"
294 " type string expected.",
298 // Don't parse if name isn't a string.
300 Manifest manifest
= ParseManifest("{ \"display\": 42 }");
301 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_UNSPECIFIED
);
302 EXPECT_EQ(1u, GetErrorCount());
303 EXPECT_EQ("Manifest parsing error: property 'display' ignored,"
304 " type string expected.",
308 // Parse fails if string isn't known.
310 Manifest manifest
= ParseManifest("{ \"display\": \"browser_something\" }");
311 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_UNSPECIFIED
);
312 EXPECT_EQ(1u, GetErrorCount());
313 EXPECT_EQ("Manifest parsing error: unknown 'display' value ignored.",
317 // Accept 'fullscreen'.
319 Manifest manifest
= ParseManifest("{ \"display\": \"fullscreen\" }");
320 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_FULLSCREEN
);
321 EXPECT_EQ(0u, GetErrorCount());
324 // Accept 'fullscreen'.
326 Manifest manifest
= ParseManifest("{ \"display\": \"standalone\" }");
327 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_STANDALONE
);
328 EXPECT_EQ(0u, GetErrorCount());
331 // Accept 'minimal-ui'.
333 Manifest manifest
= ParseManifest("{ \"display\": \"minimal-ui\" }");
334 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_MINIMAL_UI
);
335 EXPECT_EQ(0u, GetErrorCount());
340 Manifest manifest
= ParseManifest("{ \"display\": \"browser\" }");
341 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_BROWSER
);
342 EXPECT_EQ(0u, GetErrorCount());
347 Manifest manifest
= ParseManifest("{ \"display\": \"BROWSER\" }");
348 EXPECT_EQ(manifest
.display
, Manifest::DISPLAY_MODE_BROWSER
);
349 EXPECT_EQ(0u, GetErrorCount());
353 TEST_F(ManifestParserTest
, OrientationParserRules
) {
356 Manifest manifest
= ParseManifest("{ \"orientation\": \"natural\" }");
357 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockNatural
);
358 EXPECT_FALSE(manifest
.IsEmpty());
359 EXPECT_EQ(0u, GetErrorCount());
364 Manifest manifest
= ParseManifest("{ \"orientation\": \"natural\" }");
365 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockNatural
);
366 EXPECT_EQ(0u, GetErrorCount());
369 // Don't parse if name isn't a string.
371 Manifest manifest
= ParseManifest("{ \"orientation\": {} }");
372 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockDefault
);
373 EXPECT_EQ(1u, GetErrorCount());
374 EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
375 " type string expected.",
379 // Don't parse if name isn't a string.
381 Manifest manifest
= ParseManifest("{ \"orientation\": 42 }");
382 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockDefault
);
383 EXPECT_EQ(1u, GetErrorCount());
384 EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
385 " type string expected.",
389 // Parse fails if string isn't known.
391 Manifest manifest
= ParseManifest("{ \"orientation\": \"naturalish\" }");
392 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockDefault
);
393 EXPECT_EQ(1u, GetErrorCount());
394 EXPECT_EQ("Manifest parsing error: unknown 'orientation' value ignored.",
400 Manifest manifest
= ParseManifest("{ \"orientation\": \"any\" }");
401 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockAny
);
402 EXPECT_EQ(0u, GetErrorCount());
407 Manifest manifest
= ParseManifest("{ \"orientation\": \"natural\" }");
408 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockNatural
);
409 EXPECT_EQ(0u, GetErrorCount());
412 // Accept 'landscape'.
414 Manifest manifest
= ParseManifest("{ \"orientation\": \"landscape\" }");
415 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockLandscape
);
416 EXPECT_EQ(0u, GetErrorCount());
419 // Accept 'landscape-primary'.
422 ParseManifest("{ \"orientation\": \"landscape-primary\" }");
423 EXPECT_EQ(manifest
.orientation
,
424 blink::WebScreenOrientationLockLandscapePrimary
);
425 EXPECT_EQ(0u, GetErrorCount());
428 // Accept 'landscape-secondary'.
431 ParseManifest("{ \"orientation\": \"landscape-secondary\" }");
432 EXPECT_EQ(manifest
.orientation
,
433 blink::WebScreenOrientationLockLandscapeSecondary
);
434 EXPECT_EQ(0u, GetErrorCount());
437 // Accept 'portrait'.
439 Manifest manifest
= ParseManifest("{ \"orientation\": \"portrait\" }");
440 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockPortrait
);
441 EXPECT_EQ(0u, GetErrorCount());
444 // Accept 'portrait-primary'.
447 ParseManifest("{ \"orientation\": \"portrait-primary\" }");
448 EXPECT_EQ(manifest
.orientation
,
449 blink::WebScreenOrientationLockPortraitPrimary
);
450 EXPECT_EQ(0u, GetErrorCount());
453 // Accept 'portrait-secondary'.
456 ParseManifest("{ \"orientation\": \"portrait-secondary\" }");
457 EXPECT_EQ(manifest
.orientation
,
458 blink::WebScreenOrientationLockPortraitSecondary
);
459 EXPECT_EQ(0u, GetErrorCount());
464 Manifest manifest
= ParseManifest("{ \"orientation\": \"LANDSCAPE\" }");
465 EXPECT_EQ(manifest
.orientation
, blink::WebScreenOrientationLockLandscape
);
466 EXPECT_EQ(0u, GetErrorCount());
470 TEST_F(ManifestParserTest
, IconsParseRules
) {
471 // Smoke test: if no icon, empty list.
473 Manifest manifest
= ParseManifest("{ \"icons\": [] }");
474 EXPECT_EQ(manifest
.icons
.size(), 0u);
475 EXPECT_TRUE(manifest
.IsEmpty());
476 EXPECT_EQ(0u, GetErrorCount());
479 // Smoke test: if empty icon, empty list.
481 Manifest manifest
= ParseManifest("{ \"icons\": [ {} ] }");
482 EXPECT_EQ(manifest
.icons
.size(), 0u);
483 EXPECT_TRUE(manifest
.IsEmpty());
484 EXPECT_EQ(0u, GetErrorCount());
487 // Smoke test: icon with invalid src, empty list.
489 Manifest manifest
= ParseManifest("{ \"icons\": [ { \"icons\": [] } ] }");
490 EXPECT_EQ(manifest
.icons
.size(), 0u);
491 EXPECT_TRUE(manifest
.IsEmpty());
492 EXPECT_EQ(0u, GetErrorCount());
495 // Smoke test: if icon with empty src, it will be present in the list.
497 Manifest manifest
= ParseManifest("{ \"icons\": [ { \"src\": \"\" } ] }");
498 EXPECT_EQ(manifest
.icons
.size(), 1u);
499 EXPECT_EQ(manifest
.icons
[0].src
.spec(), "http://foo.com/index.html");
500 EXPECT_FALSE(manifest
.IsEmpty());
501 EXPECT_EQ(0u, GetErrorCount());
504 // Smoke test: if one icons with valid src, it will be present in the list.
507 ParseManifest("{ \"icons\": [{ \"src\": \"foo.jpg\" }] }");
508 EXPECT_EQ(manifest
.icons
.size(), 1u);
509 EXPECT_EQ(manifest
.icons
[0].src
.spec(), "http://foo.com/foo.jpg");
510 EXPECT_FALSE(manifest
.IsEmpty());
511 EXPECT_EQ(0u, GetErrorCount());
515 TEST_F(ManifestParserTest
, IconSrcParseRules
) {
519 ParseManifest("{ \"icons\": [ {\"src\": \"foo.png\" } ] }");
520 EXPECT_EQ(manifest
.icons
[0].src
.spec(),
521 default_document_url
.Resolve("foo.png").spec());
522 EXPECT_EQ(0u, GetErrorCount());
528 ParseManifest("{ \"icons\": [ {\"src\": \" foo.png \" } ] }");
529 EXPECT_EQ(manifest
.icons
[0].src
.spec(),
530 default_document_url
.Resolve("foo.png").spec());
531 EXPECT_EQ(0u, GetErrorCount());
534 // Don't parse if property isn't a string.
536 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": {} } ] }");
537 EXPECT_TRUE(manifest
.icons
.empty());
538 EXPECT_EQ(1u, GetErrorCount());
539 EXPECT_EQ("Manifest parsing error: property 'src' ignored,"
540 " type string expected.",
544 // Don't parse if property isn't a string.
546 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": 42 } ] }");
547 EXPECT_TRUE(manifest
.icons
.empty());
548 EXPECT_EQ(1u, GetErrorCount());
549 EXPECT_EQ("Manifest parsing error: property 'src' ignored,"
550 " type string expected.",
554 // Resolving has to happen based on the document_url.
556 Manifest manifest
= ParseManifestWithURLs(
557 "{ \"icons\": [ {\"src\": \"icons/foo.png\" } ] }",
558 GURL("http://foo.com/landing/index.html"),
559 default_manifest_url
);
560 EXPECT_EQ(manifest
.icons
[0].src
.spec(),
561 "http://foo.com/landing/icons/foo.png");
562 EXPECT_EQ(0u, GetErrorCount());
566 TEST_F(ManifestParserTest
, IconTypeParseRules
) {
570 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": \"foo\" } ] }");
571 EXPECT_TRUE(EqualsASCII(manifest
.icons
[0].type
.string(), "foo"));
572 EXPECT_EQ(0u, GetErrorCount());
577 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
578 " \"type\": \" foo \" } ] }");
579 EXPECT_TRUE(EqualsASCII(manifest
.icons
[0].type
.string(), "foo"));
580 EXPECT_EQ(0u, GetErrorCount());
583 // Don't parse if property isn't a string.
586 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": {} } ] }");
587 EXPECT_TRUE(manifest
.icons
[0].type
.is_null());
588 EXPECT_EQ(1u, GetErrorCount());
589 EXPECT_EQ("Manifest parsing error: property 'type' ignored,"
590 " type string expected.",
594 // Don't parse if property isn't a string.
597 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": 42 } ] }");
598 EXPECT_TRUE(manifest
.icons
[0].type
.is_null());
599 EXPECT_EQ(1u, GetErrorCount());
600 EXPECT_EQ("Manifest parsing error: property 'type' ignored,"
601 " type string expected.",
606 TEST_F(ManifestParserTest
, IconDensityParseRules
) {
610 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 42 } ] }");
611 EXPECT_EQ(manifest
.icons
[0].density
, 42);
612 EXPECT_EQ(0u, GetErrorCount());
618 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 2.5 } ] }");
619 EXPECT_EQ(manifest
.icons
[0].density
, 2.5);
620 EXPECT_EQ(0u, GetErrorCount());
623 // Parse fail if it isn't a float.
626 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": {} } ] }");
627 EXPECT_EQ(manifest
.icons
[0].density
, Manifest::Icon::kDefaultDensity
);
628 EXPECT_EQ(1u, GetErrorCount());
629 EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
630 "must be float greater than 0.",
634 // Parse fail if it isn't a float.
637 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\":\"2\" } ] }");
638 EXPECT_EQ(manifest
.icons
[0].density
, Manifest::Icon::kDefaultDensity
);
639 EXPECT_EQ(1u, GetErrorCount());
640 EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
641 "must be float greater than 0.",
648 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 1.00 } ] }");
649 EXPECT_EQ(manifest
.icons
[0].density
, 1);
650 EXPECT_EQ(0u, GetErrorCount());
653 // Edge case: values between 0.0 and 1.0 are allowed.
656 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 0.42 } ] }");
657 EXPECT_EQ(manifest
.icons
[0].density
, 0.42);
658 EXPECT_EQ(0u, GetErrorCount());
661 // 0 is an invalid value.
664 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 0.0 } ] }");
665 EXPECT_EQ(manifest
.icons
[0].density
, Manifest::Icon::kDefaultDensity
);
666 EXPECT_EQ(1u, GetErrorCount());
667 EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
668 "must be float greater than 0.",
672 // Negative values are invalid.
675 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": -2.5 } ] }");
676 EXPECT_EQ(manifest
.icons
[0].density
, Manifest::Icon::kDefaultDensity
);
677 EXPECT_EQ(1u, GetErrorCount());
678 EXPECT_EQ("Manifest parsing error: icon 'density' ignored, "
679 "must be float greater than 0.",
684 TEST_F(ManifestParserTest
, IconSizesParseRules
) {
687 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
688 "\"sizes\": \"42x42\" } ] }");
689 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 1u);
690 EXPECT_EQ(0u, GetErrorCount());
695 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
696 "\"sizes\": \" 42x42 \" } ] }");
697 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 1u);
698 EXPECT_EQ(0u, GetErrorCount());
701 // Ignore sizes if property isn't a string.
703 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
704 "\"sizes\": {} } ] }");
705 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 0u);
706 EXPECT_EQ(1u, GetErrorCount());
707 EXPECT_EQ("Manifest parsing error: property 'sizes' ignored,"
708 " type string expected.",
712 // Ignore sizes if property isn't a string.
714 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
715 "\"sizes\": 42 } ] }");
716 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 0u);
717 EXPECT_EQ(1u, GetErrorCount());
718 EXPECT_EQ("Manifest parsing error: property 'sizes' ignored,"
719 " type string expected.",
723 // Smoke test: value correctly parsed.
725 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
726 "\"sizes\": \"42x42 48x48\" } ] }");
727 EXPECT_EQ(manifest
.icons
[0].sizes
[0], gfx::Size(42, 42));
728 EXPECT_EQ(manifest
.icons
[0].sizes
[1], gfx::Size(48, 48));
729 EXPECT_EQ(0u, GetErrorCount());
732 // <WIDTH>'x'<HEIGHT> and <WIDTH>'X'<HEIGHT> are equivalent.
734 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
735 "\"sizes\": \"42X42 48X48\" } ] }");
736 EXPECT_EQ(manifest
.icons
[0].sizes
[0], gfx::Size(42, 42));
737 EXPECT_EQ(manifest
.icons
[0].sizes
[1], gfx::Size(48, 48));
738 EXPECT_EQ(0u, GetErrorCount());
741 // Twice the same value is parsed twice.
743 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
744 "\"sizes\": \"42X42 42x42\" } ] }");
745 EXPECT_EQ(manifest
.icons
[0].sizes
[0], gfx::Size(42, 42));
746 EXPECT_EQ(manifest
.icons
[0].sizes
[1], gfx::Size(42, 42));
747 EXPECT_EQ(0u, GetErrorCount());
750 // Width or height can't start with 0.
752 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
753 "\"sizes\": \"004X007 042x00\" } ] }");
754 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 0u);
755 EXPECT_EQ(1u, GetErrorCount());
756 EXPECT_EQ("Manifest parsing error: found icon with no valid size.",
760 // Width and height MUST contain digits.
762 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
763 "\"sizes\": \"e4X1.0 55ax1e10\" } ] }");
764 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 0u);
765 EXPECT_EQ(1u, GetErrorCount());
766 EXPECT_EQ("Manifest parsing error: found icon with no valid size.",
770 // 'any' is correctly parsed and transformed to gfx::Size(0,0).
772 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
773 "\"sizes\": \"any AnY ANY aNy\" } ] }");
774 gfx::Size any
= gfx::Size(0, 0);
775 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 4u);
776 EXPECT_EQ(manifest
.icons
[0].sizes
[0], any
);
777 EXPECT_EQ(manifest
.icons
[0].sizes
[1], any
);
778 EXPECT_EQ(manifest
.icons
[0].sizes
[2], any
);
779 EXPECT_EQ(manifest
.icons
[0].sizes
[3], any
);
780 EXPECT_EQ(0u, GetErrorCount());
783 // Some invalid width/height combinations.
785 Manifest manifest
= ParseManifest("{ \"icons\": [ {\"src\": \"\","
786 "\"sizes\": \"x 40xx 1x2x3 x42 42xx42\" } ] }");
787 gfx::Size any
= gfx::Size(0, 0);
788 EXPECT_EQ(manifest
.icons
[0].sizes
.size(), 0u);
789 EXPECT_EQ(1u, GetErrorCount());
790 EXPECT_EQ("Manifest parsing error: found icon with no valid size.",
795 TEST_F(ManifestParserTest
, RelatedApplicationsParseRules
) {
796 // If no application, empty list.
798 Manifest manifest
= ParseManifest(
799 "{ \"related_applications\": []}");
800 EXPECT_EQ(manifest
.related_applications
.size(), 0u);
801 EXPECT_TRUE(manifest
.IsEmpty());
802 EXPECT_EQ(0u, GetErrorCount());
805 // If empty application, empty list.
807 Manifest manifest
= ParseManifest(
808 "{ \"related_applications\": [{}]}");
809 EXPECT_EQ(manifest
.related_applications
.size(), 0u);
810 EXPECT_TRUE(manifest
.IsEmpty());
811 EXPECT_EQ(1u, GetErrorCount());
812 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
813 "related application ignored.",
817 // If invalid platform, application is ignored.
819 Manifest manifest
= ParseManifest(
820 "{ \"related_applications\": [{\"platform\": 123}]}");
821 EXPECT_EQ(manifest
.related_applications
.size(), 0u);
822 EXPECT_TRUE(manifest
.IsEmpty());
823 EXPECT_EQ(2u, GetErrorCount());
825 "Manifest parsing error: property 'platform' ignored, type string "
828 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
829 "related application ignored.",
833 // If missing platform, application is ignored.
835 Manifest manifest
= ParseManifest(
836 "{ \"related_applications\": [{\"id\": \"foo\"}]}");
837 EXPECT_EQ(manifest
.related_applications
.size(), 0u);
838 EXPECT_TRUE(manifest
.IsEmpty());
839 EXPECT_EQ(1u, GetErrorCount());
840 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
841 "related application ignored.",
845 // If missing id and url, application is ignored.
847 Manifest manifest
= ParseManifest(
848 "{ \"related_applications\": [{\"platform\": \"play\"}]}");
849 EXPECT_EQ(manifest
.related_applications
.size(), 0u);
850 EXPECT_TRUE(manifest
.IsEmpty());
851 EXPECT_EQ(1u, GetErrorCount());
852 EXPECT_EQ("Manifest parsing error: one of 'url' or 'id' is required, "
853 "related application ignored.",
857 // Valid application, with url.
859 Manifest manifest
= ParseManifest(
860 "{ \"related_applications\": ["
861 "{\"platform\": \"play\", \"url\": \"http://www.foo.com\"}]}");
862 EXPECT_EQ(manifest
.related_applications
.size(), 1u);
863 EXPECT_TRUE(EqualsASCII(manifest
.related_applications
[0].platform
.string(),
865 EXPECT_EQ(manifest
.related_applications
[0].url
.spec(),
866 "http://www.foo.com/");
867 EXPECT_FALSE(manifest
.IsEmpty());
868 EXPECT_EQ(0u, GetErrorCount());
871 // Valid application, with id.
873 Manifest manifest
= ParseManifest(
874 "{ \"related_applications\": ["
875 "{\"platform\": \"itunes\", \"id\": \"foo\"}]}");
876 EXPECT_EQ(manifest
.related_applications
.size(), 1u);
877 EXPECT_TRUE(EqualsASCII(manifest
.related_applications
[0].platform
.string(),
879 EXPECT_TRUE(EqualsASCII(manifest
.related_applications
[0].id
.string(),
881 EXPECT_FALSE(manifest
.IsEmpty());
882 EXPECT_EQ(0u, GetErrorCount());
885 // All valid applications are in list.
887 Manifest manifest
= ParseManifest(
888 "{ \"related_applications\": ["
889 "{\"platform\": \"play\", \"id\": \"foo\"},"
890 "{\"platform\": \"itunes\", \"id\": \"bar\"}]}");
891 EXPECT_EQ(manifest
.related_applications
.size(), 2u);
892 EXPECT_TRUE(EqualsASCII(manifest
.related_applications
[0].platform
.string(),
894 EXPECT_TRUE(EqualsASCII(manifest
.related_applications
[0].id
.string(),
896 EXPECT_TRUE(EqualsASCII(manifest
.related_applications
[1].platform
.string(),
898 EXPECT_TRUE(EqualsASCII(manifest
.related_applications
[1].id
.string(),
900 EXPECT_FALSE(manifest
.IsEmpty());
901 EXPECT_EQ(0u, GetErrorCount());
904 // Two invalid applications and one valid. Only the valid application should
907 Manifest manifest
= ParseManifest(
908 "{ \"related_applications\": ["
909 "{\"platform\": \"itunes\"},"
910 "{\"platform\": \"play\", \"id\": \"foo\"},"
912 EXPECT_EQ(manifest
.related_applications
.size(), 1u);
913 EXPECT_TRUE(EqualsASCII(manifest
.related_applications
[0].platform
.string(),
915 EXPECT_TRUE(EqualsASCII(manifest
.related_applications
[0].id
.string(),
917 EXPECT_FALSE(manifest
.IsEmpty());
918 EXPECT_EQ(2u, GetErrorCount());
919 EXPECT_EQ("Manifest parsing error: one of 'url' or 'id' is required, "
920 "related application ignored.",
922 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
923 "related application ignored.",
928 TEST_F(ManifestParserTest
, ParsePreferRelatedApplicationsParseRules
) {
932 ParseManifest("{ \"prefer_related_applications\": true }");
933 EXPECT_TRUE(manifest
.prefer_related_applications
);
934 EXPECT_EQ(0u, GetErrorCount());
937 // Don't parse if the property isn't a boolean.
940 ParseManifest("{ \"prefer_related_applications\": {} }");
941 EXPECT_FALSE(manifest
.prefer_related_applications
);
942 EXPECT_EQ(1u, GetErrorCount());
944 "Manifest parsing error: property 'prefer_related_applications' "
945 "ignored, type boolean expected.",
949 Manifest manifest
= ParseManifest(
950 "{ \"prefer_related_applications\": \"true\" }");
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("{ \"prefer_related_applications\": 1 }");
960 EXPECT_FALSE(manifest
.prefer_related_applications
);
961 EXPECT_EQ(1u, GetErrorCount());
963 "Manifest parsing error: property 'prefer_related_applications' "
964 "ignored, type boolean expected.",
968 // "False" should set the boolean false without throwing errors.
971 ParseManifest("{ \"prefer_related_applications\": false }");
972 EXPECT_FALSE(manifest
.prefer_related_applications
);
973 EXPECT_EQ(0u, GetErrorCount());
977 TEST_F(ManifestParserTest
, GCMSenderIDParseRules
) {
980 Manifest manifest
= ParseManifest("{ \"gcm_sender_id\": \"foo\" }");
981 EXPECT_TRUE(EqualsASCII(manifest
.gcm_sender_id
.string(), "foo"));
982 EXPECT_EQ(0u, GetErrorCount());
987 Manifest manifest
= ParseManifest("{ \"gcm_sender_id\": \" foo \" }");
988 EXPECT_TRUE(EqualsASCII(manifest
.gcm_sender_id
.string(), "foo"));
989 EXPECT_EQ(0u, GetErrorCount());
992 // Don't parse if the property isn't a string.
994 Manifest manifest
= ParseManifest("{ \"gcm_sender_id\": {} }");
995 EXPECT_TRUE(manifest
.gcm_sender_id
.is_null());
996 EXPECT_EQ(1u, GetErrorCount());
997 EXPECT_EQ("Manifest parsing error: property 'gcm_sender_id' ignored,"
998 " type string expected.",
1002 Manifest manifest
= ParseManifest("{ \"gcm_sender_id\": 42 }");
1003 EXPECT_TRUE(manifest
.gcm_sender_id
.is_null());
1004 EXPECT_EQ(1u, GetErrorCount());
1005 EXPECT_EQ("Manifest parsing error: property 'gcm_sender_id' ignored,"
1006 " type string expected.",
1011 } // namespace content