def test_security_parameter_cannot_override_path_or_operation_parameter( security_dict, ): security_dict['paths']['/example1']['get']['parameters'] = [{ 'description': 'sec1 as query parameter', 'required': True, 'in': 'query', 'type': 'integer', 'name': 'apiKey1', }] with pytest.raises(SwaggerSchemaError): Spec.from_dict(security_dict)
def test_validate_config_fail( mock_warnings, minimal_swagger_dict, minimal_swagger_abspath, config, expected_different_config, expected_warnings_call, ): spec = Spec.from_dict(minimal_swagger_dict, origin_url=get_url(minimal_swagger_abspath), config=config) assert (spec.config != dict(CONFIG_DEFAULTS, **config)) is expected_different_config mock_warnings.warn.assert_called_once_with(message=expected_warnings_call, category=Warning)
def multi_file_multi_directory_spec(request, multi_file_multi_directory_dict, multi_file_multi_directory_abspath): return Spec.from_dict( multi_file_multi_directory_dict, origin_url=get_url(multi_file_multi_directory_abspath), config={'internally_dereference_refs': request.param}, )
def test_ensure_polymorphic_objects_are_correctly_build_in_case_of_fully_dereferenced_specs( polymorphic_dict, validate_responses, use_models, internally_dereference_refs, ): raw_response = [{'name': 'name', 'type': 'Dog', 'birth_date': '2017-11-02'}] spec = Spec.from_dict( spec_dict=polymorphic_dict, config={ 'validate_responses': validate_responses, 'use_models': use_models, 'internally_dereference_refs': internally_dereference_refs, }, origin_url='', ) response = Mock( spec=IncomingResponse, status_code=200, headers={'content-type': APP_JSON}, json=Mock(return_value=raw_response), ) unmarshaled_response = unmarshal_response(response, spec.resources['pets'].get_pets) if use_models: assert repr(unmarshaled_response) == "[Dog(birth_date=datetime.date(2017, 11, 2), name='name', type='Dog')]" else: assert unmarshaled_response == raw_response
def test_missing_object_spec_defaulting_on(petstore_dict): """When default_type_to_object config option is set to True, then missing types default to object """ petstore_spec = Spec.from_dict(petstore_dict, config={'use_models': False, 'default_type_to_object': True}) category_spec = copy.deepcopy( petstore_spec.spec_dict['definitions']['Category'] ) # now a missing type will default to object type category_spec['properties']['id'].pop('type') result = unmarshal_schema_object( petstore_spec, category_spec, {'id': {'foo': 'bar'}, 'name': 'short-hair'}) assert result == {'id': {'foo': 'bar'}, 'name': 'short-hair'} # so a different type will fail with pytest.raises(SwaggerMappingError): result = unmarshal_schema_object( petstore_spec, category_spec, {'id': 'blahblah', 'name': 'short-hair'})
def test_model_equality_if_model_class_generated_by_different_Spec_object( cat_swagger_spec, cat_type, cat_kwargs): cat = cat_type(**cat_kwargs) new_cat_spec = Spec.from_dict(cat_swagger_spec.client_spec_dict) new_cat_type = new_cat_spec.definitions['Cat'] new_cat = new_cat_type(**cat_kwargs) assert cat == new_cat
def test_produces_on_op_overrides_produces_from_swagger_spec( minimal_swagger_dict): op_spec = {'produces': ['application/xml']} minimal_swagger_dict['produces'] = ['application/json'] minimal_swagger_spec = Spec.from_dict(minimal_swagger_dict) op = Operation(minimal_swagger_spec, '/foo', 'get', op_spec) assert ['application/xml'] == op.produces
def from_spec(cls, spec_dict, origin_url=None, http_client=None, config=None): """ Build a :class:`SwaggerClient` from a Swagger spec in dict form. :param spec_dict: a dict with a Swagger spec in json-like form :param origin_url: the url used to retrieve the spec_dict :type origin_url: str :param config: Configuration dict - see spec.CONFIG_DEFAULTS :rtype: :class:`bravado_core.spec.Spec` """ http_client = http_client or RequestsClient() # Apply bravado config defaults config = dict(CONFIG_DEFAULTS, **(config or {})) also_return_response = config.pop('also_return_response', False) swagger_spec = Spec.from_dict( spec_dict, origin_url, http_client, config, ) return cls(swagger_spec, also_return_response=also_return_response)
def test_composition(minimal_swagger_dict, address_spec, address, business_address_spec, business_address): minimal_swagger_dict['definitions']['Address'] = address_spec minimal_swagger_dict['definitions'][ 'BusinessAddress'] = business_address_spec swagger_spec = Spec.from_dict(minimal_swagger_dict) expected_spec_1 = address_spec['properties']['street_name'] result_1 = get_spec_for_prop( swagger_spec, address_spec, address, 'street_name', ) assert expected_spec_1 == result_1 expected_spec_2 = business_address_spec['allOf'][1]['properties'][ 'company'] result_2 = get_spec_for_prop( swagger_spec, business_address_spec, business_address, 'company', ) assert expected_spec_2 == result_2
def test_array_of_models(petstore_dict): petstore_spec = Spec.from_dict(petstore_dict) Pet = petstore_spec.definitions['Pet'] Category = petstore_spec.definitions['Category'] Tag = petstore_spec.definitions['Tag'] array_of_pets_spec = { 'type': 'array', 'items': petstore_spec.spec_dict['definitions']['Pet'] } fido = Pet( id=1, name='Fido', status='sold', photoUrls=['wagtail.png', 'bark.png'], category=Category(id=200, name='friendly'), tags=[ Tag(id=99, name='mini'), Tag(id=100, name='brown') ] ) darwin = Pet( id=2, name='Darwin', status='pending', photoUrls=['snausages.png', 'bacon.png'], category=Category(id=300, name='mascot'), tags=[], ) sumi = Pet( id=3, name='Sumi', status='available', photoUrls=['puggies.png', 'bumblebee.png'], category=Category(id=400, name='pugly'), tags=[ Tag(id=101, name='sumiwoo'), ], ) pets = [fido, darwin, sumi] result = marshal_array(petstore_spec, array_of_pets_spec, pets) for i, expected in enumerate(pets): actual = result[i] assert expected.name == actual['name'] assert expected.id == actual['id'] assert expected.photoUrls == actual['photoUrls'] assert expected.status == actual['status'] for j, expected_tag in enumerate(expected.tags): actual_tag = actual['tags'][j] assert expected_tag.id == actual_tag['id'] assert expected_tag.name == actual_tag['name'] assert expected.category.id == actual['category']['id'] assert expected.category.name == actual['category']['name']
def test_ref(minimal_swagger_dict): foo_spec = { 'type': 'object', } minimal_swagger_dict['definitions']['Foo'] = foo_spec swagger_spec = Spec.from_dict(minimal_swagger_dict) assert swagger_spec.deref({'$ref': '#/definitions/Foo'}) == foo_spec
def generate_cli(spec): origin_url = None if isinstance(spec, str): if spec.startswith('https://') or spec.startswith('http://'): origin_url = spec r = requests.get(spec) r.raise_for_status() spec = yaml.safe_load(r.text) else: with open(spec, 'rb') as fd: spec = yaml.safe_load(fd.read()) spec = sanitize_spec(spec) cli = clickclick.AliasedGroup(context_settings=CONTEXT_SETTINGS) spec = Spec.from_dict(spec, origin_url=origin_url) for res_name, res in spec.resources.items(): grp = clickclick.AliasedGroup(normalize_command_name(res_name), short_help='Manage {}'.format(res_name)) cli.add_command(grp) for op_name, op in res.operations.items(): name = get_command_name(op) cmd = click.Command(name, callback=partial(invoke, op=op), short_help=op.op_spec.get('summary')) for param_name, param in op.params.items(): if param.required: arg = click.Argument([param.name]) cmd.params.append(arg) else: arg = click.Option(['--' + param.name]) cmd.params.append(arg) grp.add_command(cmd) return cli
def test_defaultdicts_can_be_used_instead_of_models(petstore_dict): petstore_spec = Spec.from_dict(petstore_dict) pet_spec = petstore_spec.spec_dict['definitions']['Pet'] pet = defaultdict( None, { 'id': 1, 'name': 'Fido', 'status': 'sold', 'photoUrls': ['wagtail.png', 'bark.png'], 'category': { 'id': 200, 'name': 'friendly', }, 'tags': [ { 'id': 99, 'name': 'mini' }, { 'id': 100, 'name': 'brown' }, ], }) expected = copy.deepcopy(pet) result = marshal_schema_object(petstore_spec, pet_spec, pet) assert expected == result
def test_returns_consumes_from_op(minimal_swagger_dict): op_spec = { 'consumes': ['multipart/form-data'] } minimal_swagger_spec = Spec.from_dict(minimal_swagger_dict) op = Operation(minimal_swagger_spec, '/foo', 'get', op_spec) assert ['multipart/form-data'] == op.consumes
def test_use_models_false(petstore_dict): petstore_spec = Spec.from_dict(petstore_dict, config={"use_models": False}) category_spec = petstore_spec.spec_dict["definitions"]["Category"] result = unmarshal_schema_object(petstore_spec, category_spec, {"id": 200, "name": "short-hair"}) assert isinstance(result, dict)
def test_override(minimal_swagger_dict): class Byte(object): def __init__(self, x): self.x = x def __str__(self): return str(self.x) def __repr__(self): return '%s(%r)' % (self.__class__, self.x) byteformat = SwaggerFormat( format='byte', to_wire=lambda x: str(x), to_python=lambda x: Byte(x), validate=lambda x: isinstance(x, str), description=None, ) number_spec = {'type': 'string', 'format': 'byte'} swagger_spec = Spec.from_dict(minimal_swagger_dict, config={'formats': [byteformat]}) result = to_wire(swagger_spec, number_spec, '8bits') assert '8bits' == result assert isinstance(result, str) assert type(result) is StringType
def test_Nones_are_reintroduced_for_declared_properties_that_are_not_present( petstore_dict, pet_dict): petstore_spec = Spec.from_dict(petstore_dict) Pet = petstore_spec.definitions['Pet'] Tag = petstore_spec.definitions['Tag'] pet_spec = petstore_spec.spec_dict['definitions']['Pet'] # Deleting "status" and "category" from pet_dict means that should still be # attrs on Pet with a None value after unmarshaling del pet_dict['status'] del pet_dict['category'] pet = unmarshal_model(petstore_spec, pet_spec, pet_dict) assert isinstance(pet, Pet) assert 1 == pet.id assert 'Fido' == pet.name assert pet.status is None assert ['wagtail.png', 'bark.png'] == pet.photoUrls assert pet.category is None assert isinstance(pet.tags, list) assert 2 == len(pet.tags) assert isinstance(pet.tags[0], Tag) assert 99 == pet.tags[0].id assert 'mini' == pet.tags[0].name assert isinstance(pet.tags[1], Tag) assert 100 == pet.tags[1].id assert 'brown' == pet.tags[1].name
def test_object_is_ref(minimal_swagger_dict, address_spec, address): minimal_swagger_dict['definitions']['Address'] = address_spec address_ref_spec = {'$ref': '#/definitions/Address'} swagger_spec = Spec.from_dict(minimal_swagger_dict) result = get_spec_for_prop( swagger_spec, address_ref_spec, address, 'street_type') assert address_spec['properties']['street_type'] == result
def test_produces_on_op_overrides_produces_from_swagger_spec( minimal_swagger_dict, ): op_spec = {'produces': ['application/xml']} minimal_swagger_dict['produces'] = ['application/json'] minimal_swagger_spec = Spec.from_dict(minimal_swagger_dict) op = Operation(minimal_swagger_spec, '/foo', 'get', op_spec) assert ['application/xml'] == op.produces
def __init__(self): # TODO: eva.conf.settings.ROOT_PATH 有 bug, 显示的是 python3 的路径 curdir = os.path.dirname(__file__) spec_path = os.path.join(curdir, "../../codebase/schema.yml") self.spec_dict = yaml.safe_load(open(spec_path)) self.spec = Spec.from_dict(self.spec_dict)
def perf_petstore_spec(request, petstore_spec): return Spec.from_dict( spec_dict=petstore_spec.spec_dict, origin_url=petstore_spec.origin_url, config=dict(petstore_spec.config, internally_dereference_refs=request.param), )
def get_swagger_spec(settings): """Return a :class:`bravado_core.spec.Spec` constructed from the swagger specs in `pyramid_swagger.schema_directory`. If `pyramid_swagger.enable_swagger_spec_validation` is enabled the schema will be validated before returning it. :param settings: a pyramid registry settings with configuration for building a swagger schema :type settings: dict :rtype: :class:`bravado_core.spec.Spec` """ schema_dir = settings.get('pyramid_swagger.schema_directory', 'api_docs/') schema_filename = settings.get('pyramid_swagger.schema_file', 'swagger.json') schema_path = os.path.join(schema_dir, schema_filename) schema_url = urlparse.urljoin('file:', pathname2url(os.path.abspath(schema_path))) handlers = build_http_handlers(None) # don't need http_client for file: file_handler = handlers['file'] spec_dict = file_handler(schema_url) return Spec.from_dict(spec_dict, config=create_bravado_core_config(settings), origin_url=schema_url)
def test_get_spec_for_prop_with_x_nullable_and_reference(minimal_swagger_dict): # TODO: remove is_nullable support once https://github.com/Yelp/bravado-core/issues/335 is addressed minimal_swagger_dict['definitions'] = { 'referenced': { 'type': 'string', }, 'model': { 'type': 'object', 'properties': { 'property': { 'x-nullable': True, '$ref': '#/definitions/referenced', }, }, }, } swagger_spec = Spec.from_dict(minimal_swagger_dict) assert { 'x-nullable': True, 'type': 'string' } == get_spec_for_prop( swagger_spec, minimal_swagger_dict['definitions']['model'], None, 'property', )
def setUpClass(cls): # FIXME: solve memory issues from generating the spec multiple times app = BaseWebTest().make_app(settings=cls.settings) cls.spec_dict = app.get('/__api__').json cls.spec = Spec.from_dict(cls.spec_dict) cls.resources = build_resources(cls.spec)
def test_validate_object_raises_ValidationError_if_discriminator_key_is_missing( minimal_swagger_dict, ): # More context for this test on https://github.com/Yelp/bravado-core/issues/301 minimal_swagger_dict['definitions'] = { 'Model': { "type": 'object', "properties": { "discriminator_field": { "type": 'string' }, }, "discriminator": "discriminator_field", "required": ["discriminator_field"], } } spec = Spec.from_dict(minimal_swagger_dict) with pytest.raises(ValidationError) as excinfo: validate_object( swagger_spec=spec, object_spec=minimal_swagger_dict['definitions']['Model'], value={}, ) assert "'discriminator_field' is a required property" in excinfo.value.message
def __init__(self, apikey=None, headers=None, host=HOST): # - Kong forwards consumer headers when api-key used for auth # - forward consumer headers when connecting through localhost self.__dict__ = self._shared_state self.apikey = apikey self.headers = {"x-api-key": apikey} if apikey else headers self.host = host if "swagger_spec" not in self.__dict__ or ( self.headers is not None and self.swagger_spec.http_client.headers != self.headers ): http_client = FidoClientGlobalHeaders(headers=self.headers) loader = Loader(http_client) protocol = "https" if self.apikey else "http" origin_url = f"{protocol}://{self.host}/apispec.json" spec_dict = loader.load_spec(origin_url) spec_dict["host"] = self.host spec_dict["schemes"] = [protocol] config = { "validate_responses": False, "use_models": False, "include_missing_properties": False, "formats": [email_format], } bravado_config = bravado_config_from_config_dict(config) for key in set(bravado_config._fields).intersection(set(config)): del config[key] config["bravado"] = bravado_config swagger_spec = Spec.from_dict(spec_dict, origin_url, http_client, config) super().__init__( swagger_spec, also_return_response=bravado_config.also_return_response )
def test_spec_with_dereffed_and_tagged_models_works(minimal_swagger_dict): # In cases where the Swagger spec being ingested has already been de-reffed # and had models tagged with 'x-model', we still need to be able to # detect them and make them available as model types. For example, a spec # ingested via http from pyramid_swagger contains de-reffed models. pet_path_spec = { 'get': { 'responses': { '200': { 'description': 'Returns a Pet', 'schema': { MODEL_MARKER: 'Pet', 'type': 'object', 'properties': { 'name': { 'type': 'string' } } } } } } } minimal_swagger_dict['paths']['/pet'] = pet_path_spec spec = Spec.from_dict(minimal_swagger_dict) assert spec.definitions['Pet']
def test_ref_to_external_path_with_ref_to_local_model(): # Test that an an external ref to a path (in swagger.json) which contains # a local ref to a model (in pet.json) works as expected: # - model type for Pet is created # - de-reffed spec_dict contains 'x-model' annotations # # This is really a test for `tag_models`. Migrate over there # # swagger.json # paths: # /pet: # $ref: pet.json#/paths/pet (1) # # pet.json # definitions: # Pet: ... (4) # paths: (2) # ... # $ref: #/definitions/Pet (3) # my_dir = os.path.abspath(os.path.dirname(__file__)) swagger_json_path = os.path.join( my_dir, '../../test-data/2.0/x-model/swagger.json') with open(swagger_json_path) as f: swagger_json_content = json.loads(f.read()) swagger_json_url = urlparse.urljoin('file:', swagger_json_path) spec = Spec.from_dict(swagger_json_content, swagger_json_url) assert 'Pet' in spec.definitions
def from_spec(cls, spec_dict, origin_url=None, http_client=None, config=None): """ Build a :class:`SwaggerClient` from a Swagger spec in dict form. :param spec_dict: a dict with a Swagger spec in json-like form :param origin_url: the url used to retrieve the spec_dict :type origin_url: str :param config: Configuration dict - see spec.CONFIG_DEFAULTS :rtype: :class:`SwaggerClient` """ http_client = http_client or RequestsClient() config = config or {} # Apply bravado config defaults bravado_config = bravado_config_from_config_dict(config) # remove bravado configs from config dict for key in set(bravado_config._fields).intersection(set(config)): del config[key] # set bravado config object config['bravado'] = bravado_config swagger_spec = Spec.from_dict( spec_dict, origin_url, http_client, config, ) return cls(swagger_spec, also_return_response=bravado_config.also_return_response)
def get_swagger_spec(settings): """Return a :class:`bravado_core.spec.Spec` constructed from the swagger specs in `pyramid_swagger.schema_directory`. If `pyramid_swagger.enable_swagger_spec_validation` is enabled the schema will be validated before returning it. :param settings: a pyramid registry settings with configuration for building a swagger schema :type settings: dict :rtype: :class:`bravado_core.spec.Spec` """ schema_dir = settings.get('pyramid_swagger.schema_directory', 'api_docs/') schema_filename = settings.get('pyramid_swagger.schema_file', 'swagger.json') schema_path = os.path.join(schema_dir, schema_filename) schema_url = urlparse.urljoin('file:', pathname2url(os.path.abspath(schema_path))) handlers = build_http_handlers(None) # don't need http_client for file: file_handler = handlers['file'] spec_dict = file_handler(schema_url) return Spec.from_dict( spec_dict, config=create_bravado_core_config(settings), origin_url=schema_url)
def __init__(self): with open('../specs/spec_inherited.yaml', 'r') as f: self.raw_spec = yaml.load(f) self.data = self.create_json() self.spec = Spec.from_dict(self.raw_spec) self.petlist = self.raw_spec['definitions']['PetList']
def test_ref(minimal_swagger_dict): foo_spec = { 'type': 'object' } minimal_swagger_dict['definitions']['Foo'] = foo_spec swagger_spec = Spec.from_dict(minimal_swagger_dict) assert swagger_spec.deref({'$ref': '#/definitions/Foo'}) == foo_spec
def test_pet(petstore_dict, pet_dict): # Covers: # - model with primitives properties # - model with an array # - model with a nested model petstore_spec = Spec.from_dict(petstore_dict) Pet = petstore_spec.definitions['Pet'] Category = petstore_spec.definitions['Category'] Tag = petstore_spec.definitions['Tag'] pet_spec = petstore_spec.spec_dict['definitions']['Pet'] pet = unmarshal_model(petstore_spec, pet_spec, pet_dict) assert isinstance(pet, Pet) assert 1 == pet.id assert 'Fido' == pet.name assert 'sold' == pet.status assert ['wagtail.png', 'bark.png'] == pet.photoUrls assert isinstance(pet.category, Category) assert 200 == pet.category.id assert 'friendly' == pet.category.name assert isinstance(pet.tags, list) assert 2 == len(pet.tags) assert isinstance(pet.tags[0], Tag) assert 99 == pet.tags[0].id assert 'mini' == pet.tags[0].name assert isinstance(pet.tags[1], Tag) assert 100 == pet.tags[1].id assert 'brown' == pet.tags[1].name
def test_complicated_refs(): # Split the swagger spec into a bunch of different json files and use # $refs all over to place to wire stuff together - see the test-data # files or this will make no sense whatsoever. file_path = "../../test-data/2.0/simple_crossref/swagger.json" swagger_dict, origin_url = get_spec_json_and_url(file_path) swagger_spec = Spec.from_dict(swagger_dict, origin_url=origin_url) # Verify things are 'reachable' (hence, have been ingested correctly) # Resource assert swagger_spec.resources["pingpong"] # Operation op = swagger_spec.resources["pingpong"].ping assert op # Parameter assert swagger_spec.resources["pingpong"].ping.params["pung"] # Parameter name assert swagger_spec.resources["pingpong"].ping.params["pung"].name == "pung" # Response response = get_response_spec(200, op) assert response["description"] == "pong"
def test_ref_to_external_path_with_ref_to_local_model(): # Test that an an external ref to a path (in swagger.json) which contains # a local ref to a model (in pet.json) works as expected: # - model type for Pet is created # - de-reffed spec_dict contains 'x-model' annotations # # This is really a test for `tag_models`. Migrate over there # # swagger.json # paths: # /pet: # $ref: pet.json#/paths/pet (1) # # pet.json # definitions: # Pet: ... (4) # paths: (2) # ... # $ref: #/definitions/Pet (3) # my_dir = os.path.abspath(os.path.dirname(__file__)) swagger_json_path = os.path.join(my_dir, "../../test-data/2.0/x-model/swagger.json") with open(swagger_json_path) as f: swagger_json_content = json.loads(f.read()) swagger_json_url = urlparse.urljoin("file:", swagger_json_path) spec = Spec.from_dict(swagger_json_content, swagger_json_url) assert "Pet" in spec.definitions
def getOperationWithResourceAndOpName( spec, origin_url, resource, opName, ): ####+END: """Returns op object.""" pp = pprint.PrettyPrinter(indent=4) spec = Spec.from_dict(spec, origin_url=origin_url) #pp.pprint(spec) for res_name, res in list(spec.resources.items()): if res_name != resource: continue for op_name, op in list(res.operations.items()): if op_name != opName: continue name = get_command_name(op) icm.LOG_here( "Invoking: resource={resource} opName={opName}".format( resource=resource, opName=op_name)) return op
def test_returns_consumes_from_op(minimal_swagger_dict): op_spec = { 'consumes': ['multipart/form-data'], } minimal_swagger_spec = Spec.from_dict(minimal_swagger_dict) op = Operation(minimal_swagger_spec, '/foo', 'get', op_spec) assert ['multipart/form-data'] == op.consumes
def test_get_type_info_custom_format(): spec_dict = { 'swagger': '2.0', 'info': { 'title': 'Example schema', 'version': '1.0', }, 'paths': {}, 'definitions': { 'ModelWithCustomFormat': { 'type': 'object', 'properties': { 'test': { 'type': 'string', 'format': 'ipv4', }, }, }, }, } spec = Spec.from_dict(spec_dict) pschema = (spec.definitions['ModelWithCustomFormat']. _model_spec['properties']['test']) custom_formats = CustomFormats( formats={('string', 'ipv4'): 'ipaddress.IPV4Address'}, packages=('ipaddress'), ) config = Config(name='Test', path='/tmp/test.py', custom_formats=custom_formats) assert get_type_info(spec, pschema, config) == 'ipaddress.IPV4Address'
def __init__(self): with open('../specs/spec_nested.yaml', 'r') as f: self.raw_spec = yaml.load(f) self.data = self.create_json() self.spec = Spec.from_dict(self.raw_spec) self.school = self.raw_spec['definitions']['School']
def test_get_type_info(schema, expected): config = Config(name='Test', path='/tmp/test.py') spec_dict = { 'swagger': '2.0', 'info': { 'title': 'Example schema', 'version': '1.0', }, 'paths': {}, 'definitions': { 'Array': { 'type': 'array', 'items': {}, }, 'Object': { 'type': 'object', }, # Embed test case schema into schema so it get validated by # bravado-core. Use property to prevent model discovery from adding # an 'x-schema' property to object schemas. 'Nested': { 'type': 'object', 'properties': { 'test': schema, }, }, } } spec = Spec.from_dict(spec_dict) pschema = spec.definitions['Nested']._model_spec['properties']['test'] assert pschema == schema assert get_type_info(spec, pschema, config) == expected
def test_get_type_info_array_types_list(array_types, expected): spec_dict = { 'swagger': '2.0', 'info': { 'title': 'Example schema', 'version': '1.0', }, 'paths': {}, 'definitions': { 'Object': { 'type': 'object', 'properties': { # Schema to be tested 'test': { 'type': 'array', 'items': { 'type': 'string', }, }, }, }, }, } spec = Spec.from_dict(spec_dict) pschema = spec.definitions['Object']._model_spec['properties']['test'] config = Config(name='Test', path='/tmp/test.py', array_types=array_types) assert get_type_info(spec, pschema, config) == expected
def validate_event(self, raw_event: str, event_type: str) -> None: """ Checks if an event is registered and validates it based on a registered schema. Args: raw_event: The event to be validated, as a JSON-encoded string event_type: The type of an event, which corresponds to a generated model Returns: Does not return, but throws exceptions if validation fails. """ event = json.loads(raw_event) # Event not in registry if event_type not in self.event_registry: logging.debug( 'Event type %s not among registered event types (%s)', event_type, self.event_registry) raise KeyError( 'Event type {} not registered, ' 'please add it to the EventD config'.format(event_type)) # swagger_spec exists because we load it up for every event_type # in load_specs_from_registry() swagger_spec = self.event_type_to_spec[event_type] # Field and type checking bravado_spec = Spec.from_dict(swagger_spec, config={'validate_swagger_spec': False}) bravado_validate( bravado_spec, swagger_spec['definitions'][event_type], event)
def test_missing_object_spec_defaulting_on(petstore_dict): """When default_type_to_object config option is set to True, then missing types default to object """ petstore_spec = Spec.from_dict(petstore_dict, config={ 'use_models': False, 'default_type_to_object': True }) category_spec = copy.deepcopy( petstore_spec.spec_dict['definitions']['Category']) # now a missing type will default to object type category_spec['properties']['id'].pop('type') result = unmarshal_schema_object(petstore_spec, category_spec, { 'id': { 'foo': 'bar' }, 'name': 'short-hair' }) assert result == {'id': {'foo': 'bar'}, 'name': 'short-hair'} # so a different type will fail with pytest.raises(SwaggerMappingError): result = unmarshal_schema_object(petstore_spec, category_spec, { 'id': 'blahblah', 'name': 'short-hair' })
def test_complicated_refs(): # Split the swagger spec into a bunch of different json files and use # $refs all over to place to wire stuff together - see the test-data # files or this will make no sense whatsoever. file_path = '../../test-data/2.0/simple_crossref/swagger.json' swagger_dict, origin_url = get_spec_json_and_url(file_path) swagger_spec = Spec.from_dict(swagger_dict, origin_url=origin_url) # Verify things are 'reachable' (hence, have been ingested correctly) # Resource assert swagger_spec.resources['pingpong'] # Operation op = swagger_spec.resources['pingpong'].ping assert op # Parameter assert swagger_spec.resources['pingpong'].ping.params['pung'] # Parameter name assert swagger_spec.resources['pingpong'].ping.params[ 'pung'].name == 'pung' # Response response = get_response_spec(200, op) assert response['description'] == 'pong'
def assert_validate_call_count(expected_call_count, config, petstore_dict): with patch('bravado_core.param.validate_schema_object') as m_validate: petstore_spec = Spec.from_dict(petstore_dict, config=config) request = {'url': '/pet/{petId}'} op = petstore_spec.resources['pet'].operations['getPetById'] param = op.params['petId'] marshal_param(param, 34, request) assert expected_call_count == m_validate.call_count
def assert_validate_call_count(expected_call_count, config, petstore_dict): with patch("bravado_core.param.validate_schema_object") as m_validate: petstore_spec = Spec.from_dict(petstore_dict, config=config) request = {"url": "/pet/{petId}"} op = petstore_spec.resources["pet"].operations["getPetById"] param = op.params["petId"] marshal_param(param, 34, request) assert expected_call_count == m_validate.call_count
def assert_validate_call_count(expected_call_count, config, petstore_dict): with patch('bravado_core.param.validate_schema_object') as m_validate: petstore_spec = Spec.from_dict(petstore_dict, config=config) request = Mock(spec=IncomingRequest, path={'petId': 34}) op = petstore_spec.resources['pet'].operations['getPetById'] param = op.params['petId'] unmarshal_param(param, request) assert expected_call_count == m_validate.call_count
def test_value_is_not_dict_like_raises_error(petstore_dict): petstore_spec = Spec.from_dict(petstore_dict) pet_spec = petstore_spec.spec_dict['definitions']['Pet'] with pytest.raises(SwaggerMappingError) as excinfo: unmarshal_model(petstore_spec, pet_spec, 'i am not a dict') assert 'Expected type to be dict' in str(excinfo.value)
def test_ref_false(minimal_swagger_dict): minimal_swagger_dict['definitions'] = { 'Pet': { 'type': 'object', } } param_spec = {'$ref': '#/definitions/Pet'} swagger_spec = Spec.from_dict(minimal_swagger_dict) assert not is_prop_nullable(swagger_spec, param_spec)
def test_self_property_with_model(minimal_swagger_dict): link_spec = { 'type': 'object', 'required': ['_links'], 'properties': { '_links': { '$ref': '#/definitions/Self', }, }, } self_spec = { 'type': 'object', 'required': ['self'], 'properties': { 'self': { 'type': 'object', 'required': ['href'], 'properties': { 'href': { 'type': 'string', }, }, }, }, } minimal_swagger_dict['definitions']['Links'] = link_spec minimal_swagger_dict['definitions']['Self'] = self_spec self_link_response = { 'get': { 'responses': { '200': { 'description': 'A self link.', 'schema': { '$ref': '#/definitions/Links', } } } } } minimal_swagger_dict['paths']['/foo'] = self_link_response self_link_swagger_spec = Spec.from_dict(minimal_swagger_dict) href = "http://example.com" self_link_dict = { "_links": { "self": { "href": href, }, }, } self_link = unmarshal_object(self_link_swagger_spec, link_spec, self_link_dict) assert self_link["_links"].self["href"] == href
def test_returns_produces_from_swagger_spec_when_not_present_on_op( minimal_swagger_dict): op_spec = { # 'produces' left out intentionally } minimal_swagger_dict['produces'] = ['application/json'] minimal_swagger_spec = Spec.from_dict(minimal_swagger_dict) op = Operation(minimal_swagger_spec, '/foo', 'get', op_spec) assert ['application/json'] == op.produces
def test_consumes_not_present_on_swagger_spec_returns_empty_array( minimal_swagger_dict): # The point being, None should never be returned op_spec = { # 'consumes' left out intentionally } minimal_swagger_spec = Spec.from_dict(minimal_swagger_dict) op = Operation(minimal_swagger_spec, '/foo', 'get', op_spec) assert [] == op.consumes
def test_ref(minimal_swagger_dict): minimal_swagger_dict['definitions']['Int32'] = { 'type': 'integer', 'format': 'int32' } int_ref_spec = {'$ref': '#/definitions/Int32'} swagger_spec = Spec.from_dict(minimal_swagger_dict) result = to_wire(swagger_spec, int_ref_spec, 999) assert 999 == result assert isinstance(result, int)
def test_returns_consumes_from_swagger_spec_when_not_present_on_op( minimal_swagger_dict): op_spec = { # 'consumes' left out intentionally } minimal_swagger_dict['consumes'] = ['multipart/form-data'] minimal_swagger_spec = Spec.from_dict(minimal_swagger_dict) op = Operation(minimal_swagger_spec, '/foo', 'get', op_spec) assert ['multipart/form-data'] == op.consumes
def test_non_nullable_array_properties(petstore_dict, pet_dict): pet_spec_dict = petstore_dict['definitions']['Pet'] pet_spec_dict['required'].append('tags') petstore_spec = Spec.from_dict(petstore_dict) pet_spec = petstore_spec.spec_dict['definitions']['Pet'] pet_dict['tags'] = None with pytest.raises(SwaggerMappingError): unmarshal_model(petstore_spec, pet_spec, pet_dict)
def test_ref_false(minimal_swagger_dict): minimal_swagger_dict['responses'] = { 'InvalidInput': { 'description': 'Invalid input' } } response_spec = {'$ref': '#/responses/InvalidInput'} swagger_spec = Spec.from_dict(minimal_swagger_dict) assert not is_param_spec(swagger_spec, response_spec)
def test_consumes_on_op_overrides_consumes_from_swagger_spec( minimal_swagger_dict): op_spec = { 'consumes': ['application/x-www-form-urlencoded'] } minimal_swagger_dict['consumes'] = ['multipart/form-data'] minimal_swagger_spec = Spec.from_dict(minimal_swagger_dict) op = Operation(minimal_swagger_spec, '/foo', 'get', op_spec) assert ['application/x-www-form-urlencoded'] == op.consumes