Merge "Fix json schema nullable to add None to ENUM"

This commit is contained in:
Zuul 2018-04-18 20:55:15 +00:00 committed by Gerrit Code Review
commit 395c7088c2
3 changed files with 53 additions and 3 deletions

View File

@ -40,6 +40,14 @@ def nullable(property_schema):
# do that yet so I'm not wasting time on it
new_schema = property_schema.copy()
new_schema['type'] = [property_schema['type'], 'null']
# NOTE(kmalloc): If enum is specified (such as our boolean case) ensure we
# add null to the enum as well so that null can be passed/validated as
# expected. Without adding to the enum, null will not validate as enum is
# explicitly listing valid values. According to the JSON Schema
# specification, the values must be unique in the enum array.
if 'enum' in new_schema and None not in new_schema['enum']:
# In the enum the 'null' is NoneType
new_schema['enum'].append(None)
return new_schema

View File

@ -11,6 +11,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
import uuid
from keystone.application_credential import schema as app_cred_schema
@ -109,6 +110,43 @@ _INVALID_FILTERS = ['some string', 1, 0, True, False]
_INVALID_NAMES = [True, 24, ' ', '']
class CommonValidationTestCase(unit.BaseTestCase):
def test_nullable_type_only(self):
bool_without_enum = copy.deepcopy(parameter_types.boolean)
bool_without_enum.pop('enum')
schema_type_only = {
'type': 'object',
'properties': {'test': validation.nullable(bool_without_enum)},
'additionalProperties': False,
'required': ['test']}
# Null should be in the types
self.assertIn('null', schema_type_only['properties']['test']['type'])
# No Enum, and nullable should not have added it.
self.assertNotIn('enum', schema_type_only['properties']['test'].keys())
validator = validators.SchemaValidator(schema_type_only)
reqs_to_validate = [{'test': val} for val in [True, False, None]]
for req in reqs_to_validate:
validator.validate(req)
def test_nullable_with_enum(self):
schema_with_enum = {
'type': 'object',
'properties': {
'test': validation.nullable(parameter_types.boolean)},
'additionalProperties': False,
'required': ['test']}
# Null should be in enum and type
self.assertIn('null', schema_with_enum['properties']['test']['type'])
self.assertIn(None, schema_with_enum['properties']['test']['enum'])
validator = validators.SchemaValidator(schema_with_enum)
reqs_to_validate = [{'test': val} for val in [True, False, None]]
for req in reqs_to_validate:
validator.validate(req)
class EntityValidationTestCase(unit.BaseTestCase):
def setUp(self):
@ -1945,9 +1983,7 @@ class UserValidationTestCase(unit.BaseTestCase):
ro.IGNORE_CHANGE_PASSWORD_OPT.option_name: None
}
}
self.assertRaises(exception.SchemaValidationError,
self.create_user_validator.validate,
request_to_validate)
self.create_user_validator.validate(request_to_validate)
def test_user_update_with_options_change_password_required(self):
request_to_validate = {

View File

@ -0,0 +1,6 @@
---
fixes:
- |
[`bug 1763824 <https://bugs.launchpad.net/keystone/+bug/1763824>`_]
JSON Schema implementation ``nullable`` in keystone.common.validation now
properly adds ``None`` to the enum if the enum exists.