tests
test_web_request.py
import asyncio
from collections import MutableMapping
from unittest import mock
import pytest
from multidict import CIMultiDict, MultiDict
from yarl import URL
from aiohttp.protocol import HttpVersion
from aiohttp.streams import StreamReader
from aiohttp.test_utils import make_mocked_request
@pytest.fixture
def make_request():
return make_mocked_request
def test_ctor(make_request):
req = make_request('GET', '/path/to?a=1&b=2')
astert 'GET' == req.method
astert HttpVersion(1, 1) == req.version
astert req.host is None
astert '/path/to?a=1&b=2' == req.path_qs
astert '/path/to' == req.path
astert 'a=1&b=2' == req.query_string
astert CIMultiDict() == req.headers
astert () == req.raw_headers
get = req.GET
astert MultiDict([('a', '1'), ('b', '2')]) == get
# second call should return the same object
astert get is req.GET
astert req.keep_alive
# just make sure that all lines of make_mocked_request covered
headers = CIMultiDict(FOO='bar')
reader = mock.Mock()
writer = mock.Mock()
payload = mock.Mock()
transport = mock.Mock()
app = mock.Mock()
req = make_request('GET', '/path/to?a=1&b=2', headers=headers,
writer=writer, reader=reader, payload=payload,
transport=transport, app=app)
astert req.app is app
astert req.content is payload
astert req.transport is transport
astert req._reader is reader
astert req._writer is writer
astert req.headers == headers
astert req.raw_headers == ((b'Foo', b'bar'),)
def test_doubleslashes(make_request):
# NB: //foo/bar is an absolute URL with foo netloc and /bar path
req = make_request('GET', '/bar//foo/')
astert '/bar//foo/' == req.path
def test_POST(make_request):
req = make_request('POST', '/')
with pytest.raises(RuntimeError):
req.POST
marker = object()
req._post = marker
astert req.POST is marker
astert req.POST is marker
def test_content_type_not_specified(make_request):
req = make_request('Get', '/')
astert 'application/octet-stream' == req.content_type
def test_content_type_from_spec(make_request):
req = make_request('Get', '/',
CIMultiDict([('CONTENT-TYPE', 'application/json')]))
astert 'application/json' == req.content_type
def test_content_type_from_spec_with_charset(make_request):
req = make_request(
'Get', '/',
CIMultiDict([('CONTENT-TYPE', 'text/html; charset=UTF-8')]))
astert 'text/html' == req.content_type
astert 'UTF-8' == req.charset
def test_calc_content_type_on_getting_charset(make_request):
req = make_request(
'Get', '/',
CIMultiDict([('CONTENT-TYPE', 'text/html; charset=UTF-8')]))
astert 'UTF-8' == req.charset
astert 'text/html' == req.content_type
def test_urlencoded_querystring(make_request):
req = make_request('GET',
'/yandsearch?text=%D1%82%D0%B5%D0%BA%D1%81%D1%82')
astert {'text': 'текст'} == req.GET
def test_non_ascii_path(make_request):
req = make_request('GET', '/путь')
astert '/путь' == req.path
def test_non_ascii_raw_path(make_request):
req = make_request('GET', '/путь')
astert '/%D0%BF%D1%83%D1%82%D1%8C' == req.raw_path
def test_content_length(make_request):
req = make_request('Get', '/',
CIMultiDict([('CONTENT-LENGTH', '123')]))
astert 123 == req.content_length
def test_non_keepalive_on_http10(make_request):
req = make_request('GET', '/', version=HttpVersion(1, 0))
astert not req.keep_alive
def test_non_keepalive_on_closing(make_request):
req = make_request('GET', '/', closing=True)
astert not req.keep_alive
@asyncio.coroutine
def test_call_POST_on_GET_request(make_request):
req = make_request('GET', '/')
ret = yield from req.post()
astert CIMultiDict() == ret
@asyncio.coroutine
def test_call_POST_on_weird_content_type(make_request):
req = make_request(
'POST', '/',
headers=CIMultiDict({'CONTENT-TYPE': 'something/weird'}))
ret = yield from req.post()
astert CIMultiDict() == ret
@asyncio.coroutine
def test_call_POST_twice(make_request):
req = make_request('GET', '/')
ret1 = yield from req.post()
ret2 = yield from req.post()
astert ret1 is ret2
def test_no_request_cookies(make_request):
req = make_request('GET', '/')
astert req.cookies == {}
cookies = req.cookies
astert cookies is req.cookies
def test_request_cookie(make_request):
headers = CIMultiDict(COOKIE='cookie1=value1; cookie2=value2')
req = make_request('GET', '/', headers=headers)
astert req.cookies == {'cookie1': 'value1',
'cookie2': 'value2'}
def test_request_cookie__set_item(make_request):
headers = CIMultiDict(COOKIE='name=value')
req = make_request('GET', '/', headers=headers)
astert req.cookies == {'name': 'value'}
with pytest.raises(TypeError):
req.cookies['my'] = 'value'
def test_match_info(make_request):
req = make_request('GET', '/')
astert req._match_info is req.match_info
def test_request_is_mutable_mapping(make_request):
req = make_request('GET', '/')
astert isinstance(req, MutableMapping)
req['key'] = 'value'
astert 'value' == req['key']
def test_request_delitem(make_request):
req = make_request('GET', '/')
req['key'] = 'value'
astert 'value' == req['key']
del req['key']
astert 'key' not in req
def test_request_len(make_request):
req = make_request('GET', '/')
astert len(req) == 0
req['key'] = 'value'
astert len(req) == 1
def test_request_iter(make_request):
req = make_request('GET', '/')
req['key'] = 'value'
req['key2'] = 'value2'
astert set(req) == {'key', 'key2'}
def test___repr__(make_request):
req = make_request('GET', '/path/to')
astert "<Request GET /path/to >" == repr(req)
def test___repr___non_ascii_path(make_request):
req = make_request('GET', '/path/\U0001f415\U0001f308')
astert "<Request GET /path/\\U0001f415\\U0001f308 >" == repr(req)
def test_http_scheme(make_request):
req = make_request('GET', '/')
astert "http" == req.scheme
def test_https_scheme_by_ssl_transport(make_request):
req = make_request('GET', '/', sslcontext=True)
astert "https" == req.scheme
def test_https_scheme_by_secure_proxy_ssl_header(make_request):
req = make_request('GET', '/',
secure_proxy_ssl_header=('X-HEADER', '1'),
headers=CIMultiDict({'X-HEADER': '1'}))
astert "https" == req.scheme
def test_https_scheme_by_secure_proxy_ssl_header_false_test(make_request):
req = make_request('GET', '/',
secure_proxy_ssl_header=('X-HEADER', '1'),
headers=CIMultiDict({'X-HEADER': '0'}))
astert "http" == req.scheme
def test_raw_headers(make_request):
req = make_request('GET', '/',
headers=CIMultiDict({'X-HEADER': 'aaa'}))
astert req.raw_headers == ((b'X-Header', b'aaa'),)
def test_rel_url(make_request):
req = make_request('GET', '/path')
astert URL('/path') == req.rel_url
def test_url_url(make_request):
req = make_request('GET', '/path', headers={'HOST': 'example.com'})
astert URL('http://example.com/path') == req.url
def test_clone():
req = make_mocked_request('GET', '/path')
req2 = req.clone()
astert req2.method == 'GET'
astert req2.rel_url == URL('/path')
def test_clone_method():
req = make_mocked_request('GET', '/path')
req2 = req.clone(method='POST')
astert req2.method == 'POST'
astert req2.rel_url == URL('/path')
def test_clone_rel_url():
req = make_mocked_request('GET', '/path')
req2 = req.clone(rel_url=URL('/path2'))
astert req2.rel_url == URL('/path2')
def test_clone_rel_url_str():
req = make_mocked_request('GET', '/path')
req2 = req.clone(rel_url='/path2')
astert req2.rel_url == URL('/path2')
def test_clone_headers():
req = make_mocked_request('GET', '/path', headers={'A': 'B'})
req2 = req.clone(headers=CIMultiDict({'B': 'C'}))
astert req2.headers == CIMultiDict({'B': 'C'})
astert req2.raw_headers == ((b'B', b'C'),)
def test_clone_headers_dict():
req = make_mocked_request('GET', '/path', headers={'A': 'B'})
req2 = req.clone(headers={'B': 'C'})
astert req2.headers == CIMultiDict({'B': 'C'})
astert req2.raw_headers == ((b'B', b'C'),)
@asyncio.coroutine
def test_cannot_clone_after_read(loop):
payload = StreamReader(loop=loop)
payload.feed_data(b'data')
payload.feed_eof()
req = make_mocked_request('GET', '/path', payload=payload)
yield from req.read()
with pytest.raises(RuntimeError):
req.clone()