Ejemplo n.º 1
0
    def test_get_pets_param_coordinates(self, spec):
        host_url = 'http://petstore.swagger.io/v1'
        path_pattern = '/v1/pets'
        coordinates = {
            'lat': 1.12,
            'lon': 32.12,
        }
        query_params = {
            'limit': None,
            'coordinates': json.dumps(coordinates),
        }

        request = MockRequest(
            host_url,
            'GET',
            '/pets',
            path_pattern=path_pattern,
            args=query_params,
        )

        parameters = validate_parameters(spec, request)

        assert parameters == RequestParameters(query={
            'limit': None,
            'page': 1,
            'search': '',
            'coordinates': coordinates,
        })

        body = validate_body(spec, request)

        assert body is None
    def test_override_invalid(self, request_validator):
        request = MockRequest(self.host_url, 'post', '/resource/one')

        result = request_validator.validate(request)

        assert type(result.errors[0]) == InvalidSecurity
        assert result.security is None
Ejemplo n.º 3
0
    def test_default_invalid(self, request_validator):
        request = MockRequest(self.host_url, "get", "/resource/one")

        result = request_validator.validate(request)

        assert type(result.errors[0]) == InvalidSecurity
        assert result.security is None
Ejemplo n.º 4
0
    def test_get_pets_response_no_schema(self, spec, response_validator):
        host_url = 'http://petstore.swagger.io/v1'
        path_pattern = '/v1/pets'
        query_params = {
            'limit': '20',
        }

        request = MockRequest(
            host_url,
            'GET',
            '/pets',
            path_pattern=path_pattern,
            args=query_params,
        )

        parameters = validate_parameters(spec, request)
        body = validate_body(spec, request)

        assert parameters == RequestParameters(query={
            'limit': 20,
            'page': 1,
            'search': '',
        })
        assert body is None

        data = '<html></html>'
        response = MockResponse(data, status_code=404, mimetype='text/html')

        response_result = response_validator.validate(request, response)

        assert response_result.errors == []
        assert response_result.data == data
Ejemplo n.º 5
0
    def test_missing_body(self, validator):
        headers = {
            'api_key': self.api_key_encoded,
        }
        cookies = {
            'user': '******',
        }
        request = MockRequest(
            'https://development.gigantic-server.com',
            'post',
            '/v1/pets',
            path_pattern='/v1/pets',
            headers=headers,
            cookies=cookies,
        )

        result = validator.validate(request)

        assert len(result.errors) == 1
        assert type(result.errors[0]) == MissingRequiredRequestBody
        assert result.body is None
        assert result.parameters == RequestParameters(
            header={
                'api_key': self.api_key,
            },
            cookie={
                'user': 123,
            },
        )
Ejemplo n.º 6
0
    def test_post_pets_plain_no_schema(self, validator, spec_dict):
        data = 'plain text'
        headers = {
            'api_key': self.api_key_encoded,
        }
        cookies = {
            'user': '******',
        }
        request = MockRequest(
            'https://development.gigantic-server.com',
            'post',
            '/v1/pets',
            path_pattern='/v1/pets',
            data=data,
            headers=headers,
            cookies=cookies,
            mimetype='text/plain',
        )

        result = validator.validate(request)

        assert result.errors == []
        assert result.parameters == RequestParameters(
            header={
                'api_key': self.api_key,
            },
            cookie={
                'user': 123,
            },
        )
        assert result.security == {}
        assert result.body == data
Ejemplo n.º 7
0
    def test_get_pets_param_order(self, spec):
        host_url = "http://petstore.swagger.io/v1"
        path_pattern = "/v1/pets"
        query_params = {
            "limit": None,
            "order": "desc",
        }

        request = MockRequest(
            host_url,
            "GET",
            "/pets",
            path_pattern=path_pattern,
            args=query_params,
        )

        with pytest.warns(DeprecationWarning):
            parameters = spec_validate_parameters(spec, request)

        assert parameters == Parameters(
            query={
                "limit": None,
                "order": "desc",
                "page": 1,
                "search": "",
            }
        )

        body = spec_validate_body(spec, request)

        assert body is None
