Skip to content

Commit

Permalink
Also cover AsyncClient in test_async tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Gallaecio committed Mar 19, 2024
1 parent dad2589 commit 2b3da7e
Showing 1 changed file with 121 additions and 42 deletions.
163 changes: 121 additions & 42 deletions tests/test_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,41 @@

from zyte_api import AsyncZyteAPI, RequestError
from zyte_api._retry import RetryFactory
from zyte_api.aio.client import AsyncClient
from zyte_api.apikey import NoApiKey
from zyte_api.errors import ParsedError

from .mockserver import DropResource, MockServer


def test_api_key():
AsyncZyteAPI(api_key="a")
@pytest.mark.parametrize(
("client_cls",),
(
(AsyncZyteAPI,),
(AsyncClient,),
),
)
def test_api_key(client_cls):
client_cls(api_key="a")
with pytest.raises(NoApiKey):
AsyncZyteAPI()
client_cls()


@pytest.mark.parametrize(
("client_cls", "get_method"),
(
(AsyncZyteAPI, "get"),
(AsyncClient, "request_raw"),
),
)
@pytest.mark.asyncio
async def test_get(mockserver):
client = AsyncZyteAPI(api_key="a", api_url=mockserver.urljoin("/"))
async def test_get(client_cls, get_method, mockserver):
client = client_cls(api_key="a", api_url=mockserver.urljoin("/"))
expected_result = {
"url": "https://a.example",
"httpResponseBody": "PGh0bWw+PGJvZHk+SGVsbG88aDE+V29ybGQhPC9oMT48L2JvZHk+PC9odG1sPg==",
}
actual_result = await client.get(
actual_result = await getattr(client, get_method)(
{"url": "https://a.example", "httpResponseBody": True}
)
assert actual_result == expected_result
Expand All @@ -35,6 +50,13 @@ class OutlierException(RuntimeError):
pass


@pytest.mark.parametrize(
("client_cls", "get_method"),
(
(AsyncZyteAPI, "get"),
(AsyncClient, "request_raw"),
),
)
@pytest.mark.parametrize(
("value", "exception"),
(
Expand All @@ -44,7 +66,7 @@ class OutlierException(RuntimeError):
),
)
@pytest.mark.asyncio
async def test_get_handle_retries(value, exception, mockserver):
async def test_get_handle_retries(client_cls, get_method, value, exception, mockserver):
kwargs = {}
if value is not UNSET:
kwargs["handle_retries"] = value
Expand All @@ -53,21 +75,26 @@ def broken_stop(_):
raise OutlierException

retrying = AsyncRetrying(stop=broken_stop)
client = AsyncZyteAPI(
api_key="a", api_url=mockserver.urljoin("/"), retrying=retrying
)
client = client_cls(api_key="a", api_url=mockserver.urljoin("/"), retrying=retrying)
with pytest.raises(exception):
await client.get(
await getattr(client, get_method)(
{"url": "https://exception.example", "browserHtml": True},
**kwargs,
)


@pytest.mark.parametrize(
("client_cls", "get_method"),
(
(AsyncZyteAPI, "get"),
(AsyncClient, "request_raw"),
),
)
@pytest.mark.asyncio
async def test_get_request_error(mockserver):
client = AsyncZyteAPI(api_key="a", api_url=mockserver.urljoin("/"))
async def test_get_request_error(client_cls, get_method, mockserver):
client = client_cls(api_key="a", api_url=mockserver.urljoin("/"))
with pytest.raises(RequestError) as request_error_info:
await client.get(
await getattr(client, get_method)(
{"url": "https://exception.example", "browserHtml": True},
)
parsed_error = request_error_info.value.parsed
Expand All @@ -80,45 +107,73 @@ async def test_get_request_error(mockserver):
}


@pytest.mark.parametrize(
("client_cls", "get_method"),
(
(AsyncZyteAPI, "get"),
(AsyncClient, "request_raw"),
),
)
@pytest.mark.asyncio
async def test_get_request_error_empty_body(mockserver):
client = AsyncZyteAPI(api_key="a", api_url=mockserver.urljoin("/"))
async def test_get_request_error_empty_body(client_cls, get_method, mockserver):
client = client_cls(api_key="a", api_url=mockserver.urljoin("/"))
with pytest.raises(RequestError) as request_error_info:
await client.get(
await getattr(client, get_method)(
{"url": "https://empty-body-exception.example", "browserHtml": True},
)
parsed_error = request_error_info.value.parsed
assert isinstance(parsed_error, ParsedError)
assert parsed_error.data is None


@pytest.mark.parametrize(
("client_cls", "get_method"),
(
(AsyncZyteAPI, "get"),
(AsyncClient, "request_raw"),
),
)
@pytest.mark.asyncio
async def test_get_request_error_non_json(mockserver):
client = AsyncZyteAPI(api_key="a", api_url=mockserver.urljoin("/"))
async def test_get_request_error_non_json(client_cls, get_method, mockserver):
client = client_cls(api_key="a", api_url=mockserver.urljoin("/"))
with pytest.raises(RequestError) as request_error_info:
await client.get(
await getattr(client, get_method)(
{"url": "https://nonjson-exception.example", "browserHtml": True},
)
parsed_error = request_error_info.value.parsed
assert isinstance(parsed_error, ParsedError)
assert parsed_error.data is None


@pytest.mark.parametrize(
("client_cls", "get_method"),
(
(AsyncZyteAPI, "get"),
(AsyncClient, "request_raw"),
),
)
@pytest.mark.asyncio
async def test_get_request_error_unexpected_json(mockserver):
client = AsyncZyteAPI(api_key="a", api_url=mockserver.urljoin("/"))
async def test_get_request_error_unexpected_json(client_cls, get_method, mockserver):
client = client_cls(api_key="a", api_url=mockserver.urljoin("/"))
with pytest.raises(RequestError) as request_error_info:
await client.get(
await getattr(client, get_method)(
{"url": "https://array-exception.example", "browserHtml": True},
)
parsed_error = request_error_info.value.parsed
assert isinstance(parsed_error, ParsedError)
assert parsed_error.data is None


@pytest.mark.parametrize(
("client_cls", "iter_method"),
(
(AsyncZyteAPI, "iter"),
(AsyncClient, "request_parallel_as_completed"),
),
)
@pytest.mark.asyncio
async def test_iter(mockserver):
client = AsyncZyteAPI(api_key="a", api_url=mockserver.urljoin("/"))
async def test_iter(client_cls, iter_method, mockserver):
client = client_cls(api_key="a", api_url=mockserver.urljoin("/"))
queries = [
{"url": "https://a.example", "httpResponseBody": True},
{"url": "https://exception.example", "httpResponseBody": True},
Expand All @@ -136,7 +191,7 @@ async def test_iter(mockserver):
},
]
actual_results = []
for future in client.iter(queries):
for future in getattr(client, iter_method)(queries):
try:
actual_result = await future
except Exception as exception:
Expand All @@ -150,6 +205,13 @@ async def test_iter(mockserver):
assert actual_result in expected_results


@pytest.mark.parametrize(
("client_cls", "get_method"),
(
(AsyncZyteAPI, "get"),
(AsyncClient, "request_raw"),
),
)
@pytest.mark.parametrize(
("subdomain", "waiter"),
(
Expand All @@ -158,7 +220,7 @@ async def test_iter(mockserver):
),
)
@pytest.mark.asyncio
async def test_retry_wait(subdomain, waiter, mockserver):
async def test_retry_wait(client_cls, get_method, subdomain, waiter, mockserver):
def broken_wait(self, retry_state):
raise OutlierException

Expand All @@ -168,17 +230,22 @@ class CustomRetryFactory(RetryFactory):
setattr(CustomRetryFactory, f"{waiter}_wait", broken_wait)

retrying = CustomRetryFactory().build()
client = AsyncZyteAPI(
api_key="a", api_url=mockserver.urljoin("/"), retrying=retrying
)
client = client_cls(api_key="a", api_url=mockserver.urljoin("/"), retrying=retrying)
with pytest.raises(OutlierException):
await client.get(
await getattr(client, get_method)(
{"url": f"https://{subdomain}.example", "browserHtml": True},
)


@pytest.mark.parametrize(
("client_cls", "get_method"),
(
(AsyncZyteAPI, "get"),
(AsyncClient, "request_raw"),
),
)
@pytest.mark.asyncio
async def test_retry_wait_network_error():
async def test_retry_wait_network_error(client_cls, get_method):
waiter = "network_error"

def broken_wait(self, retry_state):
Expand All @@ -191,15 +258,22 @@ class CustomRetryFactory(RetryFactory):

retrying = CustomRetryFactory().build()
with MockServer(resource=DropResource) as mockserver:
client = AsyncZyteAPI(
client = client_cls(
api_key="a", api_url=mockserver.urljoin("/"), retrying=retrying
)
with pytest.raises(OutlierException):
await client.get(
await getattr(client, get_method)(
{"url": "https://example.com", "browserHtml": True},
)


@pytest.mark.parametrize(
("client_cls", "get_method"),
(
(AsyncZyteAPI, "get"),
(AsyncClient, "request_raw"),
),
)
@pytest.mark.parametrize(
("subdomain", "stopper"),
(
Expand All @@ -208,7 +282,7 @@ class CustomRetryFactory(RetryFactory):
),
)
@pytest.mark.asyncio
async def test_retry_stop(subdomain, stopper, mockserver):
async def test_retry_stop(client_cls, get_method, subdomain, stopper, mockserver):
def broken_stop(self, retry_state):
raise OutlierException

Expand All @@ -219,17 +293,22 @@ def wait(self, retry_state):
setattr(CustomRetryFactory, f"{stopper}_stop", broken_stop)

retrying = CustomRetryFactory().build()
client = AsyncZyteAPI(
api_key="a", api_url=mockserver.urljoin("/"), retrying=retrying
)
client = client_cls(api_key="a", api_url=mockserver.urljoin("/"), retrying=retrying)
with pytest.raises(OutlierException):
await client.get(
await getattr(client, get_method)(
{"url": f"https://{subdomain}.example", "browserHtml": True},
)


@pytest.mark.parametrize(
("client_cls", "get_method"),
(
(AsyncZyteAPI, "get"),
(AsyncClient, "request_raw"),
),
)
@pytest.mark.asyncio
async def test_retry_stop_network_error():
async def test_retry_stop_network_error(client_cls, get_method):
stopper = "network_error"

def broken_stop(self, retry_state):
Expand All @@ -243,10 +322,10 @@ def wait(self, retry_state):

retrying = CustomRetryFactory().build()
with MockServer(resource=DropResource) as mockserver:
client = AsyncZyteAPI(
client = client_cls(
api_key="a", api_url=mockserver.urljoin("/"), retrying=retrying
)
with pytest.raises(OutlierException):
await client.get(
await getattr(client, get_method)(
{"url": "https://example.com", "browserHtml": True},
)

0 comments on commit 2b3da7e

Please sign in to comment.