Beispiel #1
0
    def test_results_can_be_retrieved(self):

        payload = {
            "name": "test has results",
            "setup": "pass",
            "snippets": ("pass", "pass")
        }

        start_response = StartResponseMock()
        result = self.app(
            create_environ(
                path='/entries',
                method='POST',
                body=json.dumps(payload),
            ),
            start_response,
        )[0].decode()
        result = json.loads(result)

        start_response2 = StartResponseMock()
        result2 = self.app(
            create_environ(path='/entries/{0}/results'.format(result['id']), ),
            start_response2,
        )[0].decode()
        result2 = json.loads(result2)

        self.assertTrue(start_response2.status != '404 Not Found')
        self.assertTrue(start_response2.status != '500 Internal Server Error')

        for snippet in result2['snippets']:

            self.assertTrue(snippet['runtime'] is None)
            self.assertTrue(snippet['memory']['max'] is None)
            self.assertTrue(snippet['memory']['avg'] is None)
            self.assertTrue(snippet['memory']['min'] is None)
Beispiel #2
0
    def test_create_can_be_retrieved_later(self):

        payload = {
            "name": "test can be retrieved",
            "setup": "pass",
            "snippets": ("pass", "pass")
        }

        start_response = StartResponseMock()
        result = self.app(
            create_environ(
                path='/entries',
                method='POST',
                body=json.dumps(payload),
            ),
            start_response,
        )[0].decode()
        result = json.loads(result)

        start_response2 = StartResponseMock()
        result2 = self.app(
            create_environ(path='/entries/{0}'.format(result['id']), ),
            start_response2,
        )[0].decode()
        result2 = json.loads(result2)

        self.assertTrue(start_response2.status != '404 Not Found')
        self.assertTrue(result2['id'] == result['id'])
        self.assertTrue(result2['name'] == payload['name'])
        self.assertTrue(result2['setup'] == payload['setup'])

        for snip1, snip2 in zip(payload['snippets'], result2['snippets']):
            self.assertTrue(snip1 == snip2)
Beispiel #3
0
    def simulate_request(self, method='GET', path='/', query_string=None,
                         headers=None, body=None, file_wrapper=None):
        """Simulates a request to a WSGI application.

        Performs a WSGI request directly against ``self.api``.

        Keyword Args:
            method (str): The HTTP method to use in the request
                (default: 'GET')
            path (str): The URL path to request (default: '/')
            query_string (str): A raw query string to include in the
                request (default: ``None``)
            headers (dict): Additional headers to include in the request
                (default: ``None``)
            body (str): A string to send as the body of the request.
                Accepts both byte strings and Unicode strings
                (default: ``None``). If a Unicode string is provided,
                it will be encoded as UTF-8 in the request.
            file_wrapper (callable): Callable that returns an iterable,
                to be used as the value for *wsgi.file_wrapper* in the
                environ (default: ``None``).

        Returns:
            :py:class:`~.Result`: The result of the request
        """

        if not path.startswith('/'):
            raise ValueError("path must start with '/'")

        if query_string and query_string.startswith('?'):
            raise ValueError("query_string should not start with '?'")

        if '?' in path:
            # NOTE(kgriffs): We could allow this, but then we'd need
            #   to define semantics regarding whether the path takes
            #   precedence over the query_string. Also, it would make
            #   tests less consistent, since there would be "more than
            #   one...way to do it."
            raise ValueError(
                'path may not contain a query string. Please use the '
                'query_string parameter instead.'
            )

        env = create_environ(
            method=method,
            path=path,
            query_string=(query_string or ''),
            headers=headers,
            body=body,
            file_wrapper=file_wrapper,
        )

        srmock = StartResponseMock()
        validator = wsgiref.validate.validator(self.api)
        iterable = validator(env, srmock)

        result = Result(iterable, srmock.status, srmock.headers)

        return result
