Skip to content

Commit

Permalink
Rework '/versions' validator to force check on 'text/csv'
Browse files Browse the repository at this point in the history
  • Loading branch information
ml-evs committed Jan 11, 2021
1 parent 25cf7bf commit ed09680
Showing 1 changed file with 35 additions and 20 deletions.
55 changes: 35 additions & 20 deletions optimade/validator/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -947,13 +947,17 @@ def _test_versions_endpoint(self):
@test_case
def _test_versions_endpoint_content(
self, response: requests.Response
) -> Tuple[Optional[requests.Response], str]:
) -> Tuple[requests.Response, str]:
"""Checks that the response from the versions endpoint complies
with the specification.
with the specification and that its 'Content-Type' header complies with
[RFC 4180](https://tools.ietf.org/html/rfc4180.html).
Parameters:
response: The HTTP response from the versions endpoint.
Raises:
ResponseError: If any content checks fail.
Returns:
The successful HTTP response or `None`, and a summary string.
Expand All @@ -977,37 +981,48 @@ def _test_versions_endpoint_content(
f"Version numbers reported by `/{CONF.versions_endpoint}` must be integers specifying the major version, not {text_content}."
)

self._test_versions_headers(response, optional=True)
content_type = response.headers.get("content-type")
if not content_type:
raise ResponseError(
"Missing 'Content-Type' in response header from `/versions`."
)

content_type = [_.replace(" ", "") for _ in content_type.split(";")]

self._test_versions_headers(content_type, "text/csv")
self._test_versions_headers(content_type, "header=present", optional=True)

return response, "`/versions` endpoint responded correctly."

@test_case
def _test_versions_headers(
self, response: requests.Response, optional: bool = True
):
"""Tests that the versions endpoint responds with the correct optional
headers, namely that Content-Type contains both `text/csv` and
`headers=present` as per [RFC 4180](https://tools.ietf.org/html/rfc4180.html).
self, content_type: Dict[str, Any], expected_parameter: str
) -> Tuple[Dict[str, Any], str]:
"""Tests that the `Content-Type` field of the `/versions` header contains
the passed parameter.
Arguments:
content_type: The 'Content-Type' field from the response of the `/versions` endpoint.
expected_paramter: A substring that is expected in the Content-Type of the response.
"""
content_type = response.headers.get("content-type")
if content_type is not None:
content_type = [_.replace(" ", "") for _ in content_type.split(";")]
Raises:
ResponseError: If the expected 'Content-Type' parameter is missing.
expected_headers = ("text/csv", "header=present")
Returns:
The HTTP response headers and a summary string.
if not content_type:
raise ResponseError("Missing 'Content-Type' header from `/versions`.")
"""

if not all(header in content_type for header in expected_headers):
if expected_parameter not in content_type:
raise ResponseError(
f"Incorrect 'Content-Type' header {';'.join(content_type)!r} "
f"instead of the minimum expected {';'.join(expected_headers)!r}"
f"Incorrect 'Content-Type' header {';'.join(content_type)!r}.\n"
f"Missing expected parameter {expected_parameter!r}"
)

return response, "`/versions` response had correct headers."
return (
content_type,
"`/versions` response had expected Content-Type parameter {expected_header}.",
)

def _test_as_type(self) -> None:
"""Tests that the base URL of the validator (i.e. with no
Expand Down

0 comments on commit ed09680

Please sign in to comment.