1 // Copyright 2013 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.
4 
5 #include <stddef.h>
6 
7 #include "base/values.h"
8 #include "components/json_schema/json_schema_validator.h"
9 #include "components/json_schema/json_schema_validator_unittest_base.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 
12 class JSONSchemaValidatorCPPTest : public JSONSchemaValidatorTestBase {
13  public:
JSONSchemaValidatorCPPTest()14   JSONSchemaValidatorCPPTest() {}
15 
16  protected:
ExpectValid(const std::string & test_source,base::Value * instance,base::DictionaryValue * schema,base::ListValue * types)17   void ExpectValid(const std::string& test_source,
18                    base::Value* instance,
19                    base::DictionaryValue* schema,
20                    base::ListValue* types) override {
21     JSONSchemaValidator validator(schema, types);
22     if (validator.Validate(instance))
23       return;
24 
25     for (size_t i = 0; i < validator.errors().size(); ++i) {
26       ADD_FAILURE() << test_source << ": "
27                     << validator.errors()[i].path << ": "
28                     << validator.errors()[i].message;
29     }
30   }
31 
ExpectNotValid(const std::string & test_source,base::Value * instance,base::DictionaryValue * schema,base::ListValue * types,const std::string & expected_error_path,const std::string & expected_error_message)32   void ExpectNotValid(const std::string& test_source,
33                       base::Value* instance,
34                       base::DictionaryValue* schema,
35                       base::ListValue* types,
36                       const std::string& expected_error_path,
37                       const std::string& expected_error_message) override {
38     JSONSchemaValidator validator(schema, types);
39     if (validator.Validate(instance)) {
40       ADD_FAILURE() << test_source;
41       return;
42     }
43 
44     ASSERT_EQ(1u, validator.errors().size()) << test_source;
45     EXPECT_EQ(expected_error_path, validator.errors()[0].path) << test_source;
46     EXPECT_EQ(expected_error_message, validator.errors()[0].message)
47         << test_source;
48   }
49 };
50 
TEST_F(JSONSchemaValidatorCPPTest,Test)51 TEST_F(JSONSchemaValidatorCPPTest, Test) {
52   RunTests();
53 }
54 
TEST(JSONSchemaValidator,IsValidSchema)55 TEST(JSONSchemaValidator, IsValidSchema) {
56   std::string error;
57   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("", &error));
58   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("\0", &error));
59   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("string", &error));
60   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("\"string\"", &error));
61   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("[]", &error));
62   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("{}", &error));
63   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
64       "{ \"type\": 123 }", &error));
65   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
66       "{ \"type\": \"invalid\" }", &error));
67   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
68       "{"
69       "  \"type\": \"object\","
70       "  \"properties\": []"  // Invalid properties type.
71       "}", &error));
72   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
73       "{"
74       "  \"type\": \"string\","
75       "  \"maxLength\": -1"  // Must be >= 0.
76       "}", &error));
77   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
78       "{"
79       "  \"type\": \"string\","
80       "  \"enum\": [ {} ]"  // "enum" dict values must contain "name".
81       "}", &error));
82   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
83       "{"
84       "  \"type\": \"string\","
85       "  \"enum\": [ { \"name\": {} } ]"  // "enum" name must be a simple value.
86       "}", &error));
87   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
88       "{"
89       "  \"type\": \"array\","
90       "  \"items\": [ 123 ],"  // "items" must contain a schema or schemas.
91       "}", &error));
92   EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
93       "{ \"type\": \"object\" }", &error)) << error;
94   EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
95       "{ \"type\": [\"object\", \"array\"] }", &error)) << error;
96   EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
97       "{"
98       "  \"type\": [\"object\", \"array\"],"
99       "  \"properties\": {"
100       "    \"string-property\": {"
101       "      \"type\": \"string\","
102       "      \"minLength\": 1,"
103       "      \"maxLength\": 100,"
104       "      \"title\": \"The String Policy\","
105       "      \"description\": \"This policy controls the String widget.\""
106       "    },"
107       "    \"integer-property\": {"
108       "      \"type\": \"number\","
109       "      \"minimum\": 1000.0,"
110       "      \"maximum\": 9999.0"
111       "    },"
112       "    \"enum-property\": {"
113       "      \"type\": \"integer\","
114       "      \"enum\": [0, 1, {\"name\": 10}, 100]"
115       "    },"
116       "    \"items-property\": {"
117       "      \"type\": \"array\","
118       "      \"items\": {"
119       "        \"type\": \"string\""
120       "      }"
121       "    },"
122       "    \"items-list-property\": {"
123       "      \"type\": \"array\","
124       "      \"items\": ["
125       "        { \"type\": \"string\" },"
126       "        { \"type\": \"integer\" }"
127       "      ]"
128       "    }"
129       "  },"
130       "  \"additionalProperties\": {"
131       "    \"type\": \"any\""
132       "  }"
133       "}", &error)) << error;
134   EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
135       "{"
136       "  \"type\": \"object\","
137       "  \"patternProperties\": {"
138       "    \".\": { \"type\": \"any\" },"
139       "    \"foo\": { \"type\": \"any\" },"
140       "    \"^foo$\": { \"type\": \"any\" },"
141       "    \"foo+\": { \"type\": \"any\" },"
142       "    \"foo?\": { \"type\": \"any\" },"
143       "    \"fo{2,4}\": { \"type\": \"any\" },"
144       "    \"(left)|(right)\": { \"type\": \"any\" }"
145       "  }"
146       "}", &error)) << error;
147   EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
148       "{"
149       "  \"type\": \"object\","
150       "  \"unknown attribute\": \"that should just be ignored\""
151       "}",
152       JSONSchemaValidator::OPTIONS_IGNORE_UNKNOWN_ATTRIBUTES,
153       &error)) << error;
154   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
155       "{"
156       "  \"type\": \"object\","
157       "  \"unknown attribute\": \"that will cause a failure\""
158       "}", 0, &error)) << error;
159 
160   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(R"(
161       {
162         "type": "object",
163         "properties": {"foo": {"type": "number"}},
164         "required": 123
165       })",
166                                                   0, &error))
167       << error;
168 
169   EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(R"(
170       {
171         "type": "object",
172         "properties": {"foo": {"type": "number"}},
173         "required": [ 123 ]
174       })",
175                                                   0, &error))
176       << error;
177 }
178