Beispiel #4
0
 def fake_request(self, path, **kwargs):
     kwargs.setdefault("headers", {})
     content_type = kwargs.pop("content_type", None)
     if content_type:
         kwargs["headers"]["Content-Type"] = content_type
     if self._before:
         self._before(kwargs)
     parsed = urlparse(path)
     path = parsed.path
     if parsed.query:
         kwargs["query_string"] = parsed.query
     if isinstance(kwargs.get("query_string", None), dict):
         kwargs["query_string"] = urlencode(kwargs["query_string"])
     self.encode_body(kwargs)
     resp = StartResponseMock()
     environ = create_environ(path, **kwargs)
     resp.environ = environ
     body = self.app(environ, resp)
     resp.headers = resp.headers_dict
     resp.status_code = int(resp.status.split(" ")[0])
     resp.body = b"".join(list(body)) if body else b""
     try:
         # …to be smart and provide the response as str if it let iself
         # decode.
         resp.body = resp.body.decode()
     except UnicodeDecodeError:
         # But do not insist.
         pass
     if "application/json" in resp.headers.get("Content-Type", ""):
         resp.json = json.loads(resp.body) if resp.body else {}
     if self._after:
         self._after(resp)
     return resp
Beispiel #5
0
 def fake_request(self, path, **kwargs):
     kwargs.setdefault('headers', {})
     content_type = kwargs.pop('content_type', None)
     if content_type:
         kwargs['headers']['Content-Type'] = content_type
     if self._before:
         self._before(kwargs)
     parsed = urlparse(path)
     path = parsed.path
     if parsed.query:
         kwargs['query_string'] = parsed.query
     if isinstance(kwargs.get('query_string', None), dict):
         kwargs['query_string'] = urlencode(kwargs['query_string'])
     self.encode_body(kwargs)
     resp = StartResponseMock()
     body = self.app(create_environ(path, **kwargs), resp)
     resp.headers = resp.headers_dict
     resp.status_code = int(resp.status.split(' ')[0])
     resp.body = b''.join(list(body)) if body else b''
     try:
         # …to be smart and provide the response as str if it let iself
         # decode.
         resp.body = resp.body.decode()
     except UnicodeDecodeError:
         # But do not insist.
         pass
     if 'application/json' in resp.headers.get('Content-Type', ''):
         resp.json = json.loads(resp.body) if resp.body else {}
     if self._after:
         self._after(resp)
     return resp
Beispiel #6
0
    def setUp(self):
        """Initializer, unittest-style"""

        super(TestBase, self).setUp()
        self.api = falcon.API()
        self.srmock = StartResponseMock()
        self.test_route = '/' + self.getUniqueString()

        before = getattr(self, 'before', None)
        if hasattr(before, '__call__'):
            before()
Beispiel #7
0
    def setUp(self):
        """Initializer, unittest-style"""

        super(TestBase, self).setUp()
        self._id = itertools.count(0)
        self.api = falcon.API()
        self.srmock = StartResponseMock()
        self.test_route = '/{0}'.format(next(self._id))

        before = getattr(self, 'before', None)
        if hasattr(before, '__call__'):
            before()
Beispiel #8
0
 def fake_request(self, path, **kwargs):
     kwargs.setdefault('headers', {})
     content_type = kwargs.pop('content_type', None)
     if content_type:
         kwargs['headers']['Content-Type'] = content_type
     if self._before:
         self._before(kwargs)
     parsed = urlparse(path)
     path = parsed.path
     if parsed.query:
         kwargs['query_string'] = parsed.query
     if isinstance(kwargs.get('query_string', None), dict):
         kwargs['query_string'] = urlencode(kwargs['query_string'])
     self.encode_body(kwargs)
     resp = StartResponseMock()
     body = self.app(create_environ(path, **kwargs), resp)
     resp.headers = resp.headers_dict
     resp.status_code = int(resp.status.split(' ')[0])
     resp.body = b''.join(list(body)) if body else b''
     try:
         # …to be smart and provide the response as str if it let iself
         # decode.
         resp.body = resp.body.decode()
     except UnicodeDecodeError:
         # But do not insist.
         pass
     if 'application/json' in resp.headers.get('Content-Type', ''):
         resp.json = json.loads(resp.body) if resp.body else {}
     if self._after:
         self._after(resp)
     return resp
Beispiel #9
0
    def test_create_errors_when_payload_invalid(self):

        start_response = StartResponseMock()

        self.app(
            create_environ(
                path='/entries',
                method='POST',
                body='{"name": "test"}',  # Missing values
            ),
            start_response,
        )[0].decode()

        self.assertTrue(start_response.status == '400 Bad Request')
Beispiel #10
0
    def test_create_errors_when_json_invalid(self):

        start_response = StartResponseMock()

        self.app(
            create_environ(
                path='/entries',
                method='POST',
                body='{{[[[}}]',
            ),
            start_response,
        )[0].decode()

        self.assertTrue(start_response.status == '400 Bad Request')
