51 lines
1.8 KiB
Python
51 lines
1.8 KiB
Python
|
|
# retoor <retoor@molodetz.nl>
|
||
|
|
|
||
|
|
import ast
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
PACKAGE = Path(__file__).resolve().parents[2] / "devplacepy"
|
||
|
|
|
||
|
|
|
||
|
|
def _json_error_calls():
|
||
|
|
for path in sorted(PACKAGE.rglob("*.py")):
|
||
|
|
tree = ast.parse(path.read_text(), filename=str(path))
|
||
|
|
for node in ast.walk(tree):
|
||
|
|
if not isinstance(node, ast.Call):
|
||
|
|
continue
|
||
|
|
name = node.func.attr if isinstance(node.func, ast.Attribute) else getattr(node.func, "id", "")
|
||
|
|
if name == "json_error" and node.args:
|
||
|
|
yield path.relative_to(PACKAGE.parent), node
|
||
|
|
|
||
|
|
|
||
|
|
def test_json_error_never_receives_a_message_as_its_status():
|
||
|
|
offenders = [
|
||
|
|
f"{path}:{node.lineno}"
|
||
|
|
for path, node in _json_error_calls()
|
||
|
|
if isinstance(node.args[0], ast.Constant) and isinstance(node.args[0].value, str)
|
||
|
|
]
|
||
|
|
assert not offenders, (
|
||
|
|
"json_error(status_code, message) - a string in the status position builds a "
|
||
|
|
f"JSONResponse with a non-int status and raises TypeError at request time: {offenders}"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def test_json_error_never_receives_a_status_as_its_message():
|
||
|
|
offenders = [
|
||
|
|
f"{path}:{node.lineno}"
|
||
|
|
for path, node in _json_error_calls()
|
||
|
|
if len(node.args) > 1
|
||
|
|
and isinstance(node.args[1], ast.Constant)
|
||
|
|
and isinstance(node.args[1].value, int)
|
||
|
|
]
|
||
|
|
assert not offenders, (
|
||
|
|
"json_error(status_code, message) - an int in the message position means the "
|
||
|
|
f"arguments were swapped: {offenders}"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def test_every_json_error_status_is_a_real_http_error_code():
|
||
|
|
for path, node in _json_error_calls():
|
||
|
|
first = node.args[0]
|
||
|
|
if isinstance(first, ast.Constant) and isinstance(first.value, int):
|
||
|
|
assert 400 <= first.value <= 599, f"{path}:{node.lineno} status {first.value}"
|