async def test_cookies_jar_single_cookie(): fake_pools = FakePools([ Response(200, [ (b"Set-Cookie", write_response_cookie(Cookie(b"X-Foo", b"Foo"))) ]).with_content(TextContent("Hello, World!")), Response(200, None, TextContent("Hello!")), ]) check_cookie = False async def middleware_for_assertions(request, next_handler): if check_cookie: cookie = request.cookies.get("X-Foo") assert (cookie is not None ), "X-Foo cookie must be configured for following requests" return await next_handler(request) async with ClientSession( base_url=b"https://bezkitu.org", pools=fake_pools, middlewares=[middleware_for_assertions], ) as client: await client.get( b"/" ) # the first request doesn't have any cookie because the response will set; check_cookie = True await client.get(b"/")
async def test_cookies_jar(first_request_url, second_request_url, set_cookies, expected_cookies): fake_pools = FakePools([ Response(200, Headers(set_cookies), TextContent('Hello, World!')), Response(200, Headers(), TextContent('Hello!')) ]) check_cookie = False async def middleware_for_assertions(request, next_handler): if check_cookie: if not expected_cookies: assert not request.cookies for expected_cookie in expected_cookies: cookie = request.cookies.get(expected_cookie) assert cookie is not None, f'{cookie.name.decode()} cookie must be configured for following requests' return await next_handler(request) async with ClientSession( pools=fake_pools, middlewares=[middleware_for_assertions], ) as client: await client.get(first_request_url) check_cookie = True await client.get(second_request_url)
async def test_cookies_jar_single_cookie(): fake_pools = FakePools([ Response( 200, Headers([ Header(b'Set-Cookie', write_response_cookie(Cookie(b'X-Foo', b'Foo'))) ]), TextContent('Hello, World!')), Response(200, Headers(), TextContent('Hello!')) ]) check_cookie = False async def middleware_for_assertions(request, next_handler): if check_cookie: cookie = request.cookies.get(b'X-Foo') assert cookie is not None, 'X-Foo cookie must be configured for following requests' return await next_handler(request) async with ClientSession(url=b'https://bezkitu.org', pools=fake_pools, middlewares=[middleware_for_assertions ]) as client: await client.get( b'/' ) # the first request doesn't have any cookie because the response will set; check_cookie = True await client.get(b'/')
async def test_multiple_middleware(): fake_pools = FakePools([Response(200, None, TextContent("Hello, World!"))]) steps = [] async def middleware_one(request, next_handler): steps.append(1) response = await next_handler(request) steps.append(2) return response async def middleware_two(request, next_handler): steps.append(3) response = await next_handler(request) steps.append(4) return response async def middleware_three(request, next_handler): steps.append(5) response = await next_handler(request) steps.append(6) return response async with ClientSession( base_url=b"http://localhost:8080", pools=fake_pools, middlewares=[middleware_one, middleware_two, middleware_three], ) as client: response = await client.get(b"/") assert steps == [1, 3, 5, 6, 4, 2] assert response.status == 200 text = await response.text() assert text == "Hello, World!"
def status_code(status: int = 200, message: MessageType = None): """Returns a plain response with given status, with optional message; sent as plain text or JSON.""" if not message: return Response(status) if isinstance(message, str): content = TextContent(message) else: content = JsonContent(message) return Response(status, content=content)
async def handle_unauthorized(app: Any, request: Request, http_exception: UnauthorizedError) -> Response: www_authenticate = get_www_authenticated_header_from_generic_unauthorized_error( http_exception) return Response( 401, [www_authenticate] if www_authenticate else None, content=TextContent("Unauthorized"), )
async def test_remove_cookie_with_max_age(): expire_cookie = Cookie("X-Foo", "Foo") expire_cookie.max_age = 0 fake_pools = FakePools( [ Response( 200, [(b"Set-Cookie", write_response_cookie(Cookie("X-Foo", "Foo")))], TextContent("Hello, World!"), ), Response(200, None, TextContent("Hello!")), Response( 200, [(b"Set-Cookie", write_response_cookie(expire_cookie))], TextContent("Hello, World!"), ), Response(200, None, TextContent("Hello!")), ] ) expect_cookie = False async def middleware_for_assertions(request, next_handler): cookie = request.cookies.get("X-Foo") if expect_cookie: assert cookie is not None, "X-Foo cookie must be configured" else: assert cookie is None return await next_handler(request) async with ClientSession( base_url=b"https://bezkitu.org", pools=fake_pools, middlewares=[middleware_for_assertions], ) as client: await client.get(b"/") # <-- cookie set here expect_cookie = True await client.get(b"/") # <-- expect cookie in request expect_cookie = True await client.get(b"/") # <-- expect cookie in request; it gets removed here expect_cookie = False await client.get( b"/" ) # <-- expect missing cookie; was deleted by previous response
async def test_remove_cookie_with_expiration(): expire_cookie = Cookie(b'X-Foo', b'Foo') expire_cookie.expiration = datetime.utcnow() + timedelta(days=-2) fake_pools = FakePools([ Response( 200, Headers([ Header(b'Set-Cookie', write_response_cookie(Cookie(b'X-Foo', b'Foo'))) ]), TextContent('Hello, World!')), Response(200, Headers(), TextContent('Hello!')), Response( 200, Headers( [Header(b'Set-Cookie', write_response_cookie(expire_cookie))]), TextContent('Hello, World!')), Response(200, Headers(), TextContent('Hello!')) ]) expect_cookie = False async def middleware_for_assertions(request, next_handler): cookie = request.cookies.get(b'X-Foo') if expect_cookie: assert cookie is not None, 'X-Foo cookie must be configured' else: assert cookie is None return await next_handler(request) async with ClientSession(url=b'https://bezkitu.org', pools=fake_pools, middlewares=[middleware_for_assertions ]) as client: await client.get(b'/') # <-- cookie set here expect_cookie = True await client.get(b'/') # <-- expect cookie in request expect_cookie = True await client.get( b'/') # <-- expect cookie in request; it gets removed here expect_cookie = False await client.get( b'/' ) # <-- expect missing cookie; was deleted by previous response
async def test_query_params_concatenation(request_url, params, expected_query): fake_pools = FakePools([Response(200, None, TextContent('Hello, World!'))]) async def middleware_for_assertions(request, next_handler): assert expected_query == request.url.query return await next_handler(request) async with ClientSession(base_url=b'http://localhost:8080', pools=fake_pools, middlewares=[middleware_for_assertions ]) as client: await client.get(request_url, params=params)
async def test_request_headers(): fake_pools = FakePools([Response(200, [], TextContent('Hello, World!'))]) async def middleware_for_assertions(request, next_handler): assert b'Hello' in request.headers assert request.headers.get_single(b'Hello') == b'World' return await next_handler(request) async with ClientSession(base_url=b'http://localhost:8080', pools=fake_pools, middlewares=[middleware_for_assertions ]) as client: await client.get(b'/', headers=[(b'Hello', b'World')]) await client.post(b'/', headers=[(b'Hello', b'World')]) await client.put(b'/', headers=[(b'Hello', b'World')]) await client.delete(b'/', headers=[(b'Hello', b'World')])
async def test_request_headers(): fake_pools = FakePools([Response(200, [], TextContent("Hello, World!"))]) async def middleware_for_assertions(request, next_handler): assert b"Hello" in request.headers assert request.headers.get_single(b"Hello") == b"World" return await next_handler(request) async with ClientSession( base_url=b"http://localhost:8080", pools=fake_pools, middlewares=[middleware_for_assertions], ) as client: await client.get(b"/", headers=[(b"Hello", b"World")]) await client.post(b"/", headers=[(b"Hello", b"World")]) await client.put(b"/", headers=[(b"Hello", b"World")]) await client.delete(b"/", headers=[(b"Hello", b"World")])
async def test_middlewares_can_be_applied_multiple_times_without_changing(): fake_pools = FakePools( [Response(200, Headers(), TextContent('Hello, World!'))]) steps = [] async def middleware_one(request, next_handler): steps.append(1) response = await next_handler(request) steps.append(2) return response async def middleware_two(request, next_handler): steps.append(3) response = await next_handler(request) steps.append(4) return response async def middleware_three(request, next_handler): steps.append(5) response = await next_handler(request) steps.append(6) return response async with ClientSession(url=b'http://localhost:8080', pools=fake_pools) as client: client.add_middlewares([middleware_one]) client.add_middlewares([middleware_two]) client.add_middlewares([middleware_three]) assert middleware_one in client._middlewares assert middleware_two in client._middlewares assert middleware_three in client._middlewares client._build_middlewares_chain() response = await client.get(b'/') assert steps == [1, 3, 5, 6, 4, 2] assert response.status == 200 text = await response.text() assert text == 'Hello, World!'
async def test_query_params(params, expected_query): fake_pools = FakePools([Response(200, None, TextContent("Hello, World!"))]) async def middleware_for_assertions(request, next_handler): assert expected_query == request.url.query return await next_handler(request) async with ClientSession( base_url=b"http://localhost:8080", pools=fake_pools, middlewares=[middleware_for_assertions], ) as client: await client.get(b"/", params=params) await client.head(b"/", params=params) await client.post(b"/", params=params) await client.put(b"/", params=params) await client.patch(b"/", params=params) await client.delete(b"/", params=params) await client.options(b"/", params=params) await client.trace(b"/", params=params)
async def test_default_headers(): fake_pools = FakePools( [Response(200, Headers(), TextContent('Hello, World!'))]) async def middleware_for_assertions(request, next_handler): assert b'hello' in request.headers assert request.headers.get_single(b'hello').value == b'World' assert b'Foo' in request.headers assert request.headers.get_single(b'Foo').value == b'Power' return await next_handler(request) async with ClientSession(url=b'http://localhost:8080', pools=fake_pools, middlewares=[middleware_for_assertions], default_headers=[ Header(b'Hello', b'World'), Header(b'Foo', b'Power') ]) as client: await client.get(b'/')
async def test_single_middleware(): fake_pools = FakePools( [Response(200, Headers(), TextContent('Hello, World!'))]) steps = [] async def middleware_one(request, next_handler): steps.append(1) response = await next_handler(request) steps.append(2) return response async with ClientSession(url=b'http://localhost:8080', pools=fake_pools, middlewares=[middleware_one]) as client: response = await client.get(b'/') assert steps == [1, 2] assert response.status == 200 text = await response.text() assert text == 'Hello, World!'
async def test_falsy_middleware(): fake_pools = FakePools([Response(200, None, TextContent("Hello, World!"))]) steps = [] async def middleware_one(request, next_handler): steps.append(1) response = await next_handler(request) steps.append(2) return response async with ClientSession( base_url=b"http://localhost:8080", pools=fake_pools, middlewares=[middleware_one, None, False], # type: ignore ) as client: response = await client.get(b"/") assert steps == [1, 2] assert response.status == 200 text = await response.text() assert text == "Hello, World!"
async def handle_authentication_challenge(app, request, exception: AuthenticateChallenge): return Response(401, [exception.get_header()], content=TextContent('Unauthorized'))
return FakePools(fake_responses) return get_pools def get_scenarios(fn): args = [] for status in {301, 302, 303, 307, 308}: args.append(fn(status)) return args @pytest.mark.asyncio @pytest.mark.parametrize('responses,expected_status,expected_location', get_scenarios(lambda status: [ [ Response(status, Headers([Header(b'Location', b'urn:oasis:names:specification:docbook:dtd:xml:4.1.2')])), Response(200, Headers(), TextContent('Hello, World!')) ], status, b'urn:oasis:names:specification:docbook:dtd:xml:4.1.2' ]) + get_scenarios(lambda status: [ [ Response(status, Headers([Header(b'Location', b'msalf84227e26-9a47-4c00-a92c-1b1bad8225cc://auth')])), Response(200, Headers(), TextContent('Hello, World!')) ], status, b'msalf84227e26-9a47-4c00-a92c-1b1bad8225cc://auth' ])) async def test_non_url_redirect(responses, expected_status, expected_location, pools_factory): async with ClientSession(url=b'http://localhost:8080', pools=pools_factory(responses)) as client: response = await client.get(b'/') assert response is not None assert response.status == expected_status
async def exception_handler(self, request, exc: CustomException): nonlocal app assert self is app assert isinstance(exc, CustomException) return Response(200, content=TextContent('Called'))
async def exception_handler(self, request, exception: CustomException): nonlocal called assert request is not None called = True return Response(200, content=TextContent('Called'))
async def exception_handler(self, request, http_exception): nonlocal app assert self is app return Response(200, content=TextContent('Called'))
def get_scenarios(fn): args = [] for status in {301, 302, 303, 307, 308}: args.append(fn(status)) return args @pytest.mark.asyncio @pytest.mark.parametrize( 'responses,expected_status,expected_location', get_scenarios(lambda status: [[ Response(status, [(b'Location', b'urn:oasis:names:specification:docbook:dtd:xml:4.1.2')]), Response(200, None, TextContent('Hello, World!')) ], status, b'urn:oasis:names:specification:docbook:dtd:xml:4.1.2']) + get_scenarios(lambda status: [[ Response(status, [ (b'Location', b'msalf84227e26-9a47-4c00-a92c-1b1bad8225cc://auth') ]), Response(200, None, TextContent('Hello, World!')) ], status, b'msalf84227e26-9a47-4c00-a92c-1b1bad8225cc://auth'])) async def test_non_url_redirect(responses, expected_status, expected_location, pools_factory): async with ClientSession(base_url=b'http://localhost:8080', pools=pools_factory(responses)) as client: response = await client.get(b'/') assert response is not None
@pytest.mark.asyncio @pytest.mark.parametrize( "responses,expected_status,expected_location", get_scenarios( lambda status: [ [ Response( status, [ ( b"Location", b"urn:oasis:names:specification:docbook:dtd:xml:4.1.2", ) ], ), Response(200, None, TextContent("Hello, World!")), ], status, b"urn:oasis:names:specification:docbook:dtd:xml:4.1.2", ] ) + get_scenarios( lambda status: [ [ Response( status, [ ( b"Location", b"msalf84227e26-9a47-4c00-a92c-1b1bad8225cc://auth", )
def text(value: str, status: int = 200): """Returns a response with text/plain content, and given status (default HTTP 200 OK).""" return Response(status, content=TextContent(value))
async def handle_test_exception(app, request, http_exception): return Response(200, content=TextContent(f"Fake exception, to test handlers"))
def _optional_content(message: Any = None) -> Content: if isinstance(message, str): return TextContent(message) else: return _json_content(message)