104 lines
3.1 KiB
Python
104 lines
3.1 KiB
Python
from typing import Callable
|
|
|
|
import pytest
|
|
from django.test import Client
|
|
from django.urls import reverse
|
|
from hypothesis import given
|
|
from hypothesis import strategies as st
|
|
from structlog.testing import capture_logs
|
|
|
|
from .models import Teil
|
|
|
|
names = st.text(alphabet=st.characters(exclude_categories=["C"]), min_size=1)
|
|
|
|
|
|
@given(data=names)
|
|
def test_submitted_data_ends_up_in_database(data, session: Client):
|
|
with pytest.raises(Teil.DoesNotExist):
|
|
Teil.objects.get(name=data)
|
|
|
|
response = session.post(reverse("collector:enter"), data={"new_name": data})
|
|
assert response.status_code == 302
|
|
assert Teil.objects.get(name=data)
|
|
|
|
|
|
@given(data=names)
|
|
def test_entering_same_name_twice_does_not_change_database_entry(data, session: Client):
|
|
assert not Teil.objects.filter(name=data).exists()
|
|
|
|
response = session.post(reverse("collector:enter"), data={"new_name": data})
|
|
assert response.status_code == 302
|
|
assert Teil.objects.filter(name=data).count() == 1
|
|
|
|
response = session.post(reverse("collector:enter"), data={"new_name": data})
|
|
assert response.status_code == 302
|
|
assert Teil.objects.filter(name=data).count() == 1
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"http_method,expected_status",
|
|
[
|
|
("GET", 405),
|
|
("PATCH", 405),
|
|
("POST", 302),
|
|
("PUT", 405),
|
|
],
|
|
)
|
|
def test_enter_endpoint_accepts_only_post_requests(
|
|
client: Client,
|
|
http_method: str,
|
|
expected_status: int,
|
|
random_name: Callable[[int], str],
|
|
):
|
|
client_method = getattr(client, http_method.lower())
|
|
|
|
response = client_method(
|
|
reverse("collector:enter"), data={"new_name": random_name(8)}
|
|
)
|
|
assert response.status_code == expected_status
|
|
|
|
|
|
def test_enter_endpoints_emits_expected_logs(
|
|
client: Client, random_name: Callable[[int], str]
|
|
):
|
|
"""
|
|
note: capture_logs() yields a list of dicts, not a list of logfmt lines
|
|
that we configured for the app
|
|
"""
|
|
same_name = random_name(10)
|
|
|
|
with capture_logs() as logs:
|
|
response = client.post(reverse("collector:enter"), data={"new_name": same_name})
|
|
assert response.status_code == 302
|
|
assert any(
|
|
(
|
|
le["event"].lower() == "New Teil entered".lower()
|
|
and le["log_level"].lower() == "info"
|
|
and "teil_id" in le
|
|
for le in logs
|
|
)
|
|
)
|
|
|
|
with capture_logs() as logs:
|
|
response = client.post(reverse("collector:enter"), data={"new_name": same_name})
|
|
assert response.status_code == 302
|
|
assert any(
|
|
(
|
|
le["event"].lower() == "Teil already existed".lower()
|
|
and le["log_level"].lower() == "warning"
|
|
and "teil_id" not in le
|
|
for le in logs
|
|
)
|
|
)
|
|
|
|
|
|
def test_model_manager_lists_newest_teil_first():
|
|
t1 = Teil.objects.create(name="Teil 1")
|
|
t2 = Teil.objects.create(name="Teil 2")
|
|
t3 = Teil.objects.create(name="Teil 3")
|
|
|
|
assert t1.modified < t2.modified < t3.modified
|
|
|
|
t = Teil.objects.all()
|
|
|
|
assert t[2].modified < t[1].modified < t[0].modified
|