Esempio n. 1
0
class TestHandshake(testcases.ASGIWebSocketTestCase):
    """
    Tests for the WebSocket handshake
    """
    def test_minimal(self):
        message = WebSocketConnection().connect()
        self.assert_valid_websocket_connect_message(message)

    @given(
        path=http_strategies.http_path(),
        params=http_strategies.query_params(),
        headers=http_strategies.headers(),
    )
    def test_connection(self, path, params, headers):
        message = WebSocketConnection().connect(path, params, headers)
        self.assert_valid_websocket_connect_message(message, path, params,
                                                    headers)
Esempio n. 2
0
class TestHTTPRequestSpec(testcases.ASGIHTTPTestCase):
    """
    Tests which try to pour the HTTP request section of the ASGI spec into code.
    The heavy lifting is done by the assert_valid_http_request_message function,
    the tests mostly serve to wire up hypothesis so that it exercise it's power to find
    edge cases.
    """
    def test_minimal_request(self):
        """
        Smallest viable example. Mostly verifies that our request building works.
        """
        request_method, request_path = 'GET', '/'
        message = message_for_request(request_method, request_path)

        self.assert_valid_http_request_message(message, request_method,
                                               request_path)

    @given(request_path=http_strategies.http_path(),
           request_params=http_strategies.query_params())
    def test_get_request(self, request_path, request_params):
        """
        Tests a typical HTTP GET request, with a path and query parameters
        """
        request_method = 'GET'
        message = message_for_request(request_method, request_path,
                                      request_params)

        self.assert_valid_http_request_message(message,
                                               request_method,
                                               request_path,
                                               request_params=request_params)

    @given(request_path=http_strategies.http_path(),
           request_body=http_strategies.http_body())
    def test_post_request(self, request_path, request_body):
        """
        Tests a typical POST request, submitting some data in a body.
        """
        request_method = 'POST'
        headers = [content_length_header(request_body)]
        message = message_for_request(request_method,
                                      request_path,
                                      headers=headers,
                                      body=request_body)

        self.assert_valid_http_request_message(message,
                                               request_method,
                                               request_path,
                                               request_headers=headers,
                                               request_body=request_body)

    @given(request_headers=http_strategies.headers())
    def test_headers(self, request_headers):
        """
        Tests that HTTP header fields are handled as specified
        """
        request_method, request_path = 'OPTIONS', '/te st-à/'
        message = message_for_request(request_method,
                                      request_path,
                                      headers=request_headers)

        self.assert_valid_http_request_message(message,
                                               request_method,
                                               request_path,
                                               request_headers=request_headers)

    @given(request_headers=http_strategies.headers())
    def test_duplicate_headers(self, request_headers):
        """
        Tests that duplicate header values are preserved
        """
        assume(len(request_headers) >= 2)
        # Set all header field names to the same value
        header_name = request_headers[0][0]
        duplicated_headers = [(header_name, header[1])
                              for header in request_headers]

        request_method, request_path = 'OPTIONS', '/te st-à/'
        message = message_for_request(request_method,
                                      request_path,
                                      headers=duplicated_headers)

        self.assert_valid_http_request_message(
            message,
            request_method,
            request_path,
            request_headers=duplicated_headers)

    @given(
        request_method=http_strategies.http_method(),
        request_path=http_strategies.http_path(),
        request_params=http_strategies.query_params(),
        request_headers=http_strategies.headers(),
        request_body=http_strategies.http_body(),
    )
    # This test is slow enough that on Travis, hypothesis sometimes complains.
    def test_kitchen_sink(self, request_method, request_path, request_params,
                          request_headers, request_body):
        """
        Throw everything at channels that we dare. The idea is that if a combination
        of method/path/headers/body would break the spec, hypothesis will eventually find it.
        """
        request_headers.append(content_length_header(request_body))
        message = message_for_request(request_method, request_path,
                                      request_params, request_headers,
                                      request_body)

        self.assert_valid_http_request_message(message, request_method,
                                               request_path, request_params,
                                               request_headers, request_body)

    def test_headers_are_lowercased_and_stripped(self):
        request_method, request_path = 'GET', '/'
        headers = [('MYCUSTOMHEADER', '   foobar    ')]
        message = message_for_request(request_method,
                                      request_path,
                                      headers=headers)

        self.assert_valid_http_request_message(message,
                                               request_method,
                                               request_path,
                                               request_headers=headers)
        # Note that Daphne returns a list of tuples here, which is fine, because the spec
        # asks to treat them interchangeably.
        assert message['headers'] == [(b'mycustomheader', b'foobar')]

    @given(daphne_path=http_strategies.http_path())
    def test_root_path_header(self, daphne_path):
        """
        Tests root_path handling.
        """
        request_method, request_path = 'GET', '/'
        # Daphne-Root-Path must be URL encoded when submitting as HTTP header field
        headers = [('Daphne-Root-Path',
                    parse.quote(daphne_path.encode('utf8')))]
        message = message_for_request(request_method,
                                      request_path,
                                      headers=headers)

        # Daphne-Root-Path is not included in the returned 'headers' section. So we expect
        # empty headers.
        expected_headers = []
        self.assert_valid_http_request_message(
            message,
            request_method,
            request_path,
            request_headers=expected_headers)
        # And what we're looking for, root_path being set.
        assert message['root_path'] == daphne_path