Ejemplo n.º 8
0
    def test_get_pets_param_coordinates(self, spec):
        host_url = "http://petstore.swagger.io/v1"
        path_pattern = "/v1/pets"
        coordinates = {
            "lat": 1.12,
            "lon": 32.12,
        }
        query_params = {
            "limit": None,
            "coordinates": json.dumps(coordinates),
        }

        request = MockRequest(
            host_url,
            "GET",
            "/pets",
            path_pattern=path_pattern,
            args=query_params,
        )

        with pytest.warns(DeprecationWarning):
            parameters = spec_validate_parameters(spec, request)

        assert parameters == Parameters(
            query={
                "limit": None,
                "page": 1,
                "search": "",
                "coordinates": coordinates,
            }
        )

        body = spec_validate_body(spec, request)

        assert body is None
Ejemplo n.º 9
0
    def test_post_tags_extra_body_properties(self, spec, spec_dict):
        host_url = "http://petstore.swagger.io/v1"
        path_pattern = "/v1/tags"
        pet_name = "Dog"
        alias = "kitty"
        data_json = {
            "name": pet_name,
            "alias": alias,
        }
        data = json.dumps(data_json)

        request = MockRequest(
            host_url,
            "POST",
            "/tags",
            path_pattern=path_pattern,
            data=data,
        )

        parameters = spec_validate_parameters(spec, request)

        assert parameters == Parameters()

        with pytest.raises(InvalidSchemaValue):
            spec_validate_body(spec, request)
Ejemplo n.º 10
0
    def test_delete_tags_raises_missing_required_response_header(
        self, spec, response_validator
    ):
        host_url = "http://petstore.swagger.io/v1"
        path_pattern = "/v1/tags"
        request = MockRequest(
            host_url,
            "DELETE",
            "/tags",
            path_pattern=path_pattern,
        )

        parameters = spec_validate_parameters(spec, request)
        body = spec_validate_body(spec, request)

        assert parameters == Parameters()
        assert body is None

        data = None
        response = MockResponse(data, status_code=200)

        with pytest.warns(DeprecationWarning):
            response_result = response_validator.validate(request, response)

        assert response_result.errors == [
            MissingRequiredHeader(name="x-delete-confirm"),
        ]
        assert response_result.data is None
Ejemplo n.º 11
0
    def test_get_tags(self, spec, response_validator):
        host_url = "http://petstore.swagger.io/v1"
        path_pattern = "/v1/tags"

        request = MockRequest(
            host_url,
            "GET",
            "/tags",
            path_pattern=path_pattern,
        )

        parameters = spec_validate_parameters(spec, request)
        body = spec_validate_body(spec, request)

        assert parameters == Parameters()
        assert body is None

        data_json = ["cats", "birds"]
        data = json.dumps(data_json)
        response = MockResponse(data)

        response_result = response_validator.validate(request, response)

        assert response_result.errors == []
        assert response_result.data == data_json
Ejemplo n.º 12
0
    def test_get_pet_wildcard(self, spec, response_validator):
        host_url = "http://petstore.swagger.io/v1"
        path_pattern = "/v1/pets/{petId}"
        view_args = {
            "petId": "1",
        }
        request = MockRequest(
            host_url,
            "GET",
            "/pets/1",
            path_pattern=path_pattern,
            view_args=view_args,
        )

        parameters = spec_validate_parameters(spec, request)

        assert parameters == Parameters(
            path={
                "petId": 1,
            }
        )

        body = spec_validate_body(spec, request)

        assert body is None

        data = b"imagedata"
        response = MockResponse(data, mimetype="image/png")

        with pytest.warns(UserWarning):
            response_result = response_validator.validate(request, response)

        assert response_result.errors == []
        assert response_result.data == data
Ejemplo n.º 13
0
    def test_post_pets_raises_invalid_server_error(self, spec):
        host_url = 'http://flowerstore.swagger.io/v1'
        path_pattern = '/v1/pets'
        data_json = {
            'name': 'Cat',
            'tag': 'cats',
        }
        data = json.dumps(data_json)
        headers = {
            'api_key': '12345',
        }
        cookies = {
            'user': '******',
        }

        request = MockRequest(
            host_url,
            'POST',
            '/pets',
            path_pattern=path_pattern,
            data=data,
            mimetype='text/html',
            headers=headers,
            cookies=cookies,
        )

        with pytest.raises(InvalidServer):
            validate_parameters(spec, request)

        with pytest.raises(InvalidServer):
            validate_body(spec, request)
