def test_unique_items_validation_with_duplicates(value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description': 'id', 'type': ARRAY, 'required': True, 'uniqueItems': True, 'items': { 'type': [STRING, NUMBER, BOOLEAN] }, }, ]) parameter_values = { 'id': value, } with pytest.raises(ValidationError) as err: validate_parameters(parameter_values, parameters, {}) assert_message_in_errors( MESSAGES['unique_items']['invalid'], err.value.detail, 'id.uniqueItems', )
def test_parameter_schema_validation_for_invalid_value(value, error_key, message_key): parameters = parameters_validator([ { 'name': 'id', 'in': BODY, 'description': 'id', 'required': True, 'schema': { 'type': STRING, 'format': 'uuid' }, }, ]) parameter_values = { 'id': value, } with pytest.raises(ValidationError) as err: validate_parameters(parameter_values, parameters, context={}) assert_message_in_errors( MESSAGES[error_key][message_key], err.value.messages, 'id.{0}'.format(error_key), )
def test_parameter_items_validation_on_invalid_array(): parameters = parameters_validator([ { 'name': 'id', 'in': QUERY, 'description': 'id', 'items': { 'type': INTEGER, 'minimum': 0, }, 'type': ARRAY, }, ]) value = [1, 2, '3', -1, 4] parameter_values = { 'id': value, } with pytest.raises(ValidationError) as err: validate_parameters(parameter_values, parameters, context={}) assert_message_in_errors( MESSAGES['minimum']['invalid'], err.value.detail, 'id.items.type', ) assert_message_in_errors( MESSAGES['minimum']['invalid'], err.value.detail, 'id.items.minimum', )
def test_nullable_enum_with_invalid_values(enum, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description': 'id', 'type': [STRING, NUMBER, BOOLEAN], 'required': True, 'enum': enum, 'x-nullable': True }, ]) parameter_values = { 'id': value, } with pytest.raises(ValidationError) as err: validate_parameters(parameter_values, parameters, {}) assert_message_in_errors( MESSAGES['enum']['invalid'], err.value.detail, 'id.enum', )
def test_parameter_schema_validation_on_valid_values(value): parameters = parameters_validator( [{"name": "id", "in": BODY, "description": "id", "required": True, "schema": {"type": STRING, "format": "uri"}}] ) parameter_values = {"id": value} validate_parameters(parameter_values, parameters, context={})
def test_nullable_enum_with_null_values_strict(enum, value, monkeypatch): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description': 'id', 'type': [STRING, NUMBER, BOOLEAN], 'required': True, 'enum': enum, 'x-nullable': True }, ]) parameter_values = { 'id': value, } monkeypatch.setattr(os, 'environ', {FLEX_DISABLE_X_NULLABLE: '1'}) with pytest.raises(ValidationError) as err: validate_parameters(parameter_values, parameters, {}) assert_message_in_errors( MESSAGES['enum']['invalid'], err.value.detail, 'id.enum', )
def test_max_items_on_values_with_too_many_items(max_items, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description': 'id', 'type': ARRAY, 'required': True, 'maxItems': max_items, 'items': { 'type': STRING }, }, ]) parameter_values = { 'id': value, } with pytest.raises(ValidationError) as err: validate_parameters(parameter_values, parameters, {}) assert_message_in_errors( MESSAGES['max_items']['invalid'], err.value.detail, 'id.maxItems', )
def test_params_do_not_match_across_slashes(): path = '/get/{username}/posts/{id}' parameters = parameters_validator([USERNAME_IN_PATH, ID_IN_PATH]) pattern = path_to_pattern(path, parameters) assert re.match(pattern, '/get/simon/posts/123') # {id} should not expand to "/123/unread". assert not re.match(pattern, '/get/simon/posts/123/unread')
def test_undeclared_api_path_parameters_are_skipped(): """ Test that parameters that are declared in the path string but do not appear in the parameter definitions are ignored. """ path = '/get/{username}/posts/{id}/' parameters = parameters_validator([ID_IN_PATH]) pattern = path_to_pattern(path, parameters) assert pattern == '^/get/\{username\}/posts/(?P<id>.+)/$'
def test_parameter_validation_with_correct_type(type_, value): parameters = parameters_validator([ {'name': 'id', 'in': PATH, 'description': 'id', 'type': type_, 'required': True}, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_undeclared_api_path_parameters_are_skipped(): """ Test that parameters that are declared in the path string but do not appear in the parameter definitions are ignored. """ path = '/get/{username}/posts/{id}/' parameters = parameters_validator([ID_IN_PATH]) pattern = path_to_pattern(path, parameters) assert pattern == '^/get/\{username\}/posts/(?P<id>[^/]+)/$'
def test_boolean_type_casting(input_, expected): parameters = parameters_validator([{ 'type': BOOLEAN, 'in': QUERY, 'description': 'id', 'name': 'id', }]) parameter = {'id': input_} actual = type_cast_parameters(parameter, parameters, {}) assert actual['id'] == expected
def test_number_type_casting(): parameters = parameters_validator([{ 'type': NUMBER, 'in': QUERY, 'description': 'id', 'name': 'id', }]) parameter = {'id': '12.5'} actual = type_cast_parameters(parameter, parameters, {}) assert actual['id'] == 12.5
def test_find_parameter(lookup_kwargs, expected): parameters = parameters_validator([ ID_IN_PATH, USERNAME_IN_PATH, PAGE_IN_QUERY, PAGE_SIZE_IN_QUERY, ]) actual = find_parameter(parameters, **lookup_kwargs) for key in lookup_kwargs: assert actual[key] == expected[key]
def test_path_to_pattern_with_multiple_parameters(): input_ = '/get/{first_id}/then/{second_id}/' expected = '^/get/(?P<first_id>[^/]+)/then/(?P<second_id>[^/]+)/$' parameters = parameters_validator([ {'required': True, 'name': 'first_id', 'in': 'path', 'type': STRING}, {'required': True, 'name': 'second_id', 'in': 'path', 'type': STRING}, ]) actual = path_to_pattern(input_, parameters=parameters) assert actual == expected
def test_parameter_schema_as_reference_validation_for_invalid_value(value, error_key, message_key): context = {"definitions": {"UUID": {"type": STRING, "format": "uuid"}}} parameters = parameters_validator( [{"name": "id", "in": BODY, "description": "id", "required": True, "schema": {"$ref": "#/definitions/UUID"}}], context=context, ) parameter_values = {"id": value} with pytest.raises(ValidationError) as err: validate_parameters(parameter_values, parameters, context=context) assert_message_in_errors(MESSAGES[error_key][message_key], err.value.messages, "id.{0}".format(error_key))
def test_find_parameter_errors_when_no_match_found(): parameters = parameters_validator([ ID_IN_PATH, USERNAME_IN_PATH, PAGE_IN_QUERY, PAGE_SIZE_IN_QUERY, ]) #sanity check assert not filter_parameters(parameters, name='not-in-parameters') with pytest.raises(ValueError): find_parameter(parameters, name='not-in-parameters')
def test_path_to_pattern_with_single_parameter(): input_ = '/get/{id}' expected = '^/get/(?P<id>[^/]+)$' parameters = parameters_validator([{ 'required': True, 'type': STRING, 'name': 'id', 'in': 'path', }]) actual = path_to_pattern(input_, parameters=parameters) assert actual == expected
def test_filtering_parameters(lookup_kwargs, expected): parameters = parameters_validator([ ID_IN_PATH, USERNAME_IN_PATH, PAGE_IN_QUERY, PAGE_SIZE_IN_QUERY, ]) results = filter_parameters(parameters, **lookup_kwargs) assert len(results) == 1 for key in lookup_kwargs: assert results[0][key] == expected[key]
def test_find_parameter_errors_when_multiple_found(): parameters = parameters_validator([ ID_IN_PATH, USERNAME_IN_PATH, PAGE_IN_QUERY, PAGE_SIZE_IN_QUERY, ]) #sanity check sanity = filter_parameters(parameters, in_=PATH) assert len(sanity) == 2 with pytest.raises(ValueError): find_parameter(parameters, in_=PATH)
def test_array_type_casting(format_, value): parameters = parameters_validator([{ 'type': ARRAY, 'collectionFormat': format_, 'in': QUERY, 'description': 'id', 'name': 'id', 'items': { 'type': INTEGER }, }]) parameter = {'id': value} actual = type_cast_parameters(parameter, parameters, {}) assert actual['id'] == [1, 2, 3]
def test_required_parameters_invalid_when_not_present(): parameters = parameters_validator([ {'name': 'id', 'in': PATH, 'description': 'id', 'type': STRING, 'required': True}, ]) parameter_values = {} with pytest.raises(ValidationError) as err: validate_parameters(parameter_values, parameters, {}) assert_message_in_errors( MESSAGES['required']['required'], err.value.detail, 'id.required', )
def test_merge_parameters_uses_last_write_wins(): duplicate_a = { 'name': 'duplicate', 'in': PATH, 'description': 'duplicate_a', 'type': INTEGER, 'required': True } duplicate_b = { 'name': 'duplicate', 'in': PATH, 'description': 'duplicate_b', 'type': STRING, 'required': True } main_parameters = parameters_validator([ ID_IN_PATH, USERNAME_IN_PATH, duplicate_a, PAGE_IN_QUERY, ]) sub_parameters = parameters_validator([ duplicate_b, PAGE_SIZE_IN_QUERY, ]) merged_parameters = merge_parameter_lists(main_parameters, sub_parameters) assert len(merged_parameters) == 5 assert find_parameter(merged_parameters, description='duplicate_b') assert not filter_parameters(merged_parameters, description='duplicate_a') assert find_parameter(merged_parameters, in_=PATH, name='id') assert find_parameter(merged_parameters, in_=PATH, name='username') assert find_parameter(merged_parameters, in_=QUERY, name='page') assert find_parameter(merged_parameters, in_=QUERY, name='page_size')
def test_parameter_validation_with_correct_type(type_, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description': 'id', 'type': type_, 'required': True }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_parameters_allowed_missing_when_not_required(): parameters = parameters_validator([ { 'name': 'id', 'in': BODY, 'description': 'id', 'type': STRING, 'required': False, 'schema': { 'type': STRING, }, }, ]) parameter_values = {} validate_parameters(parameter_values, parameters, {})
def test_parameter_format_validation_succeeds_on_valid_values(format_, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description': 'id', 'type': STRING, 'required': True, 'format': format_, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_minimum_length_validation_with_valid_lengths(min_length, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description':'id', 'type': STRING, 'required': True, 'minLength': min_length, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_pattern_validation_with_matching_values(pattern, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description':'id', 'type': STRING, 'required': True, 'pattern': pattern, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_multiple_of_validation_for_valid_multiples(divisor, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description':'id', 'type': NUMBER, 'required': True, 'multipleOf': divisor, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_enum_validation_with_allowed_values(enum, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description': 'id', 'type': [STRING, NUMBER, BOOLEAN], 'required': True, 'enum': enum, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_parameter_validation_enforces_type(type_, value): parameters = parameters_validator([ {'name': 'id', 'in': PATH, 'description': 'id', 'type': type_, 'required': True}, ]) parameter_values = { 'id': value, } with pytest.raises(ValidationError) as err: validate_parameters(parameter_values, parameters, {}) assert_message_in_errors( MESSAGES['type']['invalid'], err.value.detail, 'id.type', )
def test_maximum_validation_for_valid_values(maximum, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description':'id', 'type': NUMBER, 'required': True, 'maximum': maximum, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_array_type_casting(format_, value): parameters = parameters_validator( [ { "type": ARRAY, "collectionFormat": format_, "in": QUERY, "description": "id", "name": "id", "items": {"type": INTEGER}, } ] ) parameter = {"id": value} actual = type_cast_parameters(parameter, parameters, {}) assert actual["id"] == [1, 2, 3]
def test_unique_items_validation_with_no_duplicates(value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description':'id', 'type': ARRAY, 'required': True, 'uniqueItems': True, 'items': {'type': [STRING, NUMBER, BOOLEAN]}, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_local_parameter_values_override_schema(value): parameters = parameters_validator( [ { "name": "id", "in": BODY, "description": "id", "required": True, "type": INTEGER, "format": INT32, "schema": {"type": STRING, "format": "uuid"}, } ] ) parameter_values = {"id": value} validate_parameters(parameter_values, parameters, context={})
def test_getting_parameter_values_from_path(): parameters = parameters_validator([ ID_IN_PATH, USERNAME_IN_PATH, ]) values = get_path_parameter_values( target_path='/get/fernando/posts/1234/', api_path='/get/{username}/posts/{id}/', path_parameters=parameters, context={}, ) assert len(values) == 2 assert 'username' in values assert 'id' in values assert isinstance(values['username'], six.string_types) assert isinstance(values['id'], int)
def test_min_items_on_values_with_valid_array_length(min_items, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description':'id', 'type': ARRAY, 'required': True, 'minItems': min_items, 'items': {'type': STRING}, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_parameter_schema_validation_for_invalid_value(value, error_key, message_key): parameters = parameters_validator( [ { "name": "id", "in": BODY, "description": "id", "required": True, "schema": {"type": STRING, "format": "uuid"}, } ] ) parameter_values = {"id": value} with pytest.raises(ValidationError) as err: validate_parameters(parameter_values, parameters, context={}) assert_message_in_errors(MESSAGES[error_key][message_key], err.value.messages, "id.{0}".format(error_key))
def test_parameter_schema_validation_on_valid_values(value): parameters = parameters_validator([ { 'name': 'id', 'in': BODY, 'description': 'id', 'required': True, 'schema': { 'type': STRING, 'format': 'uri', }, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, context={})
def test_unique_items_validation_with_no_duplicates(value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description': 'id', 'type': ARRAY, 'required': True, 'uniqueItems': True, 'items': { 'type': [STRING, NUMBER, BOOLEAN] }, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})
def test_min_items_on_values_with_valid_array_length(min_items, value): parameters = parameters_validator([ { 'name': 'id', 'in': PATH, 'description': 'id', 'type': ARRAY, 'required': True, 'minItems': min_items, 'items': { 'type': STRING }, }, ]) parameter_values = { 'id': value, } validate_parameters(parameter_values, parameters, {})