示例#1
0
async def test_remuneration_endpoint(client):
    resp = await client.get("/schema")
    spec = create_spec(json.loads(resp.body))

    resp = await client.post(
        "/remuneration",
        body={
            "beneficiaire.age": 20,
            "formation.region": 27,
            "formation.codes_financeur": [2],
        },
    )
    assert resp.status == HTTPStatus.OK
    assert "remunerations" in json.loads(resp.body)
    remunerations = json.loads(resp.body)["remunerations"]
    assert remunerations
    print(remunerations[0])
    assert "remuneration" in remunerations[0]
    assert "Version" in resp.headers

    validator = ResponseValidator(spec)
    request = MockRequest("http://trefle.pole-emploi.fr", "post",
                          "/remuneration")
    response = MockResponse(resp.body, resp.status.value)
    result = validator.validate(request, response)
    result.raise_for_errors()
示例#2
0
async def test_simulate_endpoint(client):
    resp = await client.get("/schema")
    spec = create_spec(json.loads(resp.body))

    resp = await client.post(
        "/financement",
        body={
            "beneficiaire.solde_cpf": 10,
            "beneficiaire.remuneration": 1400,
            "beneficiaire.droit_prive": True,
            "beneficiaire.contrat": "cdi",
            "formation.eligible_cpf": True,
            "formation.heures": 100,
            "beneficiaire.entreprise.commune": "2A004",
            "beneficiaire.entreprise.idcc": 2706,
        },
    )
    assert resp.status == HTTPStatus.OK
    assert "financements" in json.loads(resp.body)
    financements = json.loads(resp.body)["financements"]
    print(financements[0])
    assert financements
    assert financements[0].get("eligible")
    assert "Version" in resp.headers

    validator = ResponseValidator(spec)
    request = MockRequest("http://trefle.pole-emploi.fr", "post",
                          "/financement")
    response = MockResponse(resp.body, resp.status.value)
    result = validator.validate(request, response)
    result.raise_for_errors()
示例#3
0
class OpenApiSpecManager(SharedExtension):

    _loaded = Event()

    def setup(self):
        log.info('   ###   OpenApiSpecManager.setup')
        super().setup()

    def load_spec(self, spec_file):
        log.debug('%s.load_spec: %s' % (self.__class__.__name__, spec_file))
        # TODO: supporting loading from url instead of just file
        # TODO: How to handle/interpret/respect spec.servers[].url's?
        # TODO: Or should this be generated/injected into the spec_dict on startup?
        #spec_file = '/home/sar/vcs/nameko-openapi/petstore.yaml'
        spec_dict = yaml.safe_load(open(spec_file))
        self.spec = openapi_core.create_spec(spec_dict)
        self.request_validator = RequestValidator(self.spec)
        self.response_validator = ResponseValidator(self.spec)
        self._loaded.send(self.spec)

    def wait_for_spec(self):
        """Allow other extensions to wait until the spec is loaded."""
        return self._loaded.wait()

    def get_operation_by_id(self, operation_id):
        self.wait_for_spec()
        for path_name, path in six.iteritems(self.spec.paths):
            for http_method, operation in six.iteritems(path.operations):
                if operation.operation_id == operation_id:
                    return operation

    def validate_request(self, request, raise_for_errors=True):
        result = self.request_validator.validate(request)
        if raise_for_errors:
            result.raise_for_errors()
        return result

    def validate_response(self,
                          response,
                          openapi_request,
                          raise_for_errors=True):
        result = self.response_validator.validate(openapi_request, response)
        if raise_for_errors:
            result.raise_for_errors()
        return result
示例#4
0
def test_healthz(client):
    """Test the /healthz endpoint."""

    path = '/v1/healthz'
    rv = client.get(path)

    # Validate request and response against OpenAPI spec
    with app.test_request_context(path):
        with open(app.config['OPENAPI_SPEC']) as stream:
            spec = create_spec(safe_load(stream))

        openapi_response = FlaskOpenAPIResponse(rv)
        openapi_request = FlaskOpenAPIRequest(request)
        validator = ResponseValidator(spec)
        result = validator.validate(openapi_request, openapi_response)
        result.raise_for_errors()

    assert rv.content_type == "text/plain"
    assert rv.status_code == 200
    assert b'OK' in rv.data
示例#5
0
async def test_simulate_endpoint_with_invalid_data(client):
    resp = await client.get("/schema")
    spec = create_spec(json.loads(resp.body))

    resp = await client.post(
        "/financement",
        body={
            "beneficiaire.remuneration": "1400",
            "beneficiaire.droit_prive": "invalide",
            "beneficiaire.entreprise.idcc": 2706,
        },
    )
    assert resp.status == HTTPStatus.UNPROCESSABLE_ENTITY
    assert "application/json" in resp.headers["Content-Type"]

    validator = ResponseValidator(spec)
    request = MockRequest("http://trefle.pole-emploi.fr", "post",
                          "/financement")
    response = MockResponse(resp.body, resp.status.value)
    result = validator.validate(request, response)
    result.raise_for_errors()
示例#6
0
class Client:
    def __init__(
        self,
        spec: Union[Spec, dict],
        *,
        server_url: Optional[str] = None,
        client: Union[ModuleType, Requestable] = httpx,
        request_class: Type[ClientOpenAPIRequest] = ClientOpenAPIRequest,
        response_factory: Callable[[Any],
                                   OpenAPIResponse] = ClientOpenAPIResponse,
        headers: Optional[dict] = None,
    ):
        if not isinstance(spec, Spec):
            spec = create_spec(spec)
        self.spec = spec
        self.client = client
        self.request_class = request_class
        self.response_factory = response_factory
        self.common_headers = headers or {}

        if server_url is None:
            server_url = self.spec.servers[0].url
        else:
            server_url = server_url.rstrip("/")
            for server in self.spec.servers:
                if server_url == server.url:
                    break
            else:
                self.spec.servers.append(Server(server_url))
        self.server_url = server_url
        self.validator = ResponseValidator(self.spec)

        for path_spec in spec.paths.values():
            for op_spec in path_spec.operations.values():
                setattr(
                    self,
                    snakecase(op_spec.operation_id),
                    self._get_operation(op_spec).__get__(self),
                )

    @staticmethod
    def _get_operation(op_spec):
        # TODO: extract args and kwargs from operation parameters
        def operation(
            self,
            *args,
            body_: Optional[Union[dict, list]] = None,
            headers_: Optional[dict] = None,
            **kwargs,
        ):
            request_headers = self.common_headers.copy()
            request_headers.update(headers_ or {})
            request = self.request_class(self.server_url, op_spec)
            request.prepare(*args,
                            body_=body_,
                            headers_=request_headers,
                            **kwargs)
            request_params = {
                "method": request.method,
                "url": request.url,
                "headers": request.headers,
            }
            if request.body:
                request_params["json" if "json" in
                               request.mimetype else "data"] = request.body
            api_response = self.client.request(**request_params)
            api_response.raise_for_status()
            response = self.response_factory(api_response)
            self.validator.validate(request, response).raise_for_errors()
            return response

        operation.__doc__ = op_spec.summary or op_spec.operation_id
        if op_spec.description:
            operation.__doc__ += f"\n\n{op_spec.description}"
        return operation

    @classmethod
    def from_file(cls, path: Union[Path, str], **kwargs):
        """Creates an instance of the class by loading the spec from a local file."""
        spec = get_spec_from_file(path)
        return cls(spec, **kwargs)