| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/manifest/manifest_parser.h" | 5 #include "content/public/renderer/manifest_parser.h" |
| 6 | 6 |
| 7 #include "base/strings/string_util.h" | 7 #include "base/strings/string_util.h" |
| 8 #include "content/public/common/manifest.h" | 8 #include "content/public/common/manifest.h" |
| 9 #include "content/public/renderer/content_renderer_client.h" |
| 10 #include "content/test/test_content_client.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 12 |
| 11 namespace content { | 13 namespace content { |
| 12 | 14 |
| 13 class ManifestParserTest : public testing::Test { | 15 class ManifestParserTest : public testing::Test { |
| 14 protected: | 16 protected: |
| 15 ManifestParserTest() {} | 17 ManifestParserTest() { |
| 18 SetContentClient(&test_content_client_); |
| 19 SetRendererClientForTesting(&test_content_renderer_client_); |
| 20 } |
| 21 |
| 16 ~ManifestParserTest() override {} | 22 ~ManifestParserTest() override {} |
| 17 | 23 |
| 18 Manifest ParseManifestWithURLs(const base::StringPiece& data, | 24 Manifest ParseManifestWithURLs(const base::StringPiece& data, |
| 19 const GURL& document_url, | 25 const GURL& document_url, |
| 20 const GURL& manifest_url) { | 26 const GURL& manifest_url) { |
| 21 ManifestParser parser(data, document_url, manifest_url); | 27 scoped_ptr<ManifestParser> parser = ManifestParser::Get(); |
| 22 parser.Parse(); | 28 parser->Parse(data, document_url, manifest_url); |
| 23 errors_ = parser.errors(); | 29 errors_ = parser->errors(); |
| 24 return parser.manifest(); | 30 return parser->manifest(); |
| 25 } | 31 } |
| 26 | 32 |
| 27 Manifest ParseManifest(const base::StringPiece& data) { | 33 Manifest ParseManifest(const base::StringPiece& data) { |
| 28 return ParseManifestWithURLs( | 34 return ParseManifestWithURLs( |
| 29 data, default_document_url, default_manifest_url); | 35 data, default_document_url, default_manifest_url); |
| 30 } | 36 } |
| 31 | 37 |
| 32 const std::vector<std::string>& errors() const { | 38 const std::vector<std::string>& errors() const { |
| 33 return errors_; | 39 return errors_; |
| 34 } | 40 } |
| 35 | 41 |
| 36 unsigned int GetErrorCount() const { | 42 unsigned int GetErrorCount() const { |
| 37 return errors_.size(); | 43 return errors_.size(); |
| 38 } | 44 } |
| 39 | 45 |
| 40 static const GURL default_document_url; | 46 static const GURL default_document_url; |
| 41 static const GURL default_manifest_url; | 47 static const GURL default_manifest_url; |
| 42 | 48 |
| 43 private: | 49 private: |
| 44 std::vector<std::string> errors_; | 50 std::vector<std::string> errors_; |
| 45 | 51 |
| 52 TestContentClient test_content_client_; |
| 53 ContentRendererClient test_content_renderer_client_; |
| 54 |
| 46 DISALLOW_COPY_AND_ASSIGN(ManifestParserTest); | 55 DISALLOW_COPY_AND_ASSIGN(ManifestParserTest); |
| 47 }; | 56 }; |
| 48 | 57 |
| 49 const GURL ManifestParserTest::default_document_url( | 58 const GURL ManifestParserTest::default_document_url( |
| 50 "http://foo.com/index.html"); | 59 "http://foo.com/index.html"); |
| 51 const GURL ManifestParserTest::default_manifest_url( | 60 const GURL ManifestParserTest::default_manifest_url( |
| 52 "http://foo.com/manifest.json"); | 61 "http://foo.com/manifest.json"); |
| 53 | 62 |
| 54 TEST_F(ManifestParserTest, CrashTest) { | 63 TEST_F(ManifestParserTest, CrashTest) { |
| 55 // Passing temporary variables should not crash. | 64 // Passing temporary variables should not crash. |
| 56 ManifestParser parser("{\"start_url\": \"/\"}", | 65 scoped_ptr<ManifestParser> parser = ManifestParser::Get(); |
| 57 GURL("http://example.com"), | 66 parser->Parse("{\"start_url\": \"/\"}", |
| 58 GURL("http://example.com")); | 67 GURL("http://example.com"), |
| 59 parser.Parse(); | 68 GURL("http://example.com")); |
| 60 | 69 |
| 61 // .Parse() should have been call without crashing and succeeded. | 70 // .Parse() should have been call without crashing and succeeded. |
| 62 EXPECT_EQ(0u, parser.errors().size()); | 71 EXPECT_EQ(0u, parser->errors().size()); |
| 63 EXPECT_FALSE(parser.manifest().IsEmpty()); | 72 EXPECT_FALSE(parser->manifest().IsEmpty()); |
| 64 } | 73 } |
| 65 | 74 |
| 66 TEST_F(ManifestParserTest, EmptyStringNull) { | 75 TEST_F(ManifestParserTest, EmptyStringNull) { |
| 67 Manifest manifest = ParseManifest(""); | 76 Manifest manifest = ParseManifest(""); |
| 68 | 77 |
| 69 // This Manifest is not a valid JSON object, it's a parsing error. | 78 // This Manifest is not a valid JSON object, it's a parsing error. |
| 70 EXPECT_EQ(1u, GetErrorCount()); | 79 EXPECT_EQ(1u, GetErrorCount()); |
| 71 EXPECT_EQ("Manifest parsing error: Line: 1, column: 1, Unexpected token.", | 80 EXPECT_EQ("Manifest parsing error: Line: 1, column: 1, Unexpected token.", |
| 72 errors()[0]); | 81 errors()[0]); |
| 73 | 82 |
| 74 // A parsing error is equivalent to an empty manifest. | 83 // A parsing error is equivalent to an empty manifest. |
| 75 ASSERT_TRUE(manifest.IsEmpty()); | 84 ASSERT_TRUE(manifest.IsEmpty()); |
| 76 ASSERT_TRUE(manifest.name.is_null()); | 85 ASSERT_TRUE(manifest.name.is_null()); |
| 77 ASSERT_TRUE(manifest.short_name.is_null()); | 86 ASSERT_TRUE(manifest.short_name.is_null()); |
| 78 ASSERT_TRUE(manifest.start_url.is_empty()); | 87 ASSERT_TRUE(manifest.start_url.is_empty()); |
| 79 ASSERT_EQ(manifest.display, Manifest::DISPLAY_MODE_UNSPECIFIED); | 88 ASSERT_EQ(manifest.display, Manifest::DISPLAY_MODE_UNSPECIFIED); |
| 80 ASSERT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault); | 89 ASSERT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault); |
| 81 ASSERT_TRUE(manifest.gcm_sender_id.is_null()); | |
| 82 ASSERT_FALSE(manifest.gcm_user_visible_only); | |
| 83 } | 90 } |
| 84 | 91 |
| 85 TEST_F(ManifestParserTest, ValidNoContentParses) { | 92 TEST_F(ManifestParserTest, ValidNoContentParses) { |
| 86 Manifest manifest = ParseManifest("{}"); | 93 Manifest manifest = ParseManifest("{}"); |
| 87 | 94 |
| 88 // Empty Manifest is not a parsing error. | 95 // Empty Manifest is not a parsing error. |
| 89 EXPECT_EQ(0u, GetErrorCount()); | 96 EXPECT_EQ(0u, GetErrorCount()); |
| 90 | 97 |
| 91 // Check that all the fields are null in that case. | 98 // Check that all the fields are null in that case. |
| 92 ASSERT_TRUE(manifest.IsEmpty()); | 99 ASSERT_TRUE(manifest.IsEmpty()); |
| 93 ASSERT_TRUE(manifest.name.is_null()); | 100 ASSERT_TRUE(manifest.name.is_null()); |
| 94 ASSERT_TRUE(manifest.short_name.is_null()); | 101 ASSERT_TRUE(manifest.short_name.is_null()); |
| 95 ASSERT_TRUE(manifest.start_url.is_empty()); | 102 ASSERT_TRUE(manifest.start_url.is_empty()); |
| 96 ASSERT_EQ(manifest.display, Manifest::DISPLAY_MODE_UNSPECIFIED); | 103 ASSERT_EQ(manifest.display, Manifest::DISPLAY_MODE_UNSPECIFIED); |
| 97 ASSERT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault); | 104 ASSERT_EQ(manifest.orientation, blink::WebScreenOrientationLockDefault); |
| 98 ASSERT_TRUE(manifest.gcm_sender_id.is_null()); | |
| 99 ASSERT_FALSE(manifest.gcm_user_visible_only); | |
| 100 } | 105 } |
| 101 | 106 |
| 102 TEST_F(ManifestParserTest, MultipleErrorsReporting) { | 107 TEST_F(ManifestParserTest, MultipleErrorsReporting) { |
| 103 Manifest manifest = ParseManifest("{ \"name\": 42, \"short_name\": 4," | 108 Manifest manifest = ParseManifest("{ \"name\": 42, \"short_name\": 4," |
| 104 "\"orientation\": {}, \"display\": \"foo\", \"start_url\": null," | 109 "\"orientation\": {}, \"display\": \"foo\", \"start_url\": null," |
| 105 "\"icons\": {}, \"gcm_user_visible_only\": 42 }"); | 110 "\"icons\": {} }"); |
| 106 | 111 |
| 107 EXPECT_EQ(7u, GetErrorCount()); | 112 EXPECT_EQ(6u, GetErrorCount()); |
| 108 | 113 |
| 109 EXPECT_EQ("Manifest parsing error: property 'name' ignored," | 114 EXPECT_EQ("Manifest parsing error: property 'name' ignored," |
| 110 " type string expected.", | 115 " type string expected.", |
| 111 errors()[0]); | 116 errors()[0]); |
| 112 EXPECT_EQ("Manifest parsing error: property 'short_name' ignored," | 117 EXPECT_EQ("Manifest parsing error: property 'short_name' ignored," |
| 113 " type string expected.", | 118 " type string expected.", |
| 114 errors()[1]); | 119 errors()[1]); |
| 115 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored," | 120 EXPECT_EQ("Manifest parsing error: property 'start_url' ignored," |
| 116 " type string expected.", | 121 " type string expected.", |
| 117 errors()[2]); | 122 errors()[2]); |
| 118 EXPECT_EQ("Manifest parsing error: unknown 'display' value ignored.", | 123 EXPECT_EQ("Manifest parsing error: unknown 'display' value ignored.", |
| 119 errors()[3]); | 124 errors()[3]); |
| 120 EXPECT_EQ("Manifest parsing error: property 'orientation' ignored," | 125 EXPECT_EQ("Manifest parsing error: property 'orientation' ignored," |
| 121 " type string expected.", | 126 " type string expected.", |
| 122 errors()[4]); | 127 errors()[4]); |
| 123 EXPECT_EQ("Manifest parsing error: property 'icons' ignored, " | 128 EXPECT_EQ("Manifest parsing error: property 'icons' ignored, " |
| 124 "type array expected.", | 129 "type array expected.", |
| 125 errors()[5]); | 130 errors()[5]); |
| 126 EXPECT_EQ("Manifest parsing error: property 'gcm_user_visible_only' ignored, " | |
| 127 "type boolean expected.", | |
| 128 errors()[6]); | |
| 129 } | 131 } |
| 130 | 132 |
| 131 TEST_F(ManifestParserTest, NameParseRules) { | 133 TEST_F(ManifestParserTest, NameParseRules) { |
| 132 // Smoke test. | 134 // Smoke test. |
| 133 { | 135 { |
| 134 Manifest manifest = ParseManifest("{ \"name\": \"foo\" }"); | 136 Manifest manifest = ParseManifest("{ \"name\": \"foo\" }"); |
| 135 ASSERT_TRUE(EqualsASCII(manifest.name.string(), "foo")); | 137 ASSERT_TRUE(EqualsASCII(manifest.name.string(), "foo")); |
| 136 ASSERT_FALSE(manifest.IsEmpty()); | 138 ASSERT_FALSE(manifest.IsEmpty()); |
| 137 EXPECT_EQ(0u, GetErrorCount()); | 139 EXPECT_EQ(0u, GetErrorCount()); |
| 138 } | 140 } |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 790 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\"," | 792 Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\"," |
| 791 "\"sizes\": \"x 40xx 1x2x3 x42 42xx42\" } ] }"); | 793 "\"sizes\": \"x 40xx 1x2x3 x42 42xx42\" } ] }"); |
| 792 gfx::Size any = gfx::Size(0, 0); | 794 gfx::Size any = gfx::Size(0, 0); |
| 793 EXPECT_EQ(manifest.icons[0].sizes.size(), 0u); | 795 EXPECT_EQ(manifest.icons[0].sizes.size(), 0u); |
| 794 EXPECT_EQ(1u, GetErrorCount()); | 796 EXPECT_EQ(1u, GetErrorCount()); |
| 795 EXPECT_EQ("Manifest parsing error: found icon with no valid size.", | 797 EXPECT_EQ("Manifest parsing error: found icon with no valid size.", |
| 796 errors()[0]); | 798 errors()[0]); |
| 797 } | 799 } |
| 798 } | 800 } |
| 799 | 801 |
| 800 TEST_F(ManifestParserTest, GCMSenderIDParseRules) { | |
| 801 // Smoke test. | |
| 802 { | |
| 803 Manifest manifest = ParseManifest("{ \"gcm_sender_id\": \"foo\" }"); | |
| 804 EXPECT_TRUE(EqualsASCII(manifest.gcm_sender_id.string(), "foo")); | |
| 805 EXPECT_EQ(0u, GetErrorCount()); | |
| 806 } | |
| 807 | |
| 808 // Trim whitespaces. | |
| 809 { | |
| 810 Manifest manifest = ParseManifest("{ \"gcm_sender_id\": \" foo \" }"); | |
| 811 EXPECT_TRUE(EqualsASCII(manifest.gcm_sender_id.string(), "foo")); | |
| 812 EXPECT_EQ(0u, GetErrorCount()); | |
| 813 } | |
| 814 | |
| 815 // Don't parse if the property isn't a string. | |
| 816 { | |
| 817 Manifest manifest = ParseManifest("{ \"gcm_sender_id\": {} }"); | |
| 818 EXPECT_TRUE(manifest.gcm_sender_id.is_null()); | |
| 819 EXPECT_EQ(1u, GetErrorCount()); | |
| 820 EXPECT_EQ("Manifest parsing error: property 'gcm_sender_id' ignored," | |
| 821 " type string expected.", | |
| 822 errors()[0]); | |
| 823 } | |
| 824 { | |
| 825 Manifest manifest = ParseManifest("{ \"gcm_sender_id\": 42 }"); | |
| 826 EXPECT_TRUE(manifest.gcm_sender_id.is_null()); | |
| 827 EXPECT_EQ(1u, GetErrorCount()); | |
| 828 EXPECT_EQ("Manifest parsing error: property 'gcm_sender_id' ignored," | |
| 829 " type string expected.", | |
| 830 errors()[0]); | |
| 831 } | |
| 832 } | |
| 833 | |
| 834 TEST_F(ManifestParserTest, GCMUserVisibleOnlyParseRules) { | |
| 835 // Smoke test. | |
| 836 { | |
| 837 Manifest manifest = ParseManifest("{ \"gcm_user_visible_only\": true }"); | |
| 838 EXPECT_TRUE(manifest.gcm_user_visible_only); | |
| 839 EXPECT_EQ(0u, GetErrorCount()); | |
| 840 } | |
| 841 | |
| 842 // Don't parse if the property isn't a boolean. | |
| 843 { | |
| 844 Manifest manifest = ParseManifest("{ \"gcm_user_visible_only\": {} }"); | |
| 845 EXPECT_FALSE(manifest.gcm_user_visible_only); | |
| 846 EXPECT_EQ(1u, GetErrorCount()); | |
| 847 EXPECT_EQ( | |
| 848 "Manifest parsing error: property 'gcm_user_visible_only' ignored," | |
| 849 " type boolean expected.", | |
| 850 errors()[0]); | |
| 851 } | |
| 852 { | |
| 853 Manifest manifest = ParseManifest( | |
| 854 "{ \"gcm_user_visible_only\": \"true\" }"); | |
| 855 EXPECT_FALSE(manifest.gcm_user_visible_only); | |
| 856 EXPECT_EQ(1u, GetErrorCount()); | |
| 857 EXPECT_EQ( | |
| 858 "Manifest parsing error: property 'gcm_user_visible_only' ignored," | |
| 859 " type boolean expected.", | |
| 860 errors()[0]); | |
| 861 } | |
| 862 { | |
| 863 Manifest manifest = ParseManifest("{ \"gcm_user_visible_only\": 1 }"); | |
| 864 EXPECT_FALSE(manifest.gcm_user_visible_only); | |
| 865 EXPECT_EQ(1u, GetErrorCount()); | |
| 866 EXPECT_EQ( | |
| 867 "Manifest parsing error: property 'gcm_user_visible_only' ignored," | |
| 868 " type boolean expected.", | |
| 869 errors()[0]); | |
| 870 } | |
| 871 | |
| 872 // "False" should set the boolean false without throwing errors. | |
| 873 { | |
| 874 Manifest manifest = ParseManifest("{ \"gcm_user_visible_only\": false }"); | |
| 875 EXPECT_FALSE(manifest.gcm_user_visible_only); | |
| 876 EXPECT_EQ(0u, GetErrorCount()); | |
| 877 } | |
| 878 } | |
| 879 | |
| 880 } // namespace content | 802 } // namespace content |
| OLD | NEW |