Beispiel #11
0
    def setUp(self):
        """Initializer, unittest-style"""

        super(TestBase, self).setUp()
        self._id = itertools.count(0)
        self.api = falcon.API()
        self.srmock = StartResponseMock()
        self.test_route = '/{0}'.format(next(self._id))

        # Reset to simulate "restarting" the WSGI container
        falcon.request._maybe_wrap_wsgi_stream = True

        before = getattr(self, 'before', None)
        if callable(before):
            before()
Beispiel #12
0
    def test_can_list_all_entries(self):

        results = self.app(
            create_environ(path='/entries', ),
            StartResponseMock(),
        )[0].decode()

        results = json.loads(results)

        try:

            for r in results:

                pass

        except TypeError:

            raise AssertionError('API results are not iterable.')
Beispiel #13
0
    def test_create_succeeds_when_payload_correct(self):

        start_response = StartResponseMock()

        result = self.app(
            create_environ(
                path='/entries',
                method='POST',
                body=json.dumps({
                    "name": "test correct payload",
                    "setup": "pass",
                    "snippets": ("pass", "pass")
                }),
            ),
            start_response,
        )[0].decode()
        result = json.loads(result)

        self.assertTrue(start_response.status == '201 Created')
        self.assertTrue(result['id'] == 'test_correct_payload')
Beispiel #14
0
def simulate_request(app, method='GET', path='/', query_string=None,
                     headers=None, body=None, file_wrapper=None, wsgierrors=None,
                     params=None, params_csv=True, protocol='http'):
        """Simulates a request to a WSGI application.

        Performs a request against a WSGI application. Uses
        :any:`wsgiref.validate` to ensure the response is valid
        WSGI.

        Keyword Args:
            app (callable): The WSGI application to call
            method (str): An HTTP method to use in the request
                (default: 'GET')
            path (str): The URL path to request (default: '/')
            protocol: The protocol to use for the URL scheme
                (default: 'http')
            params (dict): A dictionary of query string parameters,
                where each key is a parameter name, and each value is
                either a ``str`` or something that can be converted
                into a ``str``, or a list of such values. If a ``list``,
                the value will be converted to a comma-delimited string
                of values (e.g., 'thing=1,2,3').
            params_csv (bool): Set to ``False`` to encode list values
                in query string params by specifying multiple instances
                of the parameter (e.g., 'thing=1&thing=2&thing=3').
                Otherwise, parameters will be encoded as comma-separated
                values (e.g., 'thing=1,2,3'). Defaults to ``True``.
            query_string (str): A raw query string to include in the
                request (default: ``None``). If specified, overrides
                `params`.
            headers (dict): Additional headers to include in the request
                (default: ``None``)
            body (str): A string to send as the body of the request.
                Accepts both byte strings and Unicode strings
                (default: ``None``). If a Unicode string is provided,
                it will be encoded as UTF-8 in the request.
            file_wrapper (callable): Callable that returns an iterable,
                to be used as the value for *wsgi.file_wrapper* in the
                environ (default: ``None``). This can be used to test
                high-performance file transmission when `resp.stream` is
                set to a file-like object.
            wsgierrors (io): The stream to use as *wsgierrors*
                (default ``sys.stderr``)

        Returns:
            :py:class:`~.Result`: The result of the request
        """

        if not path.startswith('/'):
            raise ValueError("path must start with '/'")

        if query_string and query_string.startswith('?'):
            raise ValueError("query_string should not start with '?'")

        if '?' in path:
            # NOTE(kgriffs): We could allow this, but then we'd need
            #   to define semantics regarding whether the path takes
            #   precedence over the query_string. Also, it would make
            #   tests less consistent, since there would be "more than
            #   one...way to do it."
            raise ValueError(
                'path may not contain a query string. Please use the '
                'query_string parameter instead.'
            )

        if query_string is None:
            query_string = to_query_str(
                params,
                comma_delimited_lists=params_csv,
                prefix=False,
            )

        env = helpers.create_environ(
            method=method,
            scheme=protocol,
            path=path,
            query_string=(query_string or ''),
            headers=headers,
            body=body,
            file_wrapper=file_wrapper,
            wsgierrors=wsgierrors,
        )

        srmock = StartResponseMock()
        validator = wsgiref.validate.validator(app)
        iterable = validator(env, srmock)

        result = Result(iterable, srmock.status, srmock.headers)

        return result