Ejemplo n.º 14
0
    def test_get_pets_allow_empty_value(self, spec):
        host_url = 'http://petstore.swagger.io/v1'
        path_pattern = '/v1/pets'
        query_params = {
            'limit': 20,
            'search': '',
        }

        request = MockRequest(
            host_url,
            'GET',
            '/pets',
            path_pattern=path_pattern,
            args=query_params,
        )

        with pytest.warns(DeprecationWarning):
            parameters = spec_validate_parameters(spec, request)

        assert parameters == RequestParameters(query={
            'page': 1,
            'limit': 20,
            'search': '',
        })

        body = spec_validate_body(spec, request)

        assert body is None
    def test_remove(self, request_validator):
        request = MockRequest(self.host_url, 'put', '/resource/one')

        result = request_validator.validate(request)

        assert not result.errors
        assert result.security == {}
Ejemplo n.º 16
0
    def test_get_pet_wildcard(self, spec, response_validator):
        host_url = 'http://petstore.swagger.io/v1'
        path_pattern = '/v1/pets/{petId}'
        view_args = {
            'petId': '1',
        }
        request = MockRequest(
            host_url, 'GET', '/pets/1',
            path_pattern=path_pattern, view_args=view_args,
        )

        parameters = validate_parameters(spec, request)

        assert parameters == RequestParameters(
            path={
                'petId': 1,
            }
        )

        body = validate_body(spec, request)

        assert body is None

        data = b'imagedata'
        response = MockResponse(data, mimetype='image/png')

        response_result = response_validator.validate(request, response)

        assert response_result.errors == []
        assert response_result.data == data
Ejemplo n.º 17
0
    def test_delete_tags_raises_missing_required_response_header(
            self, spec, response_validator):
        host_url = 'http://petstore.swagger.io/v1'
        path_pattern = '/v1/tags'
        request = MockRequest(
            host_url,
            'DELETE',
            '/tags',
            path_pattern=path_pattern,
        )

        parameters = spec_validate_parameters(spec, request)
        body = spec_validate_body(spec, request)

        assert parameters == RequestParameters()
        assert body is None

        data = None
        response = MockResponse(data, status_code=200)

        response_result = response_validator.validate(request, response)
        assert response_result.errors == [
            MissingRequiredHeader(name='x-delete-confirm'),
        ]
        assert response_result.data is None
Ejemplo n.º 18
0
    def test_post_pets_raises_invalid_mimetype(self, spec):
        host_url = 'https://staging.gigantic-server.com/v1'
        path_pattern = '/v1/pets'
        data_json = {
            'name': 'Cat',
            'tag': 'cats',
        }
        data = json.dumps(data_json)
        headers = {
            'api_key': self.api_key_encoded,
        }
        cookies = {
            'user': '******',
        }

        request = MockRequest(
            host_url, 'POST', '/pets',
            path_pattern=path_pattern, data=data, mimetype='text/html',
            headers=headers, cookies=cookies,
        )

        parameters = validate_parameters(spec, request)

        assert parameters == RequestParameters(
            header={
                'api_key': self.api_key,
            },
            cookie={
                'user': 123,
            },
        )

        with pytest.raises(MediaTypeNotFound):
            validate_body(spec, request)
Ejemplo n.º 19
0
    def test_post_pets_missing_header(self, spec, spec_dict):
        host_url = 'https://staging.gigantic-server.com/v1'
        path_pattern = '/v1/pets'
        pet_name = 'Cat'
        pet_healthy = True
        data_json = {
            'name': pet_name,
            'ears': {
                'healthy': pet_healthy,
            }
        }
        data = json.dumps(data_json)
        cookies = {
            'user': '******',
        }

        request = MockRequest(
            host_url, 'POST', '/pets',
            path_pattern=path_pattern, data=data,
            cookies=cookies,
        )

        with pytest.raises(MissingRequiredParameter):
            validate_parameters(spec, request)

        body = validate_body(spec, request)

        schemas = spec_dict['components']['schemas']
        pet_model = schemas['PetCreate']['x-model']
        assert body.__class__.__name__ == pet_model
        assert body.name == pet_name
        assert not hasattr(body, 'tag')
        assert not hasattr(body, 'address')
Ejemplo n.º 20
0
    def test_post_tags_extra_body_properties(self, spec, spec_dict):
        host_url = 'http://petstore.swagger.io/v1'
        path_pattern = '/v1/tags'
        pet_name = 'Dog'
        alias = 'kitty'
        data_json = {
            'name': pet_name,
            'alias': alias,
        }
        data = json.dumps(data_json)

        request = MockRequest(
            host_url,
            'POST',
            '/tags',
            path_pattern=path_pattern,
            data=data,
        )

        parameters = validate_parameters(spec, request)

        assert parameters == RequestParameters()

        with pytest.raises(InvalidSchemaValue):
            validate_body(spec, request)
