From 47728c42ddc36e99fe950f684538abc528f6d32a Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Mon, 15 Jul 2024 19:02:00 +0100 Subject: [PATCH 1/3] Ignore that body can be None in validators --- src/mock_vws/_query_validators/content_length_validators.py | 4 ++-- .../_services_validators/content_length_validators.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mock_vws/_query_validators/content_length_validators.py b/src/mock_vws/_query_validators/content_length_validators.py index 8df092192..5ee68da75 100644 --- a/src/mock_vws/_query_validators/content_length_validators.py +++ b/src/mock_vws/_query_validators/content_length_validators.py @@ -54,7 +54,7 @@ def validate_content_length_header_not_too_large( """ given_content_length = request_headers["Content-Length"] - body_length = len(request_body if request_body else b"") + body_length = len(request_body) given_content_length_value = int(given_content_length) # We skip coverage here as running a test to cover this is very slow. if given_content_length_value > body_length: # pragma: no cover @@ -81,7 +81,7 @@ def validate_content_length_header_not_too_small( """ given_content_length = request_headers["Content-Length"] - body_length = len(request_body if request_body else b"") + body_length = len(request_body) given_content_length_value = int(given_content_length) if given_content_length_value < body_length: diff --git a/src/mock_vws/_services_validators/content_length_validators.py b/src/mock_vws/_services_validators/content_length_validators.py index 733707f15..8b1bc4cab 100644 --- a/src/mock_vws/_services_validators/content_length_validators.py +++ b/src/mock_vws/_services_validators/content_length_validators.py @@ -29,7 +29,7 @@ def validate_content_length_header_is_int( ContentLengthHeaderNotIntError: The content length header is not an integer """ - body_length = len(request_body if request_body else b"") + body_length = len(request_body) given_content_length = request_headers.get("Content-Length", body_length) try: @@ -55,7 +55,7 @@ def validate_content_length_header_not_too_large( ContentLengthHeaderTooLargeError: The given content length header says that the content length is greater than the body length. """ - body_length = len(request_body if request_body else b"") + body_length = len(request_body) given_content_length = request_headers.get("Content-Length", body_length) given_content_length_value = int(given_content_length) # We skip coverage here as running a test to cover this is very slow. @@ -80,7 +80,7 @@ def validate_content_length_header_not_too_small( AuthenticationFailureError: The given content length header says that the content length is smaller than the body length. """ - body_length = len(request_body if request_body else b"") + body_length = len(request_body) given_content_length = request_headers.get("Content-Length", body_length) given_content_length_value = int(given_content_length) From 727f6600c2a2c7842a2c9bcc48406a985c0c0033 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Mon, 15 Jul 2024 19:13:53 +0100 Subject: [PATCH 2/3] Support passing data as strings --- CHANGELOG.rst | 2 + .../mock_web_query_api.py | 18 +++++++- .../mock_web_services_api.py | 46 ++++++++++++------- 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 728a28444..b0cfa3c5a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,8 @@ Changelog Next ---- +- Support passing data as strings. + 2024.07.02.1 ------------ diff --git a/src/mock_vws/_requests_mock_server/mock_web_query_api.py b/src/mock_vws/_requests_mock_server/mock_web_query_api.py index 8ad55cbed..02de58dc2 100644 --- a/src/mock_vws/_requests_mock_server/mock_web_query_api.py +++ b/src/mock_vws/_requests_mock_server/mock_web_query_api.py @@ -69,6 +69,20 @@ def decorator(method: Callable[..., str]) -> Callable[..., str]: return decorator +def _body_bytes(request: Request) -> bytes: + """ + Return the body of a request as bytes. + """ + if request.body is None: + return b"" + + if isinstance(request.body, str): + return request.body.encode(encoding="utf-8") + + assert isinstance(request.body, bytes) + return request.body + + class MockVuforiaWebQueryAPI: """ A fake implementation of the Vuforia Web Query API. @@ -103,7 +117,7 @@ def query(self, request: Request, context: Context) -> str: run_query_validators( request_path=request.path, request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, databases=self._target_manager.databases, ) @@ -114,7 +128,7 @@ def query(self, request: Request, context: Context) -> str: response_text = get_query_match_response_text( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, diff --git a/src/mock_vws/_requests_mock_server/mock_web_services_api.py b/src/mock_vws/_requests_mock_server/mock_web_services_api.py index 54a36ec4c..9b6be6885 100644 --- a/src/mock_vws/_requests_mock_server/mock_web_services_api.py +++ b/src/mock_vws/_requests_mock_server/mock_web_services_api.py @@ -81,6 +81,20 @@ def decorator(method: Callable[..., str]) -> Callable[..., str]: return decorator +def _body_bytes(request: Request) -> bytes: + """ + Return the body of a request as bytes. + """ + if request.body is None: + return b"" + + if isinstance(request.body, str): + return request.body.encode(encoding="utf-8") + + assert isinstance(request.body, bytes) + return request.body + + class MockVuforiaWebServicesAPI: """ A fake implementation of the Vuforia Web Services API. @@ -129,7 +143,7 @@ def add_target(self, request: Request, context: Context) -> str: try: run_services_validators( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -141,7 +155,7 @@ def add_target(self, request: Request, context: Context) -> str: database = get_database_matching_server_keys( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -206,7 +220,7 @@ def delete_target(self, request: Request, context: Context) -> str: try: run_services_validators( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -219,7 +233,7 @@ def delete_target(self, request: Request, context: Context) -> str: body: dict[str, str] = {} database = get_database_matching_server_keys( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -273,7 +287,7 @@ def database_summary(self, request: Request, context: Context) -> str: try: run_services_validators( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -287,7 +301,7 @@ def database_summary(self, request: Request, context: Context) -> str: database = get_database_matching_server_keys( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -339,7 +353,7 @@ def target_list(self, request: Request, context: Context) -> str: try: run_services_validators( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -351,7 +365,7 @@ def target_list(self, request: Request, context: Context) -> str: database = get_database_matching_server_keys( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -399,7 +413,7 @@ def get_target(self, request: Request, context: Context) -> str: try: run_services_validators( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -411,7 +425,7 @@ def get_target(self, request: Request, context: Context) -> str: database = get_database_matching_server_keys( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -467,7 +481,7 @@ def get_duplicates(self, request: Request, context: Context) -> str: try: run_services_validators( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -479,7 +493,7 @@ def get_duplicates(self, request: Request, context: Context) -> str: database = get_database_matching_server_keys( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -541,7 +555,7 @@ def update_target(self, request: Request, context: Context) -> str: try: run_services_validators( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -553,7 +567,7 @@ def update_target(self, request: Request, context: Context) -> str: database = get_database_matching_server_keys( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -650,7 +664,7 @@ def target_summary(self, request: Request, context: Context) -> str: try: run_services_validators( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, @@ -662,7 +676,7 @@ def target_summary(self, request: Request, context: Context) -> str: database = get_database_matching_server_keys( request_headers=request.headers, - request_body=request.body, + request_body=_body_bytes(request=request), request_method=request.method, request_path=request.path, databases=self._target_manager.databases, From 76ba939807843077a0bd8dbc4fb2fe9b65655ce6 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Mon, 15 Jul 2024 19:29:03 +0100 Subject: [PATCH 3/3] Expand coverage for _body_bytes methods --- tests/mock_vws/fixtures/prepared_requests.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/mock_vws/fixtures/prepared_requests.py b/tests/mock_vws/fixtures/prepared_requests.py index 4261fe54a..ad2e61f68 100644 --- a/tests/mock_vws/fixtures/prepared_requests.py +++ b/tests/mock_vws/fixtures/prepared_requests.py @@ -113,7 +113,9 @@ def delete_target( date = rfc_1123_date() request_path = f"/targets/{target_id}" method = HTTPMethod.DELETE - content = b"" + # This could be b"" or None, but we want to exercise handling + # all three of those types. + content = "" access_key = vuforia_database.server_access_key secret_key = vuforia_database.server_secret_key @@ -158,7 +160,9 @@ def database_summary(vuforia_database: VuforiaDatabase) -> Endpoint: request_path = "/summary" method = HTTPMethod.GET - content = b"" + # This could be b"" or "", but we want to exercise handling + # all three of those types. + content = None access_key = vuforia_database.server_access_key secret_key = vuforia_database.server_secret_key