Add ICU message format support
[chromium-blink-merge.git] / content / renderer / manifest / manifest_parser_unittest.cc
blob1d6793ca3312eeca9b2fda3dbe11c86991429bea
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"
11 namespace content {
13 class ManifestParserTest : public testing::Test {
14 protected:
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);
22 parser.Parse();
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 {
33 return errors_;
36 unsigned int GetErrorCount() const {
37 return errors_.size();
40 static const GURL default_document_url;
41 static const GURL default_manifest_url;
43 private:
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"));
59 parser.Parse();
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.",
72 errors()[0]);
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.",
111 errors()[0]);
112 EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
113 " type string expected.",
114 errors()[1]);
115 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
116 " type string expected.",
117 errors()[2]);
118 EXPECT_EQ("Manifest parsing error: unknown 'display' value ignored.",
119 errors()[3]);
120 EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
121 " type string expected.",
122 errors()[4]);
123 EXPECT_EQ("Manifest parsing error: property 'icons' ignored, "
124 "type array expected.",
125 errors()[5]);
126 EXPECT_EQ("Manifest parsing error: property 'theme_color' ignored,"
127 " type string expected.",
128 errors()[6]);
131 TEST_F(ManifestParserTest, NameParseRules) {
132 // Smoke test.
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());
140 // Trim whitespaces.
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.",
154 errors()[0]);
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.",
164 errors()[0]);
168 TEST_F(ManifestParserTest, ShortNameParseRules) {
169 // Smoke test.
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());
177 // Trim whitespaces.
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.",
191 errors()[0]);
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.",
201 errors()[0]);
205 TEST_F(ManifestParserTest, StartURLParseRules) {
206 // Smoke test.
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());
215 // Whitespaces.
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.",
230 errors()[0]);
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.",
240 errors()[0]);
243 // Absolute start_url, same origin with document.
245 Manifest manifest =
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.
255 Manifest manifest =
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.",
263 errors()[0]);
266 // Resolving has to happen based on the manifest_url.
268 Manifest manifest =
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) {
278 // Smoke test.
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());
286 // Trim whitespaces.
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.",
300 errors()[0]);
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.",
310 errors()[0]);
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.",
319 errors()[0]);
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());
343 // Accept 'browser'.
345 Manifest manifest = ParseManifest("{ \"display\": \"browser\" }");
346 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_BROWSER);
347 EXPECT_EQ(0u, GetErrorCount());
350 // Case insensitive.
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) {
359 // Smoke test.
361 Manifest manifest = ParseManifest("{ \"orientation\": \"natural\" }");
362 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockNatural);
363 EXPECT_FALSE(manifest.IsEmpty());
364 EXPECT_EQ(0u, GetErrorCount());
367 // Trim whitespaces.
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.",
381 errors()[0]);
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.",
391 errors()[0]);
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.",
400 errors()[0]);
403 // Accept 'any'.
405 Manifest manifest = ParseManifest("{ \"orientation\": \"any\" }");
406 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockAny);
407 EXPECT_EQ(0u, GetErrorCount());
410 // Accept 'natural'.
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'.
426 Manifest manifest =
427 ParseManifest("{ \"orientation\": \"landscape-primary\" }");
428 EXPECT_EQ(manifest.orientation,
429 blink::WebScreenOrientationLockLandscapePrimary);
430 EXPECT_EQ(0u, GetErrorCount());
433 // Accept 'landscape-secondary'.
435 Manifest manifest =
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'.
451 Manifest manifest =
452 ParseManifest("{ \"orientation\": \"portrait-primary\" }");
453 EXPECT_EQ(manifest.orientation,
454 blink::WebScreenOrientationLockPortraitPrimary);
455 EXPECT_EQ(0u, GetErrorCount());
458 // Accept 'portrait-secondary'.
460 Manifest manifest =
461 ParseManifest("{ \"orientation\": \"portrait-secondary\" }");
462 EXPECT_EQ(manifest.orientation,
463 blink::WebScreenOrientationLockPortraitSecondary);
464 EXPECT_EQ(0u, GetErrorCount());
467 // Case insensitive.
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.
511 Manifest manifest =
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) {
521 // Smoke test.
523 Manifest manifest =
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());
530 // Whitespaces.
532 Manifest manifest =
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.",
546 errors()[0]);
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.",
556 errors()[0]);
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) {
572 // Smoke test.
574 Manifest manifest =
575 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": \"foo\" } ] }");
576 EXPECT_TRUE(base::EqualsASCII(manifest.icons[0].type.string(), "foo"));
577 EXPECT_EQ(0u, GetErrorCount());
580 // Trim whitespaces.
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.
590 Manifest manifest =
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.",
596 errors()[0]);
599 // Don't parse if property isn't a string.
601 Manifest manifest =
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.",
607 errors()[0]);
611 TEST_F(ManifestParserTest, IconDensityParseRules) {
612 // Smoke test.
614 Manifest manifest =
615 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 42 } ] }");
616 EXPECT_EQ(manifest.icons[0].density, 42);
617 EXPECT_EQ(0u, GetErrorCount());
620 // Decimal value.
622 Manifest manifest =
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.
630 Manifest manifest =
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.",
636 errors()[0]);
639 // Parse fail if it isn't a float.
641 Manifest manifest =
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.",
647 errors()[0]);
650 // Edge case: 1.0.
652 Manifest manifest =
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.
660 Manifest manifest =
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.
668 Manifest manifest =
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.",
674 errors()[0]);
677 // Negative values are invalid.
679 Manifest manifest =
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.",
685 errors()[0]);
689 TEST_F(ManifestParserTest, IconSizesParseRules) {
690 // Smoke test.
692 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
693 "\"sizes\": \"42x42\" } ] }");
694 EXPECT_EQ(manifest.icons[0].sizes.size(), 1u);
695 EXPECT_EQ(0u, GetErrorCount());
698 // Trim whitespaces.
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.",
714 errors()[0]);
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.",
725 errors()[0]);
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.",
762 errors()[0]);
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.",
772 errors()[0]);
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.",
796 errors()[0]);
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.",
819 errors()[0]);
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());
829 EXPECT_EQ(
830 "Manifest parsing error: property 'platform' ignored, type string "
831 "expected.",
832 errors()[0]);
833 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
834 "related application ignored.",
835 errors()[1]);
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.",
847 errors()[0]);
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.",
859 errors()[0]);
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(),
870 "play"));
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(),
885 "itunes"));
886 EXPECT_TRUE(base::EqualsASCII(manifest.related_applications[0].id.string(),
887 "foo"));
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(),
901 "play"));
902 EXPECT_TRUE(base::EqualsASCII(manifest.related_applications[0].id.string(),
903 "foo"));
904 EXPECT_TRUE(base::EqualsASCII(
905 manifest.related_applications[1].platform.string(),
906 "itunes"));
907 EXPECT_TRUE(base::EqualsASCII(manifest.related_applications[1].id.string(),
908 "bar"));
909 EXPECT_FALSE(manifest.IsEmpty());
910 EXPECT_EQ(0u, GetErrorCount());
913 // Two invalid applications and one valid. Only the valid application should
914 // be in the list.
916 Manifest manifest = ParseManifest(
917 "{ \"related_applications\": ["
918 "{\"platform\": \"itunes\"},"
919 "{\"platform\": \"play\", \"id\": \"foo\"},"
920 "{}]}");
921 EXPECT_EQ(manifest.related_applications.size(), 1u);
922 EXPECT_TRUE(base::EqualsASCII(
923 manifest.related_applications[0].platform.string(),
924 "play"));
925 EXPECT_TRUE(base::EqualsASCII(manifest.related_applications[0].id.string(),
926 "foo"));
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.",
931 errors()[0]);
932 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
933 "related application ignored.",
934 errors()[1]);
938 TEST_F(ManifestParserTest, ParsePreferRelatedApplicationsParseRules) {
939 // Smoke test.
941 Manifest manifest =
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.
949 Manifest manifest =
950 ParseManifest("{ \"prefer_related_applications\": {} }");
951 EXPECT_FALSE(manifest.prefer_related_applications);
952 EXPECT_EQ(1u, GetErrorCount());
953 EXPECT_EQ(
954 "Manifest parsing error: property 'prefer_related_applications' "
955 "ignored, type boolean expected.",
956 errors()[0]);
959 Manifest manifest = ParseManifest(
960 "{ \"prefer_related_applications\": \"true\" }");
961 EXPECT_FALSE(manifest.prefer_related_applications);
962 EXPECT_EQ(1u, GetErrorCount());
963 EXPECT_EQ(
964 "Manifest parsing error: property 'prefer_related_applications' "
965 "ignored, type boolean expected.",
966 errors()[0]);
969 Manifest manifest = ParseManifest("{ \"prefer_related_applications\": 1 }");
970 EXPECT_FALSE(manifest.prefer_related_applications);
971 EXPECT_EQ(1u, GetErrorCount());
972 EXPECT_EQ(
973 "Manifest parsing error: property 'prefer_related_applications' "
974 "ignored, type boolean expected.",
975 errors()[0]);
978 // "False" should set the boolean false without throwing errors.
980 Manifest manifest =
981 ParseManifest("{ \"prefer_related_applications\": false }");
982 EXPECT_FALSE(manifest.prefer_related_applications);
983 EXPECT_EQ(0u, GetErrorCount());
987 TEST_F(ManifestParserTest, ThemeColorParserRules) {
988 // Smoke test.
990 Manifest manifest = ParseManifest("{ \"theme_color\": \"#FF0000\" }");
991 EXPECT_EQ(manifest.theme_color, 0xFFFF0000);
992 EXPECT_FALSE(manifest.IsEmpty());
993 EXPECT_EQ(0u, GetErrorCount());
996 // Trim whitespaces.
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.",
1010 errors()[0]);
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.",
1020 errors()[0]);
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.",
1030 errors()[0]);
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.",
1040 errors()[0]);
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.",
1050 errors()[0]);
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.",
1060 errors()[0]);
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.",
1070 errors()[0]);
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.",
1080 errors()[0]);
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.",
1090 errors()[0]);
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.",
1101 errors()[0]);
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) {
1141 // Smoke test.
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.",
1162 errors()[0]);
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.",
1170 errors()[0]);
1174 } // namespace content