Compare commits

...

5 commits

Author SHA1 Message Date
bronsen
ff18fc8994 [dependencies] add comments explaining why we added those dev dependencies
All checks were successful
ci/woodpecker/push/workflow/1 Pipeline was successful
ci/woodpecker/push/workflow/2 Pipeline was successful
2025-03-17 18:27:38 +01:00
bronsen
719d4254b2 [collector] ensure model manager retrieves newest Teil first
closes: #7
2025-03-17 18:16:16 +01:00
bronsen
bcf6dff1b0 [tests,dependencies] capture logs with help from structlog and forget about logot
Closes #3
2025-03-17 17:53:34 +01:00
bronsen
6de8b07d1b [just] validate templates when linting django
The is from package django_extensions
2025-03-17 17:13:49 +01:00
bronsen
1b157f2d34 [just] add new target to recalculate/update and then sync dependencies 2025-03-17 17:12:56 +01:00
8 changed files with 59 additions and 23 deletions

View file

@ -16,6 +16,7 @@ class Teil(models.Model):
verbose_name = "Teil" verbose_name = "Teil"
verbose_name_plural = "Teile" verbose_name_plural = "Teile"
ordering = ["-modified"]
def __str__(self) -> str: def __str__(self) -> str:
modified = self.modified.isoformat(timespec="seconds") modified = self.modified.isoformat(timespec="seconds")

View file

@ -1,9 +1,11 @@
from typing import Callable from typing import Callable
import pytest import pytest
from django.test import Client from django.test import Client
from django.urls import reverse from django.urls import reverse
from hypothesis import given, strategies as st from hypothesis import given
from logot import Logot, logged from hypothesis import strategies as st
from structlog.testing import capture_logs
from .models import Teil from .models import Teil
@ -56,16 +58,47 @@ def test_enter_endpoint_accepts_only_post_requests(
assert response.status_code == expected_status assert response.status_code == expected_status
@pytest.mark.xfail(reason="WIP, kein Plan warum nichts gecaptured zu werden scheint")
def test_enter_endpoints_emits_expected_logs( def test_enter_endpoints_emits_expected_logs(
client: Client, logot: Logot, random_name: Callable[[int], str] 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) same_name = random_name(10)
with capture_logs() as logs:
response = client.post(reverse("collector:enter"), data={"new_name": same_name}) response = client.post(reverse("collector:enter"), data={"new_name": same_name})
assert response.status_code == 302 assert response.status_code == 302
logot.assert_logged(logged.info("New Teil entered")) 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}) response = client.post(reverse("collector:enter"), data={"new_name": same_name})
assert response.status_code == 302 assert response.status_code == 302
logot.assert_logged(logged.warning("Teil already existed")) 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
all_teile = Teil.objects.all()
assert all_teile[2].modified < all_teile[1].modified < all_teile[0].modified

View file

@ -4,6 +4,8 @@ deps:
sync: sync:
pip-sync requirements/dev.txt pip-sync requirements/dev.txt
freshdeps: deps sync
lint: lint-ruff lint-django lint-woodpecker lint: lint-ruff lint-django lint-woodpecker
lint-ruff: lint-ruff:
@ -11,6 +13,7 @@ lint-ruff:
lint-django: lint-django:
python -m django check python -m django check
python -m django validate_templates
lint-woodpecker: lint-woodpecker:
-woodpecker-cli lint .woodpecker/workflow.yaml -woodpecker-cli lint .woodpecker/workflow.yaml
@ -20,3 +23,5 @@ serve:
test *ARGS: test *ARGS:
ENV_PATH=.env.test python -m pytest {{ARGS}} ENV_PATH=.env.test python -m pytest {{ARGS}}
alias fd := freshdeps

View file

@ -23,7 +23,6 @@ addopts = [
"--no-migrations", "--no-migrations",
"--capture=sys", "--capture=sys",
] ]
logot_capturer = "logot.structlog.StructlogCapturer"
[build-system] [build-system]
requires = ["pdm-backend"] requires = ["pdm-backend"]

View file

@ -1,9 +1,9 @@
-r test.in -r test.in
django-debug-toolbar django-debug-toolbar # debugging in the browser
django-stubs django-stubs # type hints for django
ipython ipython # more colorful repl
pip-compile-multi pip-compile-multi # superior dependency management
rich rich # pretty exceptions on dev/console
ruff ruff # linter
uv uv # resolver for pip-compile-multi

View file

@ -1,4 +1,4 @@
# SHA1:48c3af154036b224a6b21f175ea0a949febaf6f5 # SHA1:d8e7f5aef64e2e1e161d339a9c1c53d42cdd0981
# #
# This file is autogenerated by pip-compile-multi # This file is autogenerated by pip-compile-multi
# To update, run: # To update, run:

View file

@ -3,4 +3,3 @@
hypothesis[django] hypothesis[django]
pytest pytest
pytest-django pytest-django
logot[pytest,structlog]

View file

@ -1,4 +1,4 @@
# SHA1:40e4b481355fc16525f8944d39904264b6e382a6 # SHA1:9bf147356ad56dbe073ef0973141bdfb94631c9b
# #
# This file is autogenerated by pip-compile-multi # This file is autogenerated by pip-compile-multi
# To update, run: # To update, run:
@ -7,9 +7,8 @@
# #
-r prod.txt -r prod.txt
attrs==25.3.0 attrs==25.3.0
hypothesis==6.129.2 hypothesis==6.129.3
iniconfig==2.0.0 iniconfig==2.0.0
logot==1.3.0
packaging==24.2 packaging==24.2
pluggy==1.5.0 pluggy==1.5.0
pytest==8.3.5 pytest==8.3.5