cc: Make picture pile base thread safe.
[chromium-blink-merge.git] / content / renderer / manifest / manifest_parser_unittest.cc
blob72127560a3e0fbee7c1e8098f8abaa05e3aab5b6
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 virtual ~ManifestParserTest() {}
18 Manifest ParseManifest(const base::StringPiece& json,
19 const GURL& document_url = default_document_url,
20 const GURL& manifest_url = default_manifest_url) {
21 return ManifestParser::Parse(json, document_url, manifest_url);
24 static const GURL default_document_url;
25 static const GURL default_manifest_url;
27 private:
28 DISALLOW_COPY_AND_ASSIGN(ManifestParserTest);
31 const GURL ManifestParserTest::default_document_url(
32 "http://foo.com/index.html");
33 const GURL ManifestParserTest::default_manifest_url(
34 "http://foo.com/manifest.json");
36 TEST_F(ManifestParserTest, EmptyStringNull) {
37 Manifest manifest = ParseManifest("");
39 // A parsing error is equivalent to an empty manifest.
40 ASSERT_TRUE(manifest.IsEmpty());
41 ASSERT_TRUE(manifest.name.is_null());
42 ASSERT_TRUE(manifest.short_name.is_null());
43 ASSERT_TRUE(manifest.start_url.is_empty());
44 ASSERT_EQ(manifest.display, Manifest::DISPLAY_MODE_UNSPECIFIED);
45 ASSERT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault);
48 TEST_F(ManifestParserTest, ValidNoContentParses) {
49 Manifest manifest = ParseManifest("{}");
51 // Check that all the fields are null in that case.
52 ASSERT_TRUE(manifest.IsEmpty());
53 ASSERT_TRUE(manifest.name.is_null());
54 ASSERT_TRUE(manifest.short_name.is_null());
55 ASSERT_TRUE(manifest.start_url.is_empty());
56 ASSERT_EQ(manifest.display, Manifest::DISPLAY_MODE_UNSPECIFIED);
57 ASSERT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault);
60 TEST_F(ManifestParserTest, NameParseRules) {
61 // Smoke test.
63 Manifest manifest = ParseManifest("{ \"name\": \"foo\" }");
64 ASSERT_TRUE(EqualsASCII(manifest.name.string(), "foo"));
65 ASSERT_FALSE(manifest.IsEmpty());
68 // Trim whitespaces.
70 Manifest manifest = ParseManifest("{ \"name\": \" foo \" }");
71 ASSERT_TRUE(EqualsASCII(manifest.name.string(), "foo"));
74 // Don't parse if name isn't a string.
76 Manifest manifest = ParseManifest("{ \"name\": {} }");
77 ASSERT_TRUE(manifest.name.is_null());
80 // Don't parse if name isn't a string.
82 Manifest manifest = ParseManifest("{ \"name\": 42 }");
83 ASSERT_TRUE(manifest.name.is_null());
87 TEST_F(ManifestParserTest, ShortNameParseRules) {
88 // Smoke test.
90 Manifest manifest = ParseManifest("{ \"short_name\": \"foo\" }");
91 ASSERT_TRUE(EqualsASCII(manifest.short_name.string(), "foo"));
92 ASSERT_FALSE(manifest.IsEmpty());
95 // Trim whitespaces.
97 Manifest manifest = ParseManifest("{ \"short_name\": \" foo \" }");
98 ASSERT_TRUE(EqualsASCII(manifest.short_name.string(), "foo"));
101 // Don't parse if name isn't a string.
103 Manifest manifest = ParseManifest("{ \"short_name\": {} }");
104 ASSERT_TRUE(manifest.short_name.is_null());
107 // Don't parse if name isn't a string.
109 Manifest manifest = ParseManifest("{ \"short_name\": 42 }");
110 ASSERT_TRUE(manifest.short_name.is_null());
114 TEST_F(ManifestParserTest, StartURLParseRules) {
115 // Smoke test.
117 Manifest manifest = ParseManifest("{ \"start_url\": \"land.html\" }");
118 ASSERT_EQ(manifest.start_url.spec(),
119 default_document_url.Resolve("land.html").spec());
120 ASSERT_FALSE(manifest.IsEmpty());
123 // Whitespaces.
125 Manifest manifest = ParseManifest("{ \"start_url\": \" land.html \" }");
126 ASSERT_EQ(manifest.start_url.spec(),
127 default_document_url.Resolve("land.html").spec());
130 // Don't parse if property isn't a string.
132 Manifest manifest = ParseManifest("{ \"start_url\": {} }");
133 ASSERT_TRUE(manifest.start_url.is_empty());
136 // Don't parse if property isn't a string.
138 Manifest manifest = ParseManifest("{ \"start_url\": 42 }");
139 ASSERT_TRUE(manifest.start_url.is_empty());
142 // Absolute start_url, same origin with document.
144 Manifest manifest =
145 ParseManifest("{ \"start_url\": \"http://foo.com/land.html\" }",
146 GURL("http://foo.com/manifest.json"),
147 GURL("http://foo.com/index.html"));
148 ASSERT_EQ(manifest.start_url.spec(), "http://foo.com/land.html");
151 // Absolute start_url, cross origin with document.
153 Manifest manifest =
154 ParseManifest("{ \"start_url\": \"http://bar.com/land.html\" }",
155 GURL("http://foo.com/manifest.json"),
156 GURL("http://foo.com/index.html"));
157 ASSERT_TRUE(manifest.start_url.is_empty());
160 // Resolving has to happen based on the manifest_url.
162 Manifest manifest =
163 ParseManifest("{ \"start_url\": \"land.html\" }",
164 GURL("http://foo.com/landing/manifest.json"),
165 GURL("http://foo.com/index.html"));
166 ASSERT_EQ(manifest.start_url.spec(), "http://foo.com/landing/land.html");
170 TEST_F(ManifestParserTest, DisplayParserRules) {
171 // Smoke test.
173 Manifest manifest = ParseManifest("{ \"display\": \"browser\" }");
174 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_BROWSER);
175 EXPECT_FALSE(manifest.IsEmpty());
178 // Trim whitespaces.
180 Manifest manifest = ParseManifest("{ \"display\": \" browser \" }");
181 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_BROWSER);
184 // Don't parse if name isn't a string.
186 Manifest manifest = ParseManifest("{ \"display\": {} }");
187 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_UNSPECIFIED);
190 // Don't parse if name isn't a string.
192 Manifest manifest = ParseManifest("{ \"display\": 42 }");
193 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_UNSPECIFIED);
196 // Parse fails if string isn't known.
198 Manifest manifest = ParseManifest("{ \"display\": \"browser_something\" }");
199 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_UNSPECIFIED);
202 // Accept 'fullscreen'.
204 Manifest manifest = ParseManifest("{ \"display\": \"fullscreen\" }");
205 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_FULLSCREEN);
208 // Accept 'fullscreen'.
210 Manifest manifest = ParseManifest("{ \"display\": \"standalone\" }");
211 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_STANDALONE);
214 // Accept 'minimal-ui'.
216 Manifest manifest = ParseManifest("{ \"display\": \"minimal-ui\" }");
217 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_MINIMAL_UI);
220 // Accept 'browser'.
222 Manifest manifest = ParseManifest("{ \"display\": \"browser\" }");
223 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_BROWSER);
226 // Case insensitive.
228 Manifest manifest = ParseManifest("{ \"display\": \"BROWSER\" }");
229 EXPECT_EQ(manifest.display, Manifest::DISPLAY_MODE_BROWSER);
233 TEST_F(ManifestParserTest, OrientationParserRules) {
234 // Smoke test.
236 Manifest manifest = ParseManifest("{ \"orientation\": \"natural\" }");
237 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockNatural);
238 EXPECT_FALSE(manifest.IsEmpty());
241 // Trim whitespaces.
243 Manifest manifest = ParseManifest("{ \"orientation\": \"natural\" }");
244 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockNatural);
247 // Don't parse if name isn't a string.
249 Manifest manifest = ParseManifest("{ \"orientation\": {} }");
250 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault);
253 // Don't parse if name isn't a string.
255 Manifest manifest = ParseManifest("{ \"orientation\": 42 }");
256 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault);
259 // Parse fails if string isn't known.
261 Manifest manifest = ParseManifest("{ \"orientation\": \"naturalish\" }");
262 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault);
265 // Accept 'any'.
267 Manifest manifest = ParseManifest("{ \"orientation\": \"any\" }");
268 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockAny);
271 // Accept 'natural'.
273 Manifest manifest = ParseManifest("{ \"orientation\": \"natural\" }");
274 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockNatural);
277 // Accept 'landscape'.
279 Manifest manifest = ParseManifest("{ \"orientation\": \"landscape\" }");
280 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockLandscape);
283 // Accept 'landscape-primary'.
285 Manifest manifest =
286 ParseManifest("{ \"orientation\": \"landscape-primary\" }");
287 EXPECT_EQ(manifest.orientation,
288 blink::WebScreenOrientationLockLandscapePrimary);
291 // Accept 'landscape-secondary'.
293 Manifest manifest =
294 ParseManifest("{ \"orientation\": \"landscape-secondary\" }");
295 EXPECT_EQ(manifest.orientation,
296 blink::WebScreenOrientationLockLandscapeSecondary);
299 // Accept 'portrait'.
301 Manifest manifest = ParseManifest("{ \"orientation\": \"portrait\" }");
302 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockPortrait);
305 // Accept 'portrait-primary'.
307 Manifest manifest =
308 ParseManifest("{ \"orientation\": \"portrait-primary\" }");
309 EXPECT_EQ(manifest.orientation,
310 blink::WebScreenOrientationLockPortraitPrimary);
313 // Accept 'portrait-secondary'.
315 Manifest manifest =
316 ParseManifest("{ \"orientation\": \"portrait-secondary\" }");
317 EXPECT_EQ(manifest.orientation,
318 blink::WebScreenOrientationLockPortraitSecondary);
321 // Case insensitive.
323 Manifest manifest = ParseManifest("{ \"orientation\": \"LANDSCAPE\" }");
324 EXPECT_EQ(manifest.orientation, blink::WebScreenOrientationLockLandscape);
328 TEST_F(ManifestParserTest, IconsParseRules) {
329 // Smoke test: if no icon, empty list.
331 Manifest manifest = ParseManifest("{ \"icons\": [] }");
332 EXPECT_EQ(manifest.icons.size(), 0u);
333 EXPECT_TRUE(manifest.IsEmpty());
336 // Smoke test: if empty icon, empty list.
338 Manifest manifest = ParseManifest("{ \"icons\": [ {} ] }");
339 EXPECT_EQ(manifest.icons.size(), 0u);
340 EXPECT_TRUE(manifest.IsEmpty());
343 // Smoke test: icon with invalid src, empty list.
345 Manifest manifest = ParseManifest("{ \"icons\": [ { \"icons\": [] } ] }");
346 EXPECT_EQ(manifest.icons.size(), 0u);
347 EXPECT_TRUE(manifest.IsEmpty());
350 // Smoke test: if icon with empty src, it will be present in the list.
352 Manifest manifest = ParseManifest("{ \"icons\": [ { \"src\": \"\" } ] }");
353 EXPECT_EQ(manifest.icons.size(), 1u);
354 EXPECT_EQ(manifest.icons[0].src.spec(), "http://foo.com/index.html");
355 EXPECT_FALSE(manifest.IsEmpty());
358 // Smoke test: if one icons with valid src, it will be present in the list.
360 Manifest manifest =
361 ParseManifest("{ \"icons\": [{ \"src\": \"foo.jpg\" }] }");
362 EXPECT_EQ(manifest.icons.size(), 1u);
363 EXPECT_EQ(manifest.icons[0].src.spec(), "http://foo.com/foo.jpg");
364 EXPECT_FALSE(manifest.IsEmpty());
368 TEST_F(ManifestParserTest, IconSrcParseRules) {
369 // Smoke test.
371 Manifest manifest =
372 ParseManifest("{ \"icons\": [ {\"src\": \"foo.png\" } ] }");
373 EXPECT_EQ(manifest.icons[0].src.spec(),
374 default_document_url.Resolve("foo.png").spec());
377 // Whitespaces.
379 Manifest manifest =
380 ParseManifest("{ \"icons\": [ {\"src\": \" foo.png \" } ] }");
381 EXPECT_EQ(manifest.icons[0].src.spec(),
382 default_document_url.Resolve("foo.png").spec());
385 // Don't parse if property isn't a string.
387 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": {} } ] }");
388 EXPECT_TRUE(manifest.icons.empty());
391 // Don't parse if property isn't a string.
393 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": 42 } ] }");
394 EXPECT_TRUE(manifest.icons.empty());
397 // Resolving has to happen based on the document_url.
399 Manifest manifest =
400 ParseManifest("{ \"icons\": [ {\"src\": \"icons/foo.png\" } ] }",
401 GURL("http://foo.com/landing/index.html"));
402 EXPECT_EQ(manifest.icons[0].src.spec(),
403 "http://foo.com/landing/icons/foo.png");
407 TEST_F(ManifestParserTest, IconTypeParseRules) {
408 // Smoke test.
410 Manifest manifest =
411 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": \"foo\" } ] }");
412 EXPECT_TRUE(EqualsASCII(manifest.icons[0].type.string(), "foo"));
415 // Trim whitespaces.
417 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
418 " \"type\": \" foo \" } ] }");
419 EXPECT_TRUE(EqualsASCII(manifest.icons[0].type.string(), "foo"));
422 // Don't parse if property isn't a string.
424 Manifest manifest =
425 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": {} } ] }");
426 EXPECT_TRUE(manifest.icons[0].type.is_null());
429 // Don't parse if property isn't a string.
431 Manifest manifest =
432 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"type\": 42 } ] }");
433 EXPECT_TRUE(manifest.icons[0].type.is_null());
437 TEST_F(ManifestParserTest, IconDensityParseRules) {
438 // Smoke test.
440 Manifest manifest =
441 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 42 } ] }");
442 EXPECT_EQ(manifest.icons[0].density, 42);
445 // Decimal value.
447 Manifest manifest =
448 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 2.5 } ] }");
449 EXPECT_EQ(manifest.icons[0].density, 2.5);
452 // Parse fail if it isn't a float.
454 Manifest manifest =
455 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": {} } ] }");
456 EXPECT_EQ(manifest.icons[0].density, Manifest::Icon::kDefaultDensity);
459 // Parse fail if it isn't a float.
461 Manifest manifest =
462 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\":\"2\" } ] }");
463 EXPECT_EQ(manifest.icons[0].density, Manifest::Icon::kDefaultDensity);
466 // Edge case: 1.0.
468 Manifest manifest =
469 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 1.00 } ] }");
470 EXPECT_EQ(manifest.icons[0].density, 1);
473 // Edge case: values between 0.0 and 1.0 are allowed.
475 Manifest manifest =
476 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 0.42 } ] }");
477 EXPECT_EQ(manifest.icons[0].density, 0.42);
480 // 0 is an invalid value.
482 Manifest manifest =
483 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": 0.0 } ] }");
484 EXPECT_EQ(manifest.icons[0].density, Manifest::Icon::kDefaultDensity);
487 // Negative values are invalid.
489 Manifest manifest =
490 ParseManifest("{ \"icons\": [ {\"src\": \"\", \"density\": -2.5 } ] }");
491 EXPECT_EQ(manifest.icons[0].density, Manifest::Icon::kDefaultDensity);
495 TEST_F(ManifestParserTest, IconSizesParseRules) {
496 // Smoke test.
498 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
499 "\"sizes\": \"42x42\" } ] }");
500 EXPECT_EQ(manifest.icons[0].sizes.size(), 1u);
503 // Trim whitespaces.
505 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
506 "\"sizes\": \" 42x42 \" } ] }");
507 EXPECT_EQ(manifest.icons[0].sizes.size(), 1u);
510 // Don't parse if name isn't a string.
512 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
513 "\"sizes\": {} } ] }");
514 EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
517 // Don't parse if name isn't a string.
519 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
520 "\"sizes\": 42 } ] }");
521 EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
524 // Smoke test: value correctly parsed.
526 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
527 "\"sizes\": \"42x42 48x48\" } ] }");
528 EXPECT_EQ(manifest.icons[0].sizes[0], gfx::Size(42, 42));
529 EXPECT_EQ(manifest.icons[0].sizes[1], gfx::Size(48, 48));
532 // <WIDTH>'x'<HEIGHT> and <WIDTH>'X'<HEIGHT> are equivalent.
534 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
535 "\"sizes\": \"42X42 48X48\" } ] }");
536 EXPECT_EQ(manifest.icons[0].sizes[0], gfx::Size(42, 42));
537 EXPECT_EQ(manifest.icons[0].sizes[1], gfx::Size(48, 48));
540 // Twice the same value is parsed twice.
542 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
543 "\"sizes\": \"42X42 42x42\" } ] }");
544 EXPECT_EQ(manifest.icons[0].sizes[0], gfx::Size(42, 42));
545 EXPECT_EQ(manifest.icons[0].sizes[1], gfx::Size(42, 42));
548 // Width or height can't start with 0.
550 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
551 "\"sizes\": \"004X007 042x00\" } ] }");
552 EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
555 // Width and height MUST contain digits.
557 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
558 "\"sizes\": \"e4X1.0 55ax1e10\" } ] }");
559 EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
562 // 'any' is correctly parsed and transformed to gfx::Size(0,0).
564 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
565 "\"sizes\": \"any AnY ANY aNy\" } ] }");
566 gfx::Size any = gfx::Size(0, 0);
567 EXPECT_EQ(manifest.icons[0].sizes.size(), 4u);
568 EXPECT_EQ(manifest.icons[0].sizes[0], any);
569 EXPECT_EQ(manifest.icons[0].sizes[1], any);
570 EXPECT_EQ(manifest.icons[0].sizes[2], any);
571 EXPECT_EQ(manifest.icons[0].sizes[3], any);
574 // Some invalid width/height combinations.
576 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
577 "\"sizes\": \"x 40xx 1x2x3 x42 42xx42\" } ] }");
578 gfx::Size any = gfx::Size(0, 0);
579 EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
583 TEST_F(ManifestParserTest, GCMSenderIDParseRules) {
584 // Smoke test.
586 Manifest manifest = ParseManifest("{ \"gcm_sender_id\": \"foo\" }");
587 EXPECT_TRUE(EqualsASCII(manifest.gcm_sender_id.string(), "foo"));
590 // Trim whitespaces.
592 Manifest manifest = ParseManifest("{ \"gcm_sender_id\": \" foo \" }");
593 EXPECT_TRUE(EqualsASCII(manifest.gcm_sender_id.string(), "foo"));
596 // Don't parse if property isn't a string.
598 Manifest manifest = ParseManifest("{ \"gcm_sender_id\": {} }");
599 EXPECT_TRUE(manifest.gcm_sender_id.is_null());
602 Manifest manifest = ParseManifest("{ \"gcm_sender_id\": 42 }");
603 EXPECT_TRUE(manifest.gcm_sender_id.is_null());
607 } // namespace content