Fix a couple bugs in the settings_page_header wrt breadcrumbs.
[chromium-blink-merge.git] / content / renderer / manifest / manifest_parser_unittest.cc
blob948d5500aa7cbaf768132063461fbc87e15d21cf
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_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,"
103 "\"icons\": {} }");
105 EXPECT_EQ(6u, GetErrorCount());
107 EXPECT_EQ("Manifest parsing error: property 'name' ignored,"
108 " type string expected.",
109 errors()[0]);
110 EXPECT_EQ("Manifest parsing error: property 'short_name' ignored,"
111 " type string expected.",
112 errors()[1]);
113 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored,"
114 " type string expected.",
115 errors()[2]);
116 EXPECT_EQ("Manifest parsing error: unknown 'display' value ignored.",
117 errors()[3]);
118 EXPECT_EQ("Manifest parsing error: property 'orientation' ignored,"
119 " type string expected.",
120 errors()[4]);
121 EXPECT_EQ("Manifest parsing error: property 'icons' ignored, "
122 "type array expected.",
123 errors()[5]);
126 TEST_F(ManifestParserTest, NameParseRules) {
127 // Smoke test.
129 Manifest manifest = ParseManifest("{ \"name\": \"foo\" }");
130 ASSERT_TRUE(EqualsASCII(manifest.name.string(), "foo"));
131 ASSERT_FALSE(manifest.IsEmpty());
132 EXPECT_EQ(0u, GetErrorCount());
135 // Trim whitespaces.
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.",
149 errors()[0]);
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.",
159 errors()[0]);
163 TEST_F(ManifestParserTest, ShortNameParseRules) {
164 // Smoke test.
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());
172 // Trim whitespaces.
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.",
186 errors()[0]);
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.",
196 errors()[0]);
200 TEST_F(ManifestParserTest, StartURLParseRules) {
201 // Smoke test.
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());
210 // Whitespaces.
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.",
225 errors()[0]);
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.",
235 errors()[0]);
238 // Absolute start_url, same origin with document.
240 Manifest manifest =
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.
250 Manifest manifest =
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.",
258 errors()[0]);
261 // Resolving has to happen based on the manifest_url.
263 Manifest manifest =
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) {
273 // Smoke test.
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());
281 // Trim whitespaces.
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.",
295 errors()[0]);
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.",
305 errors()[0]);
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.",
314 errors()[0]);
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());
338 // Accept 'browser'.
340 Manifest manifest = ParseManifest("{ \"display\": \"browser\" }");
341 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_BROWSER);
342 EXPECT_EQ(0u, GetErrorCount());
345 // Case insensitive.
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) {
354 // Smoke test.
356 Manifest manifest = ParseManifest("{ \"orientation\": \"natural\" }");
357 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockNatural);
358 EXPECT_FALSE(manifest.IsEmpty());
359 EXPECT_EQ(0u, GetErrorCount());
362 // Trim whitespaces.
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.",
376 errors()[0]);
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.",
386 errors()[0]);
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.",
395 errors()[0]);
398 // Accept 'any'.
400 Manifest manifest = ParseManifest("{ \"orientation\": \"any\" }");
401 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockAny);
402 EXPECT_EQ(0u, GetErrorCount());
405 // Accept 'natural'.
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'.
421 Manifest manifest =
422 ParseManifest("{ \"orientation\": \"landscape-primary\" }");
423 EXPECT_EQ(manifest.orientation,
424 blink::WebScreenOrientationLockLandscapePrimary);
425 EXPECT_EQ(0u, GetErrorCount());
428 // Accept 'landscape-secondary'.
430 Manifest manifest =
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'.
446 Manifest manifest =
447 ParseManifest("{ \"orientation\": \"portrait-primary\" }");
448 EXPECT_EQ(manifest.orientation,
449 blink::WebScreenOrientationLockPortraitPrimary);
450 EXPECT_EQ(0u, GetErrorCount());
453 // Accept 'portrait-secondary'.
455 Manifest manifest =
456 ParseManifest("{ \"orientation\": \"portrait-secondary\" }");
457 EXPECT_EQ(manifest.orientation,
458 blink::WebScreenOrientationLockPortraitSecondary);
459 EXPECT_EQ(0u, GetErrorCount());
462 // Case insensitive.
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.
506 Manifest manifest =
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) {
516 // Smoke test.
518 Manifest manifest =
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());
525 // Whitespaces.
527 Manifest manifest =
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.",
541 errors()[0]);
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.",
551 errors()[0]);
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) {
567 // Smoke test.
569 Manifest manifest =
570 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": \"foo\" } ] }");
571 EXPECT_TRUE(EqualsASCII(manifest.icons[0].type.string(), "foo"));
572 EXPECT_EQ(0u, GetErrorCount());
575 // Trim whitespaces.
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.
585 Manifest manifest =
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.",
591 errors()[0]);
594 // Don't parse if property isn't a string.
596 Manifest manifest =
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.",
602 errors()[0]);
606 TEST_F(ManifestParserTest, IconDensityParseRules) {
607 // Smoke test.
609 Manifest manifest =
610 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 42 } ] }");
611 EXPECT_EQ(manifest.icons[0].density, 42);
612 EXPECT_EQ(0u, GetErrorCount());
615 // Decimal value.
617 Manifest manifest =
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.
625 Manifest manifest =
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.",
631 errors()[0]);
634 // Parse fail if it isn't a float.
636 Manifest manifest =
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.",
642 errors()[0]);
645 // Edge case: 1.0.
647 Manifest manifest =
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.
655 Manifest manifest =
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.
663 Manifest manifest =
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.",
669 errors()[0]);
672 // Negative values are invalid.
674 Manifest manifest =
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.",
680 errors()[0]);
684 TEST_F(ManifestParserTest, IconSizesParseRules) {
685 // Smoke test.
687 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
688 "\"sizes\": \"42x42\" } ] }");
689 EXPECT_EQ(manifest.icons[0].sizes.size(), 1u);
690 EXPECT_EQ(0u, GetErrorCount());
693 // Trim whitespaces.
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.",
709 errors()[0]);
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.",
720 errors()[0]);
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.",
757 errors()[0]);
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.",
767 errors()[0]);
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.",
791 errors()[0]);
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.",
814 errors()[0]);
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());
824 EXPECT_EQ(
825 "Manifest parsing error: property 'platform' ignored, type string "
826 "expected.",
827 errors()[0]);
828 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
829 "related application ignored.",
830 errors()[1]);
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.",
842 errors()[0]);
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.",
854 errors()[0]);
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(),
864 "play"));
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(),
878 "itunes"));
879 EXPECT_TRUE(EqualsASCII(manifest.related_applications[0].id.string(),
880 "foo"));
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(),
893 "play"));
894 EXPECT_TRUE(EqualsASCII(manifest.related_applications[0].id.string(),
895 "foo"));
896 EXPECT_TRUE(EqualsASCII(manifest.related_applications[1].platform.string(),
897 "itunes"));
898 EXPECT_TRUE(EqualsASCII(manifest.related_applications[1].id.string(),
899 "bar"));
900 EXPECT_FALSE(manifest.IsEmpty());
901 EXPECT_EQ(0u, GetErrorCount());
904 // Two invalid applications and one valid. Only the valid application should
905 // be in the list.
907 Manifest manifest = ParseManifest(
908 "{ \"related_applications\": ["
909 "{\"platform\": \"itunes\"},"
910 "{\"platform\": \"play\", \"id\": \"foo\"},"
911 "{}]}");
912 EXPECT_EQ(manifest.related_applications.size(), 1u);
913 EXPECT_TRUE(EqualsASCII(manifest.related_applications[0].platform.string(),
914 "play"));
915 EXPECT_TRUE(EqualsASCII(manifest.related_applications[0].id.string(),
916 "foo"));
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.",
921 errors()[0]);
922 EXPECT_EQ("Manifest parsing error: 'platform' is a required field, "
923 "related application ignored.",
924 errors()[1]);
928 TEST_F(ManifestParserTest, ParsePreferRelatedApplicationsParseRules) {
929 // Smoke test.
931 Manifest manifest =
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.
939 Manifest manifest =
940 ParseManifest("{ \"prefer_related_applications\": {} }");
941 EXPECT_FALSE(manifest.prefer_related_applications);
942 EXPECT_EQ(1u, GetErrorCount());
943 EXPECT_EQ(
944 "Manifest parsing error: property 'prefer_related_applications' "
945 "ignored, type boolean expected.",
946 errors()[0]);
949 Manifest manifest = ParseManifest(
950 "{ \"prefer_related_applications\": \"true\" }");
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("{ \"prefer_related_applications\": 1 }");
960 EXPECT_FALSE(manifest.prefer_related_applications);
961 EXPECT_EQ(1u, GetErrorCount());
962 EXPECT_EQ(
963 "Manifest parsing error: property 'prefer_related_applications' "
964 "ignored, type boolean expected.",
965 errors()[0]);
968 // "False" should set the boolean false without throwing errors.
970 Manifest manifest =
971 ParseManifest("{ \"prefer_related_applications\": false }");
972 EXPECT_FALSE(manifest.prefer_related_applications);
973 EXPECT_EQ(0u, GetErrorCount());
977 TEST_F(ManifestParserTest, GCMSenderIDParseRules) {
978 // Smoke test.
980 Manifest manifest = ParseManifest("{ \"gcm_sender_id\": \"foo\" }");
981 EXPECT_TRUE(EqualsASCII(manifest.gcm_sender_id.string(), "foo"));
982 EXPECT_EQ(0u, GetErrorCount());
985 // Trim whitespaces.
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.",
999 errors()[0]);
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.",
1007 errors()[0]);
1011 } // namespace content