Beispiel #15
0
def simulate_request(app,
                     method='GET',
                     path='/',
                     query_string=None,
                     headers=None,
                     body=None,
                     json=None,
                     file_wrapper=None,
                     wsgierrors=None,
                     params=None,
                     params_csv=True,
                     protocol='http',
                     host=helpers.DEFAULT_HOST,
                     remote_addr=None,
                     extras=None):
    """Simulates a request to a WSGI application.

    Performs a request against a WSGI application. Uses
    :any:`wsgiref.validate` to ensure the response is valid
    WSGI.

    Keyword Args:
        app (callable): The WSGI application to call
        method (str): An HTTP method to use in the request
            (default: 'GET')
        path (str): The URL path to request (default: '/').

            Note:
                The path may contain a query string. However, neither
                `query_string` nor `params` may be specified in this case.

        protocol: The protocol to use for the URL scheme
            (default: 'http')
        params (dict): A dictionary of query string parameters,
            where each key is a parameter name, and each value is
            either a ``str`` or something that can be converted
            into a ``str``, or a list of such values. If a ``list``,
            the value will be converted to a comma-delimited string
            of values (e.g., 'thing=1,2,3').
        params_csv (bool): Set to ``False`` to encode list values
            in query string params by specifying multiple instances
            of the parameter (e.g., 'thing=1&thing=2&thing=3').
            Otherwise, parameters will be encoded as comma-separated
            values (e.g., 'thing=1,2,3'). Defaults to ``True``.
        query_string (str): A raw query string to include in the
            request (default: ``None``). If specified, overrides
            `params`.
        headers (dict): Additional headers to include in the request
            (default: ``None``)
        body (str): A string to send as the body of the request.
            Accepts both byte strings and Unicode strings
            (default: ``None``). If a Unicode string is provided,
            it will be encoded as UTF-8 in the request.
        json(JSON serializable): A JSON document to serialize as the
            body of the request (default: ``None``). If specified,
            overrides `body` and the Content-Type header in
            `headers`.
        file_wrapper (callable): Callable that returns an iterable,
            to be used as the value for *wsgi.file_wrapper* in the
            environ (default: ``None``). This can be used to test
            high-performance file transmission when `resp.stream` is
            set to a file-like object.
        host(str): A string to use for the hostname part of the fully
            qualified request URL (default: 'falconframework.org')
        remote_addr (str): A string to use as the remote IP address for the
            request (default: '127.0.0.1')
        wsgierrors (io): The stream to use as *wsgierrors*
            (default ``sys.stderr``)
        extras (dict): Additional CGI variables to add to the WSGI
            ``environ`` dictionary for the request (default: ``None``)

    Returns:
        :py:class:`~.Result`: The result of the request
    """

    if not path.startswith('/'):
        raise ValueError("path must start with '/'")

    if '?' in path:
        if query_string or params:
            raise ValueError(
                'path may not contain a query string in combination with '
                'the query_string or params parameters. Please use only one '
                'way of specifying the query string.')
        path, query_string = path.split('?', 1)
    elif query_string and query_string.startswith('?'):
        raise ValueError("query_string should not start with '?'")

    extras = extras or {}
    if 'REQUEST_METHOD' in extras and extras['REQUEST_METHOD'] != method:
        # NOTE(vytas): Even given the duct tape nature of overriding
        # arbitrary environ variables, changing the method can potentially
        # be very confusing, particularly when using specialized
        # simulate_get/post/patch etc methods.
        raise ValueError(
            'environ extras may not override the request method. Please '
            'use the method parameter.')

    if query_string is None:
        query_string = to_query_str(
            params,
            comma_delimited_lists=params_csv,
            prefix=False,
        )

    if json is not None:
        body = util_json.dumps(json, ensure_ascii=False)
        headers = headers or {}
        headers['Content-Type'] = MEDIA_JSON

    env = helpers.create_environ(
        method=method,
        scheme=protocol,
        path=path,
        query_string=(query_string or ''),
        headers=headers,
        body=body,
        file_wrapper=file_wrapper,
        host=host,
        remote_addr=remote_addr,
        wsgierrors=wsgierrors,
    )
    if extras:
        env.update(extras)

    srmock = StartResponseMock()
    validator = wsgiref.validate.validator(app)

    iterable = validator(env, srmock)

    result = Result(helpers.closed_wsgi_iterable(iterable), srmock.status,
                    srmock.headers)

    return result