Complete dashboard loose ends and reconcile blocked pilot work
All checks were successful
Application acceptance / application-tests (push) Successful in 1m26s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 34s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e394-2a69-7df0-8980-22a0ebe55216
This commit is contained in:
tegwick 2026-09-27 18:34:48 +02:00
parent 387b7e9782
commit 35df9bb772
13 changed files with 325 additions and 55 deletions

View file

@ -98,3 +98,93 @@ def test_status_htmx_returns_partial(admitted_client):
response = admitted_client.post(url, {"status": "3"}, HTTP_HX_REQUEST="true")
assert response.status_code == 200
assert b"status-widget" in response.content
@pytest.mark.django_db
def test_dashboard_expiry_boundary(admitted_client):
from datetime import date, timedelta
from vergabe_teilnahme.apps.bibliothek.models import Nachweis
for title, days in [('Expired', -1), ('Boundary', 60), ('Later', 61)]:
Nachweis.objects.create(titel=title, gueltig_bis=date.today() + timedelta(days=days))
Nachweis.objects.create(titel='Undated')
response = admitted_client.get(reverse('ausschreibungen:dashboard'))
assert response.status_code == 200
assert [n.titel for n in response.context['ablaufende_nachweise']] == ['Expired', 'Boundary']
assert 'Boundary' in response.content.decode()
@pytest.mark.django_db
def test_list_search_combines_filters_and_htmx(admitted_client):
matching = AusschreibungFactory(titel='Network upgrade', ausschreiber='City', status=4)
AusschreibungFactory(titel='Other', ausschreiber='City', status=3)
AusschreibungFactory(titel='Archived', ausschreiber='City', status=4, archiviert=True)
for query in ['Network', 'City']:
response = admitted_client.get(reverse('ausschreibungen:liste'),
{'q': query, 'status': '4'}, HTTP_HX_REQUEST='true')
assert list(response.context['ausschreibungen']) == [matching]
assert 'ausschreibungen/liste_partial.html' in [t.name for t in response.templates]
@pytest.mark.django_db
def test_historical_result_validation_and_save(admitted_client):
url = reverse('ausschreibungen:neu')
response = admitted_client.get(url, {'historisch': '1'})
assert 'name="ergebnis"' in response.content.decode()
data = {'titel': 'Historical award', 'ausschreiber': 'City',
'historisch_erfassen': '1', 'teilnahmeentscheidung': 'teilnahme',
'ergebnis': 'invalid'}
response = admitted_client.post(url, data)
assert response.status_code == 200
assert response.context['form'].errors['ergebnis']
assert not Ausschreibung.objects.filter(titel=data['titel']).exists()
data['ergebnis'] = 'gewonnen'
response = admitted_client.post(url, data)
assert response.status_code == 302
tender = Ausschreibung.objects.get(titel=data['titel'])
assert tender.nachbetrachtung.ergebnis == 'gewonnen'
assert tender.status == 10
assert tender.teilnahmeentscheidung == 'teilnahme'
@pytest.mark.django_db
def test_global_search_tasks_partners_and_issuer(admitted_client):
from vergabe_teilnahme.apps.aufgaben.models import Aufgabe
from vergabe_teilnahme.apps.partner.models import Subunternehmer
tender = AusschreibungFactory(titel='Tender', ausschreiber='UniqueIssuer')
task = Aufgabe.objects.create(titel='UniqueTask', ausschreibung=tender)
partner = Subunternehmer.objects.create(name='UniquePartner')
cases = [
('UniqueIssuer', reverse('ausschreibungen:detail', kwargs={'pk': tender.pk})),
('UniqueTask', reverse('ausschreibungen:aufgaben:detail',
kwargs={'ausschreibung_id': tender.pk, 'pk': task.pk})),
('UniquePartner', reverse('partner:su_detail', kwargs={'pk': partner.pk})),
]
for query, target in cases:
response = admitted_client.get('/suche/', {'q': query})
assert response.status_code == 200
assert f'href="{target}"' in response.content.decode()
@pytest.mark.django_db
def test_inline_status_with_rendered_csrf_header(mitarbeiter):
import json
import re
from django.test import Client
client = Client(enforce_csrf_checks=True)
client.force_login(mitarbeiter)
tender = AusschreibungFactory(status=1)
response = client.get(reverse('ausschreibungen:detail', kwargs={'pk': tender.pk}))
headers = json.loads(re.search(r"hx-headers='([^']+)'", response.content.decode())[1])
url = reverse('ausschreibungen:status', kwargs={'pk': tender.pk})
assert client.post(url, {'status': '4'}).status_code == 403
response = client.post(url, {'status': '4'}, HTTP_HX_REQUEST='true',
HTTP_X_CSRFTOKEN=headers['X-CSRFToken'])
assert response.status_code == 200
tender.refresh_from_db()
assert tender.status == 4