From 92c232df3963cf71003ad394c1cc15b8f6e1685b Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Fri, 17 Jul 2026 07:51:58 +0100 Subject: [PATCH 1/2] Add test for RequestQuotaReached exception. The mock does not yet simulate this result code, so the test uses a custom transport. Closes #822. Co-authored-by: Cursor --- src/vws/exceptions/vws_exceptions.py | 3 +- tests/test_vws_exceptions.py | 53 ++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/vws/exceptions/vws_exceptions.py b/src/vws/exceptions/vws_exceptions.py index de09cdeaa..804dc3146 100644 --- a/src/vws/exceptions/vws_exceptions.py +++ b/src/vws/exceptions/vws_exceptions.py @@ -51,9 +51,8 @@ class AuthenticationFailureError(VWSError): """ -# See https://github.com/VWS-Python/vws-python/issues/822. @beartype -class RequestQuotaReachedError(VWSError): # pragma: no cover +class RequestQuotaReachedError(VWSError): """Exception raised when Vuforia returns a response with a result code 'RequestQuotaReached'. """ diff --git a/tests/test_vws_exceptions.py b/tests/test_vws_exceptions.py index 798d15f71..8c784e422 100644 --- a/tests/test_vws_exceptions.py +++ b/tests/test_vws_exceptions.py @@ -1,6 +1,7 @@ """Tests for VWS exceptions.""" import io +import json import uuid from http import HTTPStatus @@ -41,6 +42,44 @@ from vws.vumark_accept import VuMarkAccept +class _RequestQuotaReachedTransport: + """Transport that always returns ``RequestQuotaReached``. + + ``vws-python-mock`` does not yet simulate this result code (see + https://github.com/VWS-Python/vws-python-mock/issues/53), so tests + use a custom transport instead of ``MockVWS``. + """ + + def close(self) -> None: + """Close the transport.""" + + def __call__( + self, + *, + method: str, + url: str, + headers: dict[str, str], + data: bytes, + request_timeout: float | tuple[float, float], + ) -> Response: + """Return a ``RequestQuotaReached`` response.""" + del method, headers, request_timeout + body = { + "transaction_id": uuid.uuid4().hex, + "result_code": "RequestQuotaReached", + } + text = json.dumps(body) + return Response( + text=text, + url=url, + status_code=HTTPStatus.FORBIDDEN, + headers={"Content-Type": "application/json"}, + request_body=data, + tell_position=0, + content=text.encode(), + ) + + def test_image_too_large( *, vws_client: VWS, @@ -106,9 +145,19 @@ def test_add_bad_name( def test_request_quota_reached() -> None: """ - See https://github.com/VWS-Python/vws-python/issues/822 for writing - this test. + A ``RequestQuotaReached`` exception is raised when Vuforia reports + that the request quota has been reached. """ + vws_client = VWS( + server_access_key=uuid.uuid4().hex, + server_secret_key=uuid.uuid4().hex, + transport=_RequestQuotaReachedTransport(), + ) + + with pytest.raises(expected_exception=RequestQuotaReachedError) as exc: + vws_client.list_targets() + + assert exc.value.response.status_code == HTTPStatus.FORBIDDEN def test_fail(high_quality_image: io.BytesIO) -> None: From 1a86fb4e1faf600f1621a080d2b2b26e384d2752 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Fri, 17 Jul 2026 07:52:39 +0100 Subject: [PATCH 2/2] Fix json.dumps call to use keyword argument for mypy. Co-authored-by: Cursor --- tests/test_vws_exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_vws_exceptions.py b/tests/test_vws_exceptions.py index 8c784e422..3bbfc984e 100644 --- a/tests/test_vws_exceptions.py +++ b/tests/test_vws_exceptions.py @@ -68,7 +68,7 @@ def __call__( "transaction_id": uuid.uuid4().hex, "result_code": "RequestQuotaReached", } - text = json.dumps(body) + text = json.dumps(obj=body) return Response( text=text, url=url,