Ejemplo n.º 21
0
    def test_get_pets(self, spec, response_validator):
        host_url = 'http://petstore.swagger.io/v1'
        path_pattern = '/v1/pets'
        query_params = {
            'limit': '20',
        }

        request = MockRequest(
            host_url, 'GET', '/pets',
            path_pattern=path_pattern, args=query_params,
        )

        parameters = validate_parameters(spec, request)
        body = validate_body(spec, request)

        assert parameters == RequestParameters(
            query={
                'limit': 20,
                'page': 1,
                'search': '',
            }
        )
        assert body is None

        data_json = {
            'data': [],
        }
        data = json.dumps(data_json)
        response = MockResponse(data)

        response_result = response_validator.validate(request, response)

        assert response_result.errors == []
        assert isinstance(response_result.data, BaseModel)
        assert response_result.data.data == []
Ejemplo n.º 22
0
    def test_get_pets_none_value(self, spec):
        host_url = 'http://petstore.swagger.io/v1'
        path_pattern = '/v1/pets'
        query_params = {
            'limit': None,
        }

        request = MockRequest(
            host_url, 'GET', '/pets',
            path_pattern=path_pattern, args=query_params,
        )

        parameters = validate_parameters(spec, request)

        assert parameters == RequestParameters(
            query={
                'limit': None,
                'page': 1,
                'search': '',
            }
        )

        body = validate_body(spec, request)

        assert body is None
Ejemplo n.º 23
0
    def test_invalid_content_type(self, validator):
        headers = {
            'api_key': self.api_key_encoded,
        }
        cookies = {
            'user': '******',
        }
        request = MockRequest(
            'https://development.gigantic-server.com', 'post', '/v1/pets',
            path_pattern='/v1/pets', mimetype='text/csv',
            headers=headers, cookies=cookies,
        )

        result = validator.validate(request)

        assert len(result.errors) == 1
        assert type(result.errors[0]) == InvalidContentType
        assert result.body is None
        assert result.parameters == RequestParameters(
            header={
                'api_key': self.api_key,
            },
            cookie={
                'user': 123,
            },
        )
Ejemplo n.º 24
0
    def test_get_tags(self, spec, response_validator):
        host_url = 'http://petstore.swagger.io/v1'
        path_pattern = '/v1/tags'

        request = MockRequest(
            host_url,
            'GET',
            '/tags',
            path_pattern=path_pattern,
        )

        parameters = validate_parameters(spec, request)
        body = validate_body(spec, request)

        assert parameters == RequestParameters()
        assert body is None

        data_json = ['cats', 'birds']
        data = json.dumps(data_json)
        response = MockResponse(data)

        response_result = response_validator.validate(request, response)

        assert response_result.errors == []
        assert response_result.data == data_json
Ejemplo n.º 25
0
    def test_post_pets_plain_no_schema(self, validator, spec_dict):
        data = "plain text"
        headers = {
            "api-key": self.api_key_encoded,
        }
        cookies = {
            "user": "******",
        }
        request = MockRequest(
            "https://development.gigantic-server.com",
            "post",
            "/v1/pets",
            path_pattern="/v1/pets",
            data=data,
            headers=headers,
            cookies=cookies,
            mimetype="text/plain",
        )

        with pytest.warns(UserWarning):
            result = validator.validate(request)

        assert result.errors == []
        assert result.parameters == Parameters(
            header={
                "api-key": self.api_key,
            },
            cookie={
                "user": 123,
            },
        )
        assert result.security == {}
        assert result.body == data
Ejemplo n.º 26
0
    def test_invalid_content_type(self, validator):
        data = "csv,data"
        headers = {
            "api-key": self.api_key_encoded,
        }
        cookies = {
            "user": "******",
        }
        request = MockRequest(
            "https://development.gigantic-server.com",
            "post",
            "/v1/pets",
            path_pattern="/v1/pets",
            mimetype="text/csv",
            data=data,
            headers=headers,
            cookies=cookies,
        )

        result = validator.validate(request)

        assert len(result.errors) == 1
        assert type(result.errors[0]) == MediaTypeNotFound
        assert result.body is None
        assert result.parameters == Parameters(
            header={
                "api-key": self.api_key,
            },
            cookie={
                "user": 123,
            },
        )
