OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "components/policy/core/common/schema.h" | 5 #include "components/policy/core/common/schema.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | |
7 #include "components/policy/core/common/schema_internal.h" | 8 #include "components/policy/core/common/schema_internal.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
9 | 10 |
10 namespace policy { | 11 namespace policy { |
11 | 12 |
12 namespace { | 13 namespace { |
13 | 14 |
14 const char kTestSchema[] = | 15 const char kTestSchema[] = |
15 "{" | 16 "{" |
16 " \"type\": \"object\"," | 17 " \"type\": \"object\"," |
(...skipping 25 matching lines...) Expand all Loading... | |
42 " }" | 43 " }" |
43 " }," | 44 " }," |
44 " \"Object\": {" | 45 " \"Object\": {" |
45 " \"type\": \"object\"," | 46 " \"type\": \"object\"," |
46 " \"properties\": {" | 47 " \"properties\": {" |
47 " \"one\": { \"type\": \"boolean\" }," | 48 " \"one\": { \"type\": \"boolean\" }," |
48 " \"two\": { \"type\": \"integer\" }" | 49 " \"two\": { \"type\": \"integer\" }" |
49 " }," | 50 " }," |
50 " \"additionalProperties\": { \"type\": \"string\" }" | 51 " \"additionalProperties\": { \"type\": \"string\" }" |
51 " }," | 52 " }," |
53 " \"ObjectOfObject\": {" | |
54 " \"type\": \"object\"," | |
55 " \"Object\": {" | |
56 " \"type\": \"object\"," | |
57 " \"properties\": {" | |
58 " \"one\": { \"type\": \"string\" }," | |
59 " \"two\": { \"type\": \"integer\" }" | |
60 " }" | |
61 " }" | |
62 " }," | |
Joao da Silva
2014/01/22 10:49:53
Test with a list of dictionaries too. More types t
binjin
2014/01/23 12:01:31
Done. Added tests for ArrayOfObjects, ObjectOfArra
| |
52 " \"IntegerWithEnums\": {" | 63 " \"IntegerWithEnums\": {" |
53 " \"type\": \"integer\"," | 64 " \"type\": \"integer\"," |
54 " \"enum\": [1, 2, 3]" | 65 " \"enum\": [1, 2, 3]" |
55 " }," | 66 " }," |
56 " \"IntegerWithEnumsGaps\": {" | 67 " \"IntegerWithEnumsGaps\": {" |
57 " \"type\": \"integer\"," | 68 " \"type\": \"integer\"," |
58 " \"enum\": [10, 20, 30]" | 69 " \"enum\": [10, 20, 30]" |
59 " }," | 70 " }," |
60 " \"StringWithEnums\": {" | 71 " \"StringWithEnums\": {" |
61 " \"type\": \"string\"," | 72 " \"type\": \"string\"," |
62 " \"enum\": [\"one\", \"two\", \"three\"]" | 73 " \"enum\": [\"one\", \"two\", \"three\"]" |
63 " }," | 74 " }," |
64 " \"IntegerWithRange\": {" | 75 " \"IntegerWithRange\": {" |
65 " \"type\": \"integer\"," | 76 " \"type\": \"integer\"," |
66 " \"minimum\": 1," | 77 " \"minimum\": 1," |
67 " \"maximum\": 3" | 78 " \"maximum\": 3" |
68 " }" | 79 " }" |
69 " }" | 80 " }" |
70 "}"; | 81 "}"; |
71 | 82 |
72 bool ParseFails(const std::string& content) { | 83 bool ParseFails(const std::string& content) { |
73 std::string error; | 84 std::string error; |
74 Schema schema = Schema::Parse(content, &error); | 85 Schema schema = Schema::Parse(content, &error); |
75 if (schema.valid()) | 86 if (schema.valid()) |
76 return false; | 87 return false; |
77 EXPECT_FALSE(error.empty()); | 88 EXPECT_FALSE(error.empty()); |
78 return true; | 89 return true; |
79 } | 90 } |
80 | 91 |
92 void TestSchemaValidation(Schema schema, | |
93 const base::Value& value, | |
94 SchemaOnErrorStrategy strategy, | |
95 bool expected_return_value) { | |
96 std::string error; | |
97 static const char* no_error_returned = "No error returned."; | |
98 | |
99 // Test that Schema::Validate() works as expected. | |
100 error = no_error_returned; | |
101 bool returned = schema.Validate(value, strategy, &error); | |
102 EXPECT_EQ(returned, expected_return_value) << error; | |
103 | |
104 // Test that Schema::Normalize() will return the same value as | |
105 // Schema::Validate(). | |
106 error = no_error_returned; | |
107 scoped_ptr<base::Value> cloned_value(value.DeepCopy()); | |
108 returned = schema.Normalize(cloned_value.get(), strategy, &error); | |
109 EXPECT_EQ(returned, expected_return_value) << error; | |
110 | |
111 // Test that Schema::Normalize() have actually dropped invalid and unknown | |
112 // properties. | |
113 if (expected_return_value) { | |
114 EXPECT_TRUE(schema.Validate(*cloned_value.get(), | |
115 SCHEMA_VERY_STRICT, &error)); | |
116 EXPECT_TRUE(schema.Normalize(cloned_value.get(), | |
117 SCHEMA_VERY_STRICT, &error)); | |
118 } | |
119 } | |
120 | |
81 std::string SchemaObjectWrapper(const std::string& subschema) { | 121 std::string SchemaObjectWrapper(const std::string& subschema) { |
82 return "{" | 122 return "{" |
83 " \"type\": \"object\"," | 123 " \"type\": \"object\"," |
84 " \"properties\": {" | 124 " \"properties\": {" |
85 " \"SomePropertyName\":" + subschema + | 125 " \"SomePropertyName\":" + subschema + |
86 " }" | 126 " }" |
87 "}"; | 127 "}"; |
88 } | 128 } |
89 | 129 |
90 } // namespace | 130 } // namespace |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
279 { "ArrayOfArray", base::Value::TYPE_LIST }, | 319 { "ArrayOfArray", base::Value::TYPE_LIST }, |
280 { "ArrayOfObjects", base::Value::TYPE_LIST }, | 320 { "ArrayOfObjects", base::Value::TYPE_LIST }, |
281 { "Boolean", base::Value::TYPE_BOOLEAN }, | 321 { "Boolean", base::Value::TYPE_BOOLEAN }, |
282 { "Integer", base::Value::TYPE_INTEGER }, | 322 { "Integer", base::Value::TYPE_INTEGER }, |
283 { "IntegerWithEnums", base::Value::TYPE_INTEGER }, | 323 { "IntegerWithEnums", base::Value::TYPE_INTEGER }, |
284 { "IntegerWithEnumsGaps", base::Value::TYPE_INTEGER }, | 324 { "IntegerWithEnumsGaps", base::Value::TYPE_INTEGER }, |
285 { "IntegerWithRange", base::Value::TYPE_INTEGER }, | 325 { "IntegerWithRange", base::Value::TYPE_INTEGER }, |
286 { "Null", base::Value::TYPE_NULL }, | 326 { "Null", base::Value::TYPE_NULL }, |
287 { "Number", base::Value::TYPE_DOUBLE }, | 327 { "Number", base::Value::TYPE_DOUBLE }, |
288 { "Object", base::Value::TYPE_DICTIONARY }, | 328 { "Object", base::Value::TYPE_DICTIONARY }, |
329 { "ObjectOfObject", base::Value::TYPE_DICTIONARY }, | |
289 { "String", base::Value::TYPE_STRING }, | 330 { "String", base::Value::TYPE_STRING }, |
290 { "StringWithEnums", base::Value::TYPE_STRING }, | 331 { "StringWithEnums", base::Value::TYPE_STRING }, |
291 }; | 332 }; |
292 Schema::Iterator it = schema.GetPropertiesIterator(); | 333 Schema::Iterator it = schema.GetPropertiesIterator(); |
293 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpectedProperties); ++i) { | 334 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpectedProperties); ++i) { |
294 ASSERT_FALSE(it.IsAtEnd()); | 335 ASSERT_FALSE(it.IsAtEnd()); |
295 EXPECT_STREQ(kExpectedProperties[i].expected_key, it.key()); | 336 EXPECT_STREQ(kExpectedProperties[i].expected_key, it.key()); |
296 ASSERT_TRUE(it.schema().valid()); | 337 ASSERT_TRUE(it.schema().valid()); |
297 EXPECT_EQ(kExpectedProperties[i].expected_type, it.schema().type()); | 338 EXPECT_EQ(kExpectedProperties[i].expected_type, it.schema().type()); |
298 it.Advance(); | 339 it.Advance(); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
460 ASSERT_TRUE(subsubsub.valid()); | 501 ASSERT_TRUE(subsubsub.valid()); |
461 ASSERT_EQ(base::Value::TYPE_STRING, subsubsub.type()); | 502 ASSERT_EQ(base::Value::TYPE_STRING, subsubsub.type()); |
462 } | 503 } |
463 | 504 |
464 TEST(SchemaTest, Validate) { | 505 TEST(SchemaTest, Validate) { |
465 std::string error; | 506 std::string error; |
466 Schema schema = Schema::Parse(kTestSchema, &error); | 507 Schema schema = Schema::Parse(kTestSchema, &error); |
467 ASSERT_TRUE(schema.valid()) << error; | 508 ASSERT_TRUE(schema.valid()) << error; |
468 | 509 |
469 base::DictionaryValue bundle; | 510 base::DictionaryValue bundle; |
470 EXPECT_TRUE(schema.Validate(bundle)); | 511 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, true); |
471 | 512 |
472 // Wrong type, expected integer. | 513 // Wrong type, expected integer. |
473 bundle.SetBoolean("Integer", true); | 514 bundle.SetBoolean("Integer", true); |
474 EXPECT_FALSE(schema.Validate(bundle)); | 515 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
475 | 516 |
476 // Wrong type, expected list of strings. | 517 // Wrong type, expected list of strings. |
477 { | 518 { |
478 bundle.Clear(); | 519 bundle.Clear(); |
479 base::ListValue list; | 520 base::ListValue list; |
480 list.AppendInteger(1); | 521 list.AppendInteger(1); |
481 bundle.Set("Array", list.DeepCopy()); | 522 bundle.Set("Array", list.DeepCopy()); |
482 EXPECT_FALSE(schema.Validate(bundle)); | 523 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
483 } | 524 } |
484 | 525 |
485 // Wrong type in a sub-object. | 526 // Wrong type in a sub-object. |
486 { | 527 { |
487 bundle.Clear(); | 528 bundle.Clear(); |
488 base::DictionaryValue dict; | 529 base::DictionaryValue dict; |
489 dict.SetString("one", "one"); | 530 dict.SetString("one", "one"); |
490 bundle.Set("Object", dict.DeepCopy()); | 531 bundle.Set("Object", dict.DeepCopy()); |
491 EXPECT_FALSE(schema.Validate(bundle)); | 532 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
492 } | 533 } |
493 | 534 |
494 // Unknown name. | 535 // Unknown name. |
495 bundle.Clear(); | 536 bundle.Clear(); |
496 bundle.SetBoolean("Unknown", true); | 537 bundle.SetBoolean("Unknown", true); |
497 EXPECT_FALSE(schema.Validate(bundle)); | 538 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
498 | 539 |
499 // All of these will be valid. | 540 // All of these will be valid. |
500 bundle.Clear(); | 541 bundle.Clear(); |
501 bundle.SetBoolean("Boolean", true); | 542 bundle.SetBoolean("Boolean", true); |
502 bundle.SetInteger("Integer", 123); | 543 bundle.SetInteger("Integer", 123); |
503 bundle.Set("Null", base::Value::CreateNullValue()); | 544 bundle.Set("Null", base::Value::CreateNullValue()); |
504 bundle.Set("Number", base::Value::CreateDoubleValue(3.14)); | 545 bundle.Set("Number", base::Value::CreateDoubleValue(3.14)); |
505 bundle.SetString("String", "omg"); | 546 bundle.SetString("String", "omg"); |
506 | 547 |
507 { | 548 { |
(...skipping 30 matching lines...) Expand all Loading... | |
538 dict.SetString("additionally", "a string"); | 579 dict.SetString("additionally", "a string"); |
539 dict.SetString("and also", "another string"); | 580 dict.SetString("and also", "another string"); |
540 bundle.Set("Object", dict.DeepCopy()); | 581 bundle.Set("Object", dict.DeepCopy()); |
541 } | 582 } |
542 | 583 |
543 bundle.SetInteger("IntegerWithEnums", 1); | 584 bundle.SetInteger("IntegerWithEnums", 1); |
544 bundle.SetInteger("IntegerWithEnumsGaps", 20); | 585 bundle.SetInteger("IntegerWithEnumsGaps", 20); |
545 bundle.SetString("StringWithEnums", "two"); | 586 bundle.SetString("StringWithEnums", "two"); |
546 bundle.SetInteger("IntegerWithRange", 3); | 587 bundle.SetInteger("IntegerWithRange", 3); |
547 | 588 |
548 EXPECT_TRUE(schema.Validate(bundle)); | 589 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, true); |
549 | |
550 bundle.SetString("boom", "bang"); | |
551 EXPECT_FALSE(schema.Validate(bundle)); | |
552 bundle.Remove("boom", NULL); | |
553 | 590 |
554 bundle.SetInteger("IntegerWithEnums", 0); | 591 bundle.SetInteger("IntegerWithEnums", 0); |
555 EXPECT_FALSE(schema.Validate(bundle)); | 592 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
556 bundle.SetInteger("IntegerWithEnums", 1); | 593 bundle.SetInteger("IntegerWithEnums", 1); |
557 | 594 |
558 bundle.SetInteger("IntegerWithEnumsGaps", 0); | 595 bundle.SetInteger("IntegerWithEnumsGaps", 0); |
559 EXPECT_FALSE(schema.Validate(bundle)); | 596 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
560 bundle.SetInteger("IntegerWithEnumsGaps", 9); | 597 bundle.SetInteger("IntegerWithEnumsGaps", 9); |
561 EXPECT_FALSE(schema.Validate(bundle)); | 598 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
562 bundle.SetInteger("IntegerWithEnumsGaps", 10); | 599 bundle.SetInteger("IntegerWithEnumsGaps", 10); |
563 EXPECT_TRUE(schema.Validate(bundle)); | 600 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, true); |
564 bundle.SetInteger("IntegerWithEnumsGaps", 11); | 601 bundle.SetInteger("IntegerWithEnumsGaps", 11); |
565 EXPECT_FALSE(schema.Validate(bundle)); | 602 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
566 bundle.SetInteger("IntegerWithEnumsGaps", 19); | 603 bundle.SetInteger("IntegerWithEnumsGaps", 19); |
567 EXPECT_FALSE(schema.Validate(bundle)); | 604 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
568 bundle.SetInteger("IntegerWithEnumsGaps", 21); | 605 bundle.SetInteger("IntegerWithEnumsGaps", 21); |
569 EXPECT_FALSE(schema.Validate(bundle)); | 606 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
570 bundle.SetInteger("IntegerWithEnumsGaps", 29); | 607 bundle.SetInteger("IntegerWithEnumsGaps", 29); |
571 EXPECT_FALSE(schema.Validate(bundle)); | 608 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
572 bundle.SetInteger("IntegerWithEnumsGaps", 30); | 609 bundle.SetInteger("IntegerWithEnumsGaps", 30); |
573 EXPECT_TRUE(schema.Validate(bundle)); | 610 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, true); |
574 bundle.SetInteger("IntegerWithEnumsGaps", 31); | 611 bundle.SetInteger("IntegerWithEnumsGaps", 31); |
575 EXPECT_FALSE(schema.Validate(bundle)); | 612 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
576 bundle.SetInteger("IntegerWithEnumsGaps", 100); | 613 bundle.SetInteger("IntegerWithEnumsGaps", 100); |
577 EXPECT_FALSE(schema.Validate(bundle)); | 614 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
578 bundle.SetInteger("IntegerWithEnumsGaps", 20); | 615 bundle.SetInteger("IntegerWithEnumsGaps", 20); |
579 | 616 |
580 bundle.SetString("StringWithEnums", "FOUR"); | 617 bundle.SetString("StringWithEnums", "FOUR"); |
581 EXPECT_FALSE(schema.Validate(bundle)); | 618 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
582 bundle.SetString("StringWithEnums", "two"); | 619 bundle.SetString("StringWithEnums", "two"); |
583 | 620 |
584 bundle.SetInteger("IntegerWithRange", 4); | 621 bundle.SetInteger("IntegerWithRange", 4); |
585 EXPECT_FALSE(schema.Validate(bundle)); | 622 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); |
586 bundle.SetInteger("IntegerWithRange", 3); | 623 bundle.SetInteger("IntegerWithRange", 3); |
587 | 624 |
625 // Unknown top level property. | |
626 bundle.SetString("boom", "bang"); | |
627 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); | |
628 TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, true); | |
629 TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_UNKNOWN, true); | |
630 bundle.Remove("boom", NULL); | |
631 | |
632 // Invalid top level property. | |
633 bundle.SetInteger("Boolean", 12345); | |
634 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); | |
635 TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_INVALID_TOPLEVEL, true); | |
636 TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_INVALID, true); | |
637 bundle.SetBoolean("Boolean", true); | |
638 | |
639 // Unknown property. | |
640 bundle.SetBoolean("ObjectOfObject.Object.three", false); | |
641 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); | |
642 TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, false); | |
643 TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_UNKNOWN, true); | |
644 bundle.Remove("ObjectOfObject.Object.three", NULL); | |
645 | |
646 // Invalid property. | |
647 bundle.SetInteger("ObjectOfObject.Object.one", 12345); | |
648 TestSchemaValidation(schema, bundle, SCHEMA_VERY_STRICT, false); | |
649 TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_INVALID_TOPLEVEL, false); | |
650 TestSchemaValidation(schema, bundle, SCHEMA_ALLOW_INVALID, true); | |
651 bundle.Remove("ObjectOfObject.Object.one", NULL); | |
588 } | 652 } |
653 | |
589 TEST(SchemaTest, InvalidReferences) { | 654 TEST(SchemaTest, InvalidReferences) { |
590 // References to undeclared schemas fail. | 655 // References to undeclared schemas fail. |
591 EXPECT_TRUE(ParseFails( | 656 EXPECT_TRUE(ParseFails( |
592 "{" | 657 "{" |
593 " \"type\": \"object\"," | 658 " \"type\": \"object\"," |
594 " \"properties\": {" | 659 " \"properties\": {" |
595 " \"name\": { \"$ref\": \"undeclared\" }" | 660 " \"name\": { \"$ref\": \"undeclared\" }" |
596 " }" | 661 " }" |
597 "}")); | 662 "}")); |
598 | 663 |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
838 | 903 |
839 EXPECT_FALSE(ParseFails(SchemaObjectWrapper( | 904 EXPECT_FALSE(ParseFails(SchemaObjectWrapper( |
840 "{" | 905 "{" |
841 " \"type\": \"integer\"," | 906 " \"type\": \"integer\"," |
842 " \"minimum\": 10," | 907 " \"minimum\": 10," |
843 " \"maximum\": 20" | 908 " \"maximum\": 20" |
844 "}"))); | 909 "}"))); |
845 } | 910 } |
846 | 911 |
847 } // namespace policy | 912 } // namespace policy |
OLD | NEW |