added basic tests for extern view

This commit is contained in:
Oliver Zander 2025-08-18 16:42:09 +02:00 committed by Tobias Herre
parent 233151968b
commit e5cea49673
4 changed files with 157 additions and 0 deletions

View File

@ -8,6 +8,9 @@ from django.http import HttpResponse
from input.forms import LibraryForm
from input.models import HonoraryCertificate, Project, Account, Literature
from .views import ViewTestCase
class TestWithoutLogin(TestCase):
def setUp(self):

40
input/tests/views.py Normal file
View File

@ -0,0 +1,40 @@
from django.test import TestCase
from input.utils.testing import request
class ViewTestCase(TestCase):
def test_index(self):
request(self, 'index')
def test_extern(self):
request(self, 'extern')
def test_extern_travel(self):
data = {
'extern_view-current_step': 0,
'0-realname': 'Test',
'0-email': 'test@example.com',
'0-choice': 'TRAV',
'0-check': True,
}
response = request(self, 'extern', data=data)
self.assertContains(response, 'Transportmittel')
data = {
'extern_view-current_step': 1,
'project_name': 'Test',
'transport': 'BAHN',
'travelcost': 10,
'checkin': '2025-01-01',
'checkout': '2025-01-02',
'hotel': 'TRUE',
'notes': '',
}
response = request(self, 'extern', data=data)
self.assertContains(response, 'Deine Anfrage wurde gesendet.')

0
input/utils/__init__.py Normal file
View File

114
input/utils/testing.py Normal file
View File

@ -0,0 +1,114 @@
from typing import Any, Iterable, Mapping, Union, Tuple, Protocol
from django.http import HttpRequest, HttpResponse
from django.http.response import HttpResponseRedirectBase, StreamingHttpResponse
from django.shortcuts import resolve_url
from django.template import Context
from django.template.response import TemplateResponse
from django.test import Client, SimpleTestCase
from django.urls import reverse, ResolverMatch
from django.utils.http import urlencode
FormData = dict
JSONDict = dict
JSONList = list
RequestData = Union[FormData, JSONDict, JSONList]
QueryParams = Union[Mapping[str, Any], Iterable[Tuple[str, Any]]]
class TestClientResponse(Protocol):
client: Client
request: HttpRequest
templates: list
context: Context
resolver_match: ResolverMatch
def json(self) -> Union[JSONList, JSONDict]: ...
Response = Union[
HttpResponse,
HttpResponseRedirectBase,
StreamingHttpResponse,
TemplateResponse,
TestClientResponse,
]
class ObjectWithGetAbsoluteURLMethod(Protocol):
def get_absolute_url(self) -> str: ...
URL = Union[str, ObjectWithGetAbsoluteURLMethod]
URLArgs = Union[tuple, list]
URLKwargs = dict
def get_url(url: URL, args: URLArgs = None, kwargs: URLKwargs = None) -> str:
"""
Helper to reverse the given url name.
"""
if args or kwargs:
return reverse(url, args=args, kwargs=kwargs)
return resolve_url(url)
def get_handler(test_case: SimpleTestCase, method: str = None, data=None):
if data:
method = str.lower(method or 'POST')
else:
method = str.lower(method or 'GET')
return getattr(test_case.client, method)
def request(
test_case: SimpleTestCase,
url: URL,
status_code: int = None,
expected_url: URL = None,
args: URLArgs = None,
kwargs: URLKwargs = None,
headers: dict = None,
msg: str = None,
query_params: QueryParams = None,
method: str = None,
data: RequestData = None,
**options,
) -> Response:
"""
A helper to make a request with the test case's http client.
The given args and kwargs are used to reverse the url
but not the expected url. When expected url needs
args/kwargs pass an absolute url instead.
All additional kwargs are passed as post parameters.
When posting without parameters just pass post=True.
"""
data = data or options or None
handler = get_handler(test_case, method, data)
url = get_url(url, args, kwargs)
if query_params:
url = f'{url}?%s' % urlencode(query_params, doseq=True)
headers = headers or {}
status_code = status_code or 200
response = handler(url, data=data, **headers)
msg = msg or getattr(response, 'content', None)
if expected_url:
test_case.assertRedirects(
response=response,
expected_url=get_url(expected_url),
target_status_code=status_code,
)
else:
test_case.assertEqual(response.status_code, status_code, msg=msg)
return response