aboutsummaryrefslogtreecommitdiffstats
path: root/test/netlib
diff options
context:
space:
mode:
Diffstat (limited to 'test/netlib')
-rw-r--r--test/netlib/http/http1/test_read.py26
-rw-r--r--test/netlib/http/test_cookies.py21
-rw-r--r--test/netlib/http/test_headers.py11
-rw-r--r--test/netlib/http/test_message.py220
-rw-r--r--test/netlib/test_encoding.py40
-rw-r--r--test/netlib/test_strutils.py5
6 files changed, 261 insertions, 62 deletions
diff --git a/test/netlib/http/http1/test_read.py b/test/netlib/http/http1/test_read.py
index 5285ac1d..c8a40ecb 100644
--- a/test/netlib/http/http1/test_read.py
+++ b/test/netlib/http/http1/test_read.py
@@ -1,6 +1,9 @@
from __future__ import absolute_import, print_function, division
+
from io import BytesIO
from mock import Mock
+import pytest
+
from netlib.exceptions import HttpException, HttpSyntaxException, HttpReadDisconnect, TcpDisconnect
from netlib.http import Headers
from netlib.http.http1.read import (
@@ -23,11 +26,18 @@ def test_get_header_tokens():
assert get_header_tokens(headers, "foo") == ["bar", "voing", "oink"]
-def test_read_request():
- rfile = BytesIO(b"GET / HTTP/1.1\r\n\r\nskip")
+@pytest.mark.parametrize("input", [
+ b"GET / HTTP/1.1\r\n\r\nskip",
+ b"GET / HTTP/1.1\r\n\r\nskip",
+ b"GET / HTTP/1.1\r\n\r\nskip",
+ b"GET / HTTP/1.1 \r\n\r\nskip",
+])
+def test_read_request(input):
+ rfile = BytesIO(input)
r = read_request(rfile)
assert r.method == "GET"
assert r.content == b""
+ assert r.http_version == "HTTP/1.1"
assert r.timestamp_end
assert rfile.read() == b"skip"
@@ -50,11 +60,19 @@ def test_read_request_head():
assert rfile.read() == b"skip"
-def test_read_response():
+@pytest.mark.parametrize("input", [
+ b"HTTP/1.1 418 I'm a teapot\r\n\r\nbody",
+ b"HTTP/1.1 418 I'm a teapot\r\n\r\nbody",
+ b"HTTP/1.1 418 I'm a teapot\r\n\r\nbody",
+ b"HTTP/1.1 418 I'm a teapot \r\n\r\nbody",
+])
+def test_read_response(input):
req = treq()
- rfile = BytesIO(b"HTTP/1.1 418 I'm a teapot\r\n\r\nbody")
+ rfile = BytesIO(input)
r = read_response(rfile, req)
+ assert r.http_version == "HTTP/1.1"
assert r.status_code == 418
+ assert r.reason == "I'm a teapot"
assert r.content == b"body"
assert r.timestamp_end
diff --git a/test/netlib/http/test_cookies.py b/test/netlib/http/test_cookies.py
index 83b85656..17e21b94 100644
--- a/test/netlib/http/test_cookies.py
+++ b/test/netlib/http/test_cookies.py
@@ -245,3 +245,24 @@ def test_refresh_cookie():
assert cookies.refresh_set_cookie_header(c, 0)
c = "foo/bar=bla"
assert cookies.refresh_set_cookie_header(c, 0)
+
+
+def test_is_expired():
+ CA = cookies.CookieAttrs
+
+ # A cookie can be expired
+ # by setting the expire time in the past
+ assert cookies.is_expired(CA([("Expires", "Thu, 01-Jan-1970 00:00:00 GMT")]))
+
+ # or by setting Max-Age to 0
+ assert cookies.is_expired(CA([("Max-Age", "0")]))
+
+ # or both
+ assert cookies.is_expired(CA([("Expires", "Thu, 01-Jan-1970 00:00:00 GMT"), ("Max-Age", "0")]))
+
+ assert not cookies.is_expired(CA([("Expires", "Thu, 24-Aug-2063 00:00:00 GMT")]))
+ assert not cookies.is_expired(CA([("Max-Age", "1")]))
+ assert not cookies.is_expired(CA([("Expires", "Thu, 15-Jul-2068 00:00:00 GMT"), ("Max-Age", "1")]))
+
+ assert not cookies.is_expired(CA([("Max-Age", "nan")]))
+ assert not cookies.is_expired(CA([("Expires", "false")]))
diff --git a/test/netlib/http/test_headers.py b/test/netlib/http/test_headers.py
index 51819b86..51537310 100644
--- a/test/netlib/http/test_headers.py
+++ b/test/netlib/http/test_headers.py
@@ -1,4 +1,6 @@
-from netlib.http import Headers, parse_content_type
+import collections
+
+from netlib.http.headers import Headers, parse_content_type, assemble_content_type
from netlib.tutils import raises
@@ -81,3 +83,10 @@ def test_parse_content_type():
v = p("text/html; charset=UTF-8")
assert v == ('text', 'html', {'charset': 'UTF-8'})
+
+
+def test_assemble_content_type():
+ p = assemble_content_type
+ assert p("text", "html", {}) == "text/html"
+ assert p("text", "html", {"charset": "utf8"}) == "text/html; charset=utf8"
+ assert p("text", "html", collections.OrderedDict([("charset", "utf8"), ("foo", "bar")])) == "text/html; charset=utf8; foo=bar"
diff --git a/test/netlib/http/test_message.py b/test/netlib/http/test_message.py
index ab2ac628..deebd6f2 100644
--- a/test/netlib/http/test_message.py
+++ b/test/netlib/http/test_message.py
@@ -1,8 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
-from netlib.http import decoded
+import mock
+import six
+
from netlib.tutils import tresp
+from netlib import http, tutils
def _test_passthrough_attr(message, attr):
@@ -68,6 +71,15 @@ class TestMessage(object):
assert resp != 0
+ def test_hash(self):
+ resp = tresp()
+ assert hash(resp)
+
+ def test_serializable(self):
+ resp = tresp()
+ resp2 = http.Response.from_state(resp.get_state())
+ assert resp == resp2
+
def test_content_length_update(self):
resp = tresp()
resp.content = b"foo"
@@ -76,9 +88,9 @@ class TestMessage(object):
resp.content = b""
assert resp.data.content == b""
assert resp.headers["content-length"] == "0"
-
- def test_content_basic(self):
- _test_passthrough_attr(tresp(), "content")
+ resp.raw_content = b"bar"
+ assert resp.data.content == b"bar"
+ assert resp.headers["content-length"] == "0"
def test_headers(self):
_test_passthrough_attr(tresp(), "headers")
@@ -89,65 +101,201 @@ class TestMessage(object):
def test_timestamp_end(self):
_test_passthrough_attr(tresp(), "timestamp_end")
- def teste_http_version(self):
+ def test_http_version(self):
_test_decoded_attr(tresp(), "http_version")
-class TestDecodedDecorator(object):
-
+class TestMessageContentEncoding(object):
def test_simple(self):
r = tresp()
- assert r.content == b"message"
+ assert r.raw_content == b"message"
assert "content-encoding" not in r.headers
- assert r.encode("gzip")
+ r.encode("gzip")
assert r.headers["content-encoding"]
- assert r.content != b"message"
- with decoded(r):
- assert "content-encoding" not in r.headers
- assert r.content == b"message"
- assert r.headers["content-encoding"]
- assert r.content != b"message"
+ assert r.raw_content != b"message"
+ assert r.content == b"message"
+ assert r.raw_content != b"message"
+
+ r.raw_content = b"foo"
+ with mock.patch("netlib.encoding.decode") as e:
+ assert r.content
+ assert e.call_count == 1
+ e.reset_mock()
+ assert r.content
+ assert e.call_count == 0
def test_modify(self):
r = tresp()
assert "content-encoding" not in r.headers
- assert r.encode("gzip")
+ r.encode("gzip")
+
+ r.content = b"foo"
+ assert r.raw_content != b"foo"
+ r.decode()
+ assert r.raw_content == b"foo"
- with decoded(r):
+ r.encode("identity")
+ with mock.patch("netlib.encoding.encode") as e:
r.content = b"foo"
+ assert e.call_count == 0
+ r.content = b"bar"
+ assert e.call_count == 1
- assert r.content != b"foo"
- r.decode()
- assert r.content == b"foo"
+ with tutils.raises(TypeError):
+ r.content = u"foo"
def test_unknown_ce(self):
r = tresp()
r.headers["content-encoding"] = "zopfli"
- r.content = b"foo"
- with decoded(r):
- assert r.headers["content-encoding"]
- assert r.content == b"foo"
+ r.raw_content = b"foo"
+ with tutils.raises(ValueError):
+ assert r.content
assert r.headers["content-encoding"]
- assert r.content == b"foo"
+ assert r.get_content(strict=False) == b"foo"
def test_cannot_decode(self):
r = tresp()
- assert r.encode("gzip")
- r.content = b"foo"
- with decoded(r):
- assert r.headers["content-encoding"]
- assert r.content == b"foo"
+ r.encode("gzip")
+ r.raw_content = b"foo"
+ with tutils.raises(ValueError):
+ assert r.content
assert r.headers["content-encoding"]
- assert r.content != b"foo"
- r.decode()
+ assert r.get_content(strict=False) == b"foo"
+
+ with tutils.raises(ValueError):
+ r.decode()
+ assert r.raw_content == b"foo"
+ assert "content-encoding" in r.headers
+
+ r.decode(strict=False)
assert r.content == b"foo"
+ assert "content-encoding" not in r.headers
+
+ def test_none(self):
+ r = tresp(content=None)
+ assert r.content is None
+ r.content = b"foo"
+ assert r.content is not None
+ r.content = None
+ assert r.content is None
def test_cannot_encode(self):
r = tresp()
- assert r.encode("gzip")
- with decoded(r):
- r.content = None
+ r.encode("gzip")
+ r.content = None
+ assert r.headers["content-encoding"]
+ assert r.raw_content is None
+ r.headers["content-encoding"] = "zopfli"
+ r.content = b"foo"
assert "content-encoding" not in r.headers
- assert r.content is None
+ assert r.raw_content == b"foo"
+
+ with tutils.raises(ValueError):
+ r.encode("zopfli")
+ assert r.raw_content == b"foo"
+ assert "content-encoding" not in r.headers
+
+
+class TestMessageText(object):
+ def test_simple(self):
+ r = tresp(content=b'\xfc')
+ assert r.raw_content == b"\xfc"
+ assert r.content == b"\xfc"
+ assert r.text == u"ü"
+
+ r.encode("gzip")
+ assert r.text == u"ü"
+ r.decode()
+ assert r.text == u"ü"
+
+ r.headers["content-type"] = "text/html; charset=latin1"
+ r.content = b"\xc3\xbc"
+ assert r.text == u"ü"
+ r.headers["content-type"] = "text/html; charset=utf8"
+ assert r.text == u"ü"
+
+ r.encode("identity")
+ r.raw_content = b"foo"
+ with mock.patch("netlib.encoding.decode") as e:
+ assert r.text
+ assert e.call_count == 2
+ e.reset_mock()
+ assert r.text
+ assert e.call_count == 0
+
+ def test_guess_json(self):
+ r = tresp(content=b'"\xc3\xbc"')
+ r.headers["content-type"] = "application/json"
+ assert r.text == u'"ü"'
+
+ def test_none(self):
+ r = tresp(content=None)
+ assert r.text is None
+ r.text = u"foo"
+ assert r.text is not None
+ r.text = None
+ assert r.text is None
+
+ def test_modify(self):
+ r = tresp()
+
+ r.text = u"ü"
+ assert r.raw_content == b"\xfc"
+
+ r.headers["content-type"] = "text/html; charset=utf8"
+ r.text = u"ü"
+ assert r.raw_content == b"\xc3\xbc"
+ assert r.headers["content-length"] == "2"
+
+ r.encode("identity")
+ with mock.patch("netlib.encoding.encode") as e:
+ e.return_value = b""
+ r.text = u"ü"
+ assert e.call_count == 0
+ r.text = u"ä"
+ assert e.call_count == 2
+
+ def test_unknown_ce(self):
+ r = tresp()
+ r.headers["content-type"] = "text/html; charset=wtf"
+ r.raw_content = b"foo"
+ with tutils.raises(ValueError):
+ assert r.text == u"foo"
+ assert r.get_text(strict=False) == u"foo"
+
+ def test_cannot_decode(self):
+ r = tresp()
+ r.headers["content-type"] = "text/html; charset=utf8"
+ r.raw_content = b"\xFF"
+ with tutils.raises(ValueError):
+ assert r.text
+
+ assert r.get_text(strict=False) == u'\ufffd' if six.PY2 else '\udcff'
+
+ def test_cannot_encode(self):
+ r = tresp()
+ r.content = None
+ assert "content-type" not in r.headers
+ assert r.raw_content is None
+
+ r.headers["content-type"] = "text/html; charset=latin1; foo=bar"
+ r.text = u"☃"
+ assert r.headers["content-type"] == "text/html; charset=utf-8; foo=bar"
+ assert r.raw_content == b'\xe2\x98\x83'
+
+ r.headers["content-type"] = "gibberish"
+ r.text = u"☃"
+ assert r.headers["content-type"] == "text/plain; charset=utf-8"
+ assert r.raw_content == b'\xe2\x98\x83'
+
+ del r.headers["content-type"]
+ r.text = u"☃"
+ assert r.headers["content-type"] == "text/plain; charset=utf-8"
+ assert r.raw_content == b'\xe2\x98\x83'
+
+ r.headers["content-type"] = "text/html; charset=latin1"
+ r.text = u'\udcff'
+ assert r.headers["content-type"] == "text/html; charset=utf-8"
+ assert r.raw_content == b'\xed\xb3\xbf' if six.PY2 else b"\xFF"
diff --git a/test/netlib/test_encoding.py b/test/netlib/test_encoding.py
index 0ff1aad1..de10fc48 100644
--- a/test/netlib/test_encoding.py
+++ b/test/netlib/test_encoding.py
@@ -1,37 +1,39 @@
-from netlib import encoding
+from netlib import encoding, tutils
def test_identity():
- assert b"string" == encoding.decode("identity", b"string")
- assert b"string" == encoding.encode("identity", b"string")
- assert not encoding.encode("nonexistent", b"string")
- assert not encoding.decode("nonexistent encoding", b"string")
+ assert b"string" == encoding.decode(b"string", "identity")
+ assert b"string" == encoding.encode(b"string", "identity")
+ with tutils.raises(ValueError):
+ encoding.encode(b"string", "nonexistent encoding")
def test_gzip():
assert b"string" == encoding.decode(
- "gzip",
encoding.encode(
- "gzip",
- b"string"
- )
+ b"string",
+ "gzip"
+ ),
+ "gzip"
)
- assert encoding.decode("gzip", b"bogus") is None
+ with tutils.raises(ValueError):
+ encoding.decode(b"bogus", "gzip")
def test_deflate():
assert b"string" == encoding.decode(
- "deflate",
encoding.encode(
- "deflate",
- b"string"
- )
+ b"string",
+ "deflate"
+ ),
+ "deflate"
)
assert b"string" == encoding.decode(
- "deflate",
encoding.encode(
- "deflate",
- b"string"
- )[2:-4]
+ b"string",
+ "deflate"
+ )[2:-4],
+ "deflate"
)
- assert encoding.decode("deflate", b"bogus") is None
+ with tutils.raises(ValueError):
+ encoding.decode(b"bogus", "deflate")
diff --git a/test/netlib/test_strutils.py b/test/netlib/test_strutils.py
index 68bfdb94..7c3eacc6 100644
--- a/test/netlib/test_strutils.py
+++ b/test/netlib/test_strutils.py
@@ -38,8 +38,9 @@ def test_escape_control_characters():
u'=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.'
)
- with tutils.raises(ValueError):
- strutils.escape_control_characters(b"foo")
+ if not six.PY2:
+ with tutils.raises(ValueError):
+ strutils.escape_control_characters(b"foo")
def test_bytes_to_escaped_str():