import pytest
from eggfetch.compat.httpx import (
Auth,
AsyncClient,
Client,
MockTransport,
Request,
Response,
)
class ReplayRequiredAuth(Auth):
def auth_flow(self, request):
request.headers["x-attempt"] = "first"
response = yield request
if response.status_code == 401:
request.headers["x-attempt"] = "second"
response = yield request
class TestSyncReplayBehavior:
def test_bytes_body_replay_succeeds(self):
def handler(request):
attempt = request.headers.get("x-attempt", "")
if attempt == "first":
return Response(401)
return Response(200, text="ok")
with Client(
auth=ReplayRequiredAuth(),
transport=MockTransport(handler),
) as client:
resp = client.post("http://testserver/", content=b"payload")
assert resp.status_code == 200
def test_string_body_replay_succeeds(self):
def handler(request):
attempt = request.headers.get("x-attempt", "")
if attempt == "first":
return Response(401)
return Response(200, text="ok")
with Client(
auth=ReplayRequiredAuth(),
transport=MockTransport(handler),
) as client:
resp = client.post("http://testserver/", content="payload")
assert resp.status_code == 200
def test_iterator_body_buffered_on_read(self):
def body_gen():
yield b"chunk1"
yield b"chunk2"
def handler(request):
body = request.read()
attempt = request.headers.get("x-attempt", "")
if attempt == "first":
return Response(401)
return Response(200, text=f"received={body}")
with Client(
auth=ReplayRequiredAuth(),
transport=MockTransport(handler),
) as client:
resp = client.post("http://testserver/", content=body_gen())
assert resp.status_code == 200
assert "received=b" in resp.text
def test_iterator_body_replay_uses_buffered_content(self):
read_count = [0]
def body_gen():
yield b"data"
def handler(request):
read_count[0] += 1
body = request.read()
if read_count[0] == 1:
return Response(401)
return Response(200, text=f"replay={body}")
with Client(
auth=ReplayRequiredAuth(),
transport=MockTransport(handler),
) as client:
resp = client.post("http://testserver/", content=body_gen())
assert resp.status_code == 200
assert "replay=b'data'" in resp.text
assert read_count[0] == 2
def test_empty_body_replay_succeeds(self):
def handler(request):
attempt = request.headers.get("x-attempt", "")
if attempt == "first":
return Response(401)
return Response(200, text="ok")
with Client(
auth=ReplayRequiredAuth(),
transport=MockTransport(handler),
) as client:
resp = client.post("http://testserver/", content=b"")
assert resp.status_code == 200
def test_no_body_request_replay_succeeds(self):
def handler(request):
attempt = request.headers.get("x-attempt", "")
if attempt == "first":
return Response(401)
return Response(200, text="ok")
with Client(
auth=ReplayRequiredAuth(),
transport=MockTransport(handler),
) as client:
resp = client.get("http://testserver/")
assert resp.status_code == 200
class TestAsyncReplayBehavior:
@pytest.mark.asyncio
async def test_async_bytes_body_replay_succeeds(self):
async def handler(request):
attempt = request.headers.get("x-attempt", "")
if attempt == "first":
return Response(401)
return Response(200, text="ok")
async with AsyncClient(
auth=ReplayRequiredAuth(),
async_transport=MockTransport(handler),
) as client:
resp = await client.post("http://testserver/", content=b"payload")
assert resp.status_code == 200
@pytest.mark.asyncio
async def test_async_string_body_replay_succeeds(self):
async def handler(request):
attempt = request.headers.get("x-attempt", "")
if attempt == "first":
return Response(401)
return Response(200, text="ok")
async with AsyncClient(
auth=ReplayRequiredAuth(),
async_transport=MockTransport(handler),
) as client:
resp = await client.post("http://testserver/", content="payload")
assert resp.status_code == 200
@pytest.mark.asyncio
async def test_async_empty_body_replay_succeeds(self):
async def handler(request):
attempt = request.headers.get("x-attempt", "")
if attempt == "first":
return Response(401)
return Response(200, text="ok")
async with AsyncClient(
auth=ReplayRequiredAuth(),
async_transport=MockTransport(handler),
) as client:
resp = await client.post("http://testserver/", content=b"")
assert resp.status_code == 200
@pytest.mark.asyncio
async def test_async_no_body_request_replay_succeeds(self):
async def handler(request):
attempt = request.headers.get("x-attempt", "")
if attempt == "first":
return Response(401)
return Response(200, text="ok")
async with AsyncClient(
auth=ReplayRequiredAuth(),
async_transport=MockTransport(handler),
) as client:
resp = await client.get("http://testserver/")
assert resp.status_code == 200