Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Unified Diff: components/policy/core/common/schema_unittest.cc

Issue 134153005: Add strictness to Schema::Validate() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@expand-policy-schema-2
Patch Set: minor fixes Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/policy/core/common/schema_map.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/policy/core/common/schema_unittest.cc
diff --git a/components/policy/core/common/schema_unittest.cc b/components/policy/core/common/schema_unittest.cc
index 8a3ba90b1bd09876b9f0f98900fb11a9ddd50b6c..0c80a440fbe441477c5dc9cbd0a0757c6a9cae4b 100644
--- a/components/policy/core/common/schema_unittest.cc
+++ b/components/policy/core/common/schema_unittest.cc
@@ -4,6 +4,7 @@
#include "components/policy/core/common/schema.h"
+#include "base/memory/scoped_ptr.h"
#include "components/policy/core/common/schema_internal.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -49,6 +50,18 @@ const char kTestSchema[] =
" },"
" \"additionalProperties\": { \"type\": \"string\" }"
" },"
+ " \"ObjectOfObject\": {"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"Object\": {"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"one\": { \"type\": \"string\" },"
+ " \"two\": { \"type\": \"integer\" }"
+ " }"
+ " }"
+ " }"
+ " },"
" \"IntegerWithEnums\": {"
" \"type\": \"integer\","
" \"enum\": [1, 2, 3]"
@@ -65,6 +78,27 @@ const char kTestSchema[] =
" \"type\": \"integer\","
" \"minimum\": 1,"
" \"maximum\": 3"
+ " },"
+ " \"ObjectOfArray\": {"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"List\": {"
+ " \"type\": \"array\","
+ " \"items\": { \"type\": \"integer\" }"
+ " }"
+ " }"
+ " },"
+ " \"ArrayOfObjectOfArray\": {"
+ " \"type\": \"array\","
+ " \"items\": {"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"List\": {"
+ " \"type\": \"array\","
+ " \"items\": { \"type\": \"string\" }"
+ " }"
+ " }"
+ " }"
" }"
" }"
"}";
@@ -78,6 +112,33 @@ bool ParseFails(const std::string& content) {
return true;
}
+void TestSchemaValidation(Schema schema,
+ const base::Value& value,
+ SchemaOnErrorStrategy strategy,
+ bool expected_return_value) {
+ std::string error;
+ static const char kNoErrorReturned[] = "No error returned.";
+
+ // Test that Schema::Validate() works as expected.
+ error = kNoErrorReturned;
+ bool returned = schema.Validate(value, strategy, &error);
+ EXPECT_EQ(returned, expected_return_value) << error;
+
+ // Test that Schema::Normalize() will return the same value as
+ // Schema::Validate().
+ error = kNoErrorReturned;
+ scoped_ptr<base::Value> cloned_value(value.DeepCopy());
+ returned = schema.Normalize(cloned_value.get(), strategy, &error);
+ EXPECT_EQ(returned, expected_return_value) << error;
+
+ // Test that Schema::Normalize() have actually dropped invalid and unknown
+ // properties.
+ if (expected_return_value) {
+ EXPECT_TRUE(schema.Validate(*cloned_value.get(), SCHEMA_STRICT, &error));
+ EXPECT_TRUE(schema.Normalize(cloned_value.get(), SCHEMA_STRICT, &error));
+ }
+}
+
std::string SchemaObjectWrapper(const std::string& subschema) {
return "{"
" \"type\": \"object\","
@@ -277,6 +338,7 @@ TEST(SchemaTest, ValidSchema) {
} kExpectedProperties[] = {
{ "Array", base::Value::TYPE_LIST },
{ "ArrayOfArray", base::Value::TYPE_LIST },
+ { "ArrayOfObjectOfArray", base::Value::TYPE_LIST },
{ "ArrayOfObjects", base::Value::TYPE_LIST },
{ "Boolean", base::Value::TYPE_BOOLEAN },
{ "Integer", base::Value::TYPE_INTEGER },
@@ -286,6 +348,8 @@ TEST(SchemaTest, ValidSchema) {
{ "Null", base::Value::TYPE_NULL },
{ "Number", base::Value::TYPE_DOUBLE },
{ "Object", base::Value::TYPE_DICTIONARY },
+ { "ObjectOfArray", base::Value::TYPE_DICTIONARY },
+ { "ObjectOfObject", base::Value::TYPE_DICTIONARY },
{ "String", base::Value::TYPE_STRING },
{ "StringWithEnums", base::Value::TYPE_STRING },
};
@@ -467,11 +531,11 @@ TEST(SchemaTest, Validate) {
ASSERT_TRUE(schema.valid()) << error;
base::DictionaryValue bundle;
- EXPECT_TRUE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, true);
// Wrong type, expected integer.
bundle.SetBoolean("Integer", true);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
// Wrong type, expected list of strings.
{
@@ -479,7 +543,7 @@ TEST(SchemaTest, Validate) {
base::ListValue list;
list.AppendInteger(1);
bundle.Set("Array", list.DeepCopy());
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
}
// Wrong type in a sub-object.
@@ -488,13 +552,13 @@ TEST(SchemaTest, Validate) {
base::DictionaryValue dict;
dict.SetString("one", "one");
bundle.Set("Object", dict.DeepCopy());
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
}
// Unknown name.
bundle.Clear();
bundle.SetBoolean("Unknown", true);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
// All of these will be valid.
bundle.Clear();
@@ -545,47 +609,169 @@ TEST(SchemaTest, Validate) {
bundle.SetString("StringWithEnums", "two");
bundle.SetInteger("IntegerWithRange", 3);
- EXPECT_TRUE(schema.Validate(bundle));
-
- bundle.SetString("boom", "bang");
- EXPECT_FALSE(schema.Validate(bundle));
- bundle.Remove("boom", NULL);
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, true);
bundle.SetInteger("IntegerWithEnums", 0);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetInteger("IntegerWithEnums", 1);
bundle.SetInteger("IntegerWithEnumsGaps", 0);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetInteger("IntegerWithEnumsGaps", 9);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetInteger("IntegerWithEnumsGaps", 10);
- EXPECT_TRUE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, true);
bundle.SetInteger("IntegerWithEnumsGaps", 11);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetInteger("IntegerWithEnumsGaps", 19);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetInteger("IntegerWithEnumsGaps", 21);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetInteger("IntegerWithEnumsGaps", 29);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetInteger("IntegerWithEnumsGaps", 30);
- EXPECT_TRUE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, true);
bundle.SetInteger("IntegerWithEnumsGaps", 31);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetInteger("IntegerWithEnumsGaps", 100);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetInteger("IntegerWithEnumsGaps", 20);
bundle.SetString("StringWithEnums", "FOUR");
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetString("StringWithEnums", "two");
bundle.SetInteger("IntegerWithRange", 4);
- EXPECT_FALSE(schema.Validate(bundle));
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
bundle.SetInteger("IntegerWithRange", 3);
+ // Unknown top level property.
+ bundle.SetString("boom", "bang");
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
+ TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, true);
+ TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_UNKNOWN, true);
+ bundle.Remove("boom", NULL);
+
+ // Invalid top level property.
+ bundle.SetInteger("Boolean", 12345);
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, false);
+ TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_INVALID_TOPLEVEL, true);
+ TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_INVALID, true);
+ bundle.SetBoolean("Boolean", true);
+
+ // Tests on ObjectOfObject.
+ {
+ Schema subschema = schema.GetProperty("ObjectOfObject");
+ ASSERT_TRUE(subschema.valid());
+ base::DictionaryValue root;
+
+ // Unknown property.
+ root.SetBoolean("Object.three", false);
+ TestSchemaValidation(subschema, root, SCHEMA_STRICT, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID_TOPLEVEL, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID, true);
+ root.Remove("Object.three", NULL);
+
+ // Invalid property.
+ root.SetInteger("Object.one", 12345);
+ TestSchemaValidation(subschema, root, SCHEMA_STRICT, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID_TOPLEVEL, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID, true);
+ root.Remove("Object.one", NULL);
+ }
+
+ // Tests on ArrayOfObjects.
+ {
+ Schema subschema = schema.GetProperty("ArrayOfObjects");
+ ASSERT_TRUE(subschema.valid());
+ base::ListValue root;
+
+ // Unknown property.
+ base::DictionaryValue* dict_value = new base::DictionaryValue();
+ dict_value->SetBoolean("three", true);
+ root.Append(dict_value); // Pass ownership to root.
+ TestSchemaValidation(subschema, root, SCHEMA_STRICT, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID_TOPLEVEL, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID, true);
+ root.Remove(root.GetSize() - 1, NULL);
+
+ // Invalid property.
+ dict_value = new base::DictionaryValue();
+ dict_value->SetBoolean("two", true);
+ root.Append(dict_value); // Pass ownership to root.
+ TestSchemaValidation(subschema, root, SCHEMA_STRICT, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID_TOPLEVEL, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID, true);
+ root.Remove(root.GetSize() - 1, NULL);
+ }
+
+ // Tests on ObjectOfArray.
+ {
+ Schema subschema = schema.GetProperty("ObjectOfArray");
+ ASSERT_TRUE(subschema.valid());
+ base::DictionaryValue root;
+
+ base::ListValue* list_value = new base::ListValue();
+ root.Set("List", list_value); // Pass ownership to root.
+
+ // No errors.
+ list_value->Append(new base::FundamentalValue(12345));
+ TestSchemaValidation(subschema, root, SCHEMA_STRICT, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID_TOPLEVEL, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID, true);
+
+ // Invalid list item.
+ list_value->Append(new base::StringValue("blabla"));
+ TestSchemaValidation(subschema, root, SCHEMA_STRICT, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID_TOPLEVEL, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID, true);
+ }
+
+ // Tests on ArrayOfObjectOfArray.
+ {
+ Schema subschema = schema.GetProperty("ArrayOfObjectOfArray");
+ ASSERT_TRUE(subschema.valid());
+ base::ListValue root;
+
+ base::ListValue* list_value = new base::ListValue();
+ base::DictionaryValue* dict_value = new base::DictionaryValue();
+ dict_value->Set("List", list_value); // Pass ownership to dict_value.
+ root.Append(dict_value); // Pass ownership to root.
+
+ // No errors.
+ list_value->Append(new base::StringValue("blabla"));
+ TestSchemaValidation(subschema, root, SCHEMA_STRICT, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID_TOPLEVEL, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID, true);
+
+ // Invalid list item.
+ list_value->Append(new base::FundamentalValue(12345));
+ TestSchemaValidation(subschema, root, SCHEMA_STRICT, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, false);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID_TOPLEVEL, true);
+ TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID, true);
+ }
+
+ // Test that integer to double promotion is allowed.
+ bundle.SetInteger("Number", 31415);
+ TestSchemaValidation(schema, bundle, SCHEMA_STRICT, true);
}
+
TEST(SchemaTest, InvalidReferences) {
// References to undeclared schemas fail.
EXPECT_TRUE(ParseFails(
« no previous file with comments | « components/policy/core/common/schema_map.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698