Ejemplo n.º 27
0
    def test_missing_body(self, validator):
        headers = {
            "api-key": self.api_key_encoded,
        }
        cookies = {
            "user": "******",
        }
        request = MockRequest(
            "https://development.gigantic-server.com",
            "post",
            "/v1/pets",
            path_pattern="/v1/pets",
            headers=headers,
            cookies=cookies,
        )

        result = validator.validate(request)

        assert len(result.errors) == 1
        assert type(result.errors[0]) == MissingRequiredRequestBody
        assert result.body is None
        assert result.parameters == Parameters(
            header={
                "api-key": self.api_key,
            },
            cookie={
                "user": 123,
            },
        )
Ejemplo n.º 28
0
    def test_post_cats_boolean_string(self, spec, spec_dict):
        host_url = 'https://staging.gigantic-server.com/v1'
        path_pattern = '/v1/pets'
        pet_name = 'Cat'
        pet_tag = 'cats'
        pet_street = 'Piekna'
        pet_city = 'Warsaw'
        pet_healthy = False
        data_json = {
            'name': pet_name,
            'tag': pet_tag,
            'position': 2,
            'address': {
                'street': pet_street,
                'city': pet_city,
            },
            'healthy': pet_healthy,
            'ears': {
                'healthy': pet_healthy,
            }
        }
        data = json.dumps(data_json)
        headers = {
            'api_key': self.api_key_encoded,
        }
        cookies = {
            'user': '******',
        }

        request = MockRequest(
            host_url, 'POST', '/pets',
            path_pattern=path_pattern, data=data,
            headers=headers, cookies=cookies,
        )

        parameters = validate_parameters(spec, request)

        assert parameters == RequestParameters(
            header={
                'api_key': self.api_key,
            },
            cookie={
                'user': 123,
            },
        )

        body = validate_body(spec, request)

        schemas = spec_dict['components']['schemas']
        pet_model = schemas['PetCreate']['x-model']
        address_model = schemas['Address']['x-model']
        assert body.__class__.__name__ == pet_model
        assert body.name == pet_name
        assert body.tag == pet_tag
        assert body.position == 2
        assert body.address.__class__.__name__ == address_model
        assert body.address.street == pet_street
        assert body.address.city == pet_city
        assert body.healthy is False
Ejemplo n.º 29
0
def validate_request(
    url: str,
    method: str,
    data: Union[str, bytes, Dict[str, Any]],
    http_headers: Dict[str, Any],
    json_url: bool,
    status_code: str,
    intentionally_undocumented: bool = False,
) -> None:
    # Some JSON endpoints have different parameters compared to
    # their `/api/v1` counterparts.
    if json_url and (url, method) in SKIP_JSON:
        return

    # TODO: Add support for file upload endpoints that lack the /json/
    # or /api/v1/ prefix.
    if url == "/user_uploads" or url.startswith("/realm/emoji/"):
        return

    # Now using the openapi_core APIs, validate the request schema
    # against the OpenAPI documentation.
    mock_request = MockRequest("http://localhost:9991/",
                               method,
                               "/api/v1" + url,
                               headers=http_headers,
                               args=data)
    result = openapi_spec.request_validator().validate(mock_request)
    if len(result.errors) != 0:
        # Requests that do not validate against the OpenAPI spec must either:
        # * Have returned a 400 (bad request) error
        # * Have returned a 200 (success) with this request marked as intentionally
        # undocumented behavior.
        if status_code.startswith("4"):
            return
        if status_code.startswith("2") and intentionally_undocumented:
            return

    # If no errors are raised, then validation is successful
    if len(result.errors) == 0:
        return

    # Show a block error message explaining the options for fixing it.
    msg = f"""

Error!  The OpenAPI schema for {method} {url} is not consistent
with the parameters passed in this HTTP request.  Consider:

* Updating the OpenAPI schema defined in zerver/openapi/zulip.yaml
* Adjusting the test to pass valid parameters.  If the test
  fails due to intentionally_undocumented features, you need to pass
  `intentionally_undocumented=True` to self.client_{method.lower()} or
  self.api_{method.lower()} to document your intent.

See https://zulip.readthedocs.io/en/latest/documentation/api.html for help.

The errors logged by the OpenAPI validator are below:\n"""
    for error in result.errors:
        msg += f"* {str(error)}\n"
    raise SchemaError(msg)
Ejemplo n.º 30
0
    def test_request_missing_param(self, validator):
        request = MockRequest('http://example.com', 'get', '/resource')
        result = validator.validate(request)

        assert len(result.errors) == 1
        assert type(result.errors[0]) == MissingRequiredParameter
        assert result.body is None
        assert result.parameters == RequestParameters()