from unittest import mock from wptserve.request import Request, RequestHeaders, MultiDict class MockHTTPMessage(dict): """A minimum (and not completely correctly) mock of HTTPMessage for testing. Constructing HTTPMessage is annoying and different in Python 2 and 3. This only implements the parts used by RequestHeaders. Requirements for construction: * Keys are header names and MUST be lower-case. * Values are lists of header values (even if there's only one). * Keys and values should be native strings to match stdlib's behaviours. """ def __getitem__(self, key): assert isinstance(key, str) values = dict.__getitem__(self, key.lower()) assert isinstance(values, list) return values[0] def get(self, key, default=None): try: return self[key] except KeyError: return default def getallmatchingheaders(self, key): values = dict.__getitem__(self, key.lower()) return [f"{key}: {v}\n" for v in values] def test_request_headers_get(): raw_headers = MockHTTPMessage({ 'x-foo': ['foo'], 'x-bar': ['bar1', 'bar2'], }) headers = RequestHeaders(raw_headers) assert headers['x-foo'] == b'foo' assert headers['X-Bar'] == b'bar1, bar2' assert headers.get('x-bar') == b'bar1, bar2' def test_request_headers_encoding(): raw_headers = MockHTTPMessage({ 'x-foo': ['foo'], 'x-bar': ['bar1', 'bar2'], }) headers = RequestHeaders(raw_headers) assert isinstance(headers['x-foo'], bytes) assert isinstance(headers['x-bar'], bytes) assert isinstance(headers.get_list('x-bar')[0], bytes) def test_request_url_from_server_address(): request_handler = mock.Mock() request_handler.server.scheme = 'http' request_handler.server.server_address = ('localhost', '8000') request_handler.path = '/demo' request_handler.headers = MockHTTPMessage() request = Request(request_handler) assert request.url == 'http://localhost:8000/demo' assert isinstance(request.url, str) def test_request_url_from_host_header(): request_handler = mock.Mock() request_handler.server.scheme = 'http' request_handler.server.server_address = ('localhost', '8000') request_handler.path = '/demo' request_handler.headers = MockHTTPMessage({'host': ['web-platform.test:8001']}) request = Request(request_handler) assert request.url == 'http://web-platform.test:8001/demo' assert isinstance(request.url, str) def test_multidict(): m = MultiDict() m["foo"] = "bar" m["bar"] = "baz" m.add("foo", "baz") m.add("baz", "qux") assert m["foo"] == "bar" assert m.get("foo") == "bar" assert m["bar"] == "baz" assert m.get("bar") == "baz" assert m["baz"] == "qux" assert m.get("baz") == "qux" assert m.first("foo") == "bar" assert m.last("foo") == "baz" assert m.get_list("foo") == ["bar", "baz"] assert m.get_list("non_existent") == [] assert m.get("non_existent") is None try: m["non_existent"] assert False, "An exception should be raised" except KeyError: pass