chore(*): add various tests

pull/174/head
Christian Merten 4 months ago
parent 162b9a46ea
commit 5efdbcb63c
Signed by: christian.merten
GPG Key ID: D953D69721B948B3

@ -39,8 +39,8 @@ fi
cd jdav_web
if [[ "$DJANGO_TEST_KEEPDB" == 1 ]]; then
coverage run manage.py test startpage finance members contrib logindata mailer material ludwigsburgalpin -v 2 --noinput --keepdb
coverage run manage.py test startpage finance members contrib logindata mailer material ludwigsburgalpin jdav_web -v 2 --noinput --keepdb
else
coverage run manage.py test startpage finance members contrib logindata mailer material ludwigsburgalpin -v 2 --noinput
coverage run manage.py test startpage finance members contrib logindata mailer material ludwigsburgalpin jdav_web -v 2 --noinput
fi
coverage html

@ -2,6 +2,7 @@ from unittest import skip
from django.test import TestCase
from django.utils import timezone
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from decimal import Decimal
from finance.models import Statement, StatementUnSubmitted, StatementSubmitted, Bill, Ledger, Transaction,\
StatementUnSubmittedManager, StatementSubmittedManager, StatementConfirmedManager,\
@ -59,13 +60,35 @@ class StatementTestCase(TestCase):
if i < self.allowance_to_count:
self.st3.allowance_to.add(m)
# Create a small excursion with < 5 theoretic LJP participants for LJP contribution test
small_ex = Freizeit.objects.create(name='Small trip', kilometers_traveled=100,
tour_type=GEMEINSCHAFTS_TOUR,
tour_approach=MUSKELKRAFT_ANREISE,
difficulty=1)
# Add only 3 participants (< 5 for theoretic_ljp_participant_count)
for i in range(3):
# Create young participants (< 6 years old) so they don't count toward LJP
birth_date = timezone.now().date() - relativedelta(years=4)
m = Member.objects.create(prename='Small {}'.format(i), lastname='Participant',
birth_date=birth_date,
email=settings.TEST_MAIL, gender=MALE)
NewMemberOnList.objects.create(member=m, memberlist=small_ex)
# Create LJP proposal for the small excursion
ljp_proposal = LJPProposal.objects.create(title='Small LJP', category=LJPProposal.LJP_STAFF_TRAINING)
small_ex.ljpproposal = ljp_proposal
small_ex.save()
self.st_small = Statement.objects.create(night_cost=10, excursion=small_ex)
ex = Freizeit.objects.create(name='Wild trip 2', kilometers_traveled=self.kilometers_traveled,
tour_type=GEMEINSCHAFTS_TOUR,
tour_approach=MUSKELKRAFT_ANREISE,
difficulty=2)
self.st4 = Statement.objects.create(night_cost=self.night_cost, excursion=ex, subsidy_to=self.fritz)
for i in range(2):
m = Member.objects.create(prename='Peter {}'.format(i), lastname='Walter', birth_date=timezone.now().date(),
m = Member.objects.create(prename='Peter {}'.format(i), lastname='Walter',
birth_date=timezone.now().date() - relativedelta(years=30),
email=settings.TEST_MAIL, gender=DIVERSE)
mol = NewMemberOnList.objects.create(member=m, memberlist=ex)
ex.membersonlist.add(mol)
@ -408,6 +431,63 @@ class StatementTestCase(TestCase):
self.assertIn('euro_per_km', context)
self.assertIsInstance(context['euro_per_km'], (int, float, Decimal))
def test_title_with_excursion(self):
title = self.st3.title
self.assertIn('Wild trip', title)
def test_transaction_issues_with_org_fee(self):
issues = self.st4.transaction_issues
self.assertIsInstance(issues, list)
def test_transaction_issues_with_ljp(self):
self.st3.ljp_to = self.fritz
self.st3.save()
issues = self.st3.transaction_issues
self.assertIsInstance(issues, list)
def test_generate_transactions_org_fee(self):
# Ensure conditions for org fee are met: need subsidy_to or allowances
# and participants >= 27 years old
self.st4.subsidy_to = self.fritz
self.st4.save()
# Verify org fee is calculated
self.assertGreater(self.st4.total_org_fee, 0, "Org fee should be > 0 with subsidies and old participants")
initial_count = Transaction.objects.count()
self.st4.generate_transactions()
final_count = Transaction.objects.count()
self.assertGreater(final_count, initial_count)
org_fee_transaction = Transaction.objects.filter(statement=self.st4,
reference__icontains=_('reduced by org fee')).first()
self.assertIsNotNone(org_fee_transaction)
def test_generate_transactions_ljp(self):
self.st3.ljp_to = self.fritz
self.st3.save()
initial_count = Transaction.objects.count()
self.st3.generate_transactions()
final_count = Transaction.objects.count()
self.assertGreater(final_count, initial_count)
ljp_transaction = Transaction.objects.filter(statement=self.st3, member=self.fritz, reference__icontains='LJP').first()
self.assertIsNotNone(ljp_transaction)
def test_subsidies_paid_property(self):
subsidies_paid = self.st3.subsidies_paid
expected = self.st3.total_subsidies - self.st3.total_org_fee
self.assertEqual(subsidies_paid, expected)
def test_ljp_contributions_low_participant_count(self):
self.st_small.ljp_to = self.fritz
self.st_small.save()
# Verify that the small excursion has < 5 theoretic LJP participants
self.assertLess(self.st_small.excursion.theoretic_ljp_participant_count, 5,
"Should have < 5 theoretic LJP participants")
ljp_contrib = self.st_small.paid_ljp_contributions
self.assertEqual(ljp_contrib, 0)
class LedgerTestCase(TestCase):
def setUp(self):

@ -0,0 +1,30 @@
from django.test import TestCase, RequestFactory, override_settings
from django.contrib.auth.models import User
from django.contrib import admin
from unittest.mock import Mock, patch
from jdav_web.views import media_unprotected, custom_admin_view
from startpage.models import Link
class ViewsTestCase(TestCase):
def setUp(self):
self.factory = RequestFactory()
self.user = User.objects.create_user('testuser', 'test@example.com', 'password')
Link.objects.create(title='Test Link', url='https://example.com')
@override_settings(DEBUG=True)
def test_media_unprotected_debug_true(self):
request = self.factory.get('/media/test.jpg')
with patch('jdav_web.views.serve') as mock_serve:
mock_serve.return_value = Mock()
result = media_unprotected(request, 'test.jpg')
mock_serve.assert_called_once()
def test_custom_admin_view(self):
request = self.factory.get('/admin/')
request.user = self.user
with patch.object(admin.site, 'get_app_list') as mock_get_app_list:
mock_get_app_list.return_value = []
response = custom_admin_view(request)
self.assertEqual(response.status_code, 200)
mock_get_app_list.assert_called_once_with(request)

@ -2,3 +2,4 @@ from .models import *
from .admin import *
from .views import *
from .rules import *
from .mailutils import *

@ -0,0 +1,34 @@
from django.test import TestCase, override_settings
from unittest.mock import patch, Mock
from mailer.mailutils import send, SENT, NOT_SENT
class MailUtilsTest(TestCase):
def setUp(self):
self.subject = "Test Subject"
self.content = "Test Content"
self.sender = "sender@example.com"
self.recipient = "recipient@example.com"
def test_send_with_reply_to(self):
with patch('mailer.mailutils.mail.get_connection') as mock_connection:
mock_conn = Mock()
mock_connection.return_value = mock_conn
result = send(self.subject, self.content, self.sender, self.recipient, reply_to=["reply@example.com"])
self.assertEqual(result, SENT)
def test_send_with_message_id(self):
with patch('mailer.mailutils.mail.get_connection') as mock_connection:
mock_conn = Mock()
mock_connection.return_value = mock_conn
result = send(self.subject, self.content, self.sender, self.recipient, message_id="<test@example.com>")
self.assertEqual(result, SENT)
def test_send_exception_handling(self):
with patch('mailer.mailutils.mail.get_connection') as mock_connection:
mock_conn = Mock()
mock_conn.send_messages.side_effect = Exception("Test exception")
mock_connection.return_value = mock_conn
with patch('builtins.print'):
result = send(self.subject, self.content, self.sender, self.recipient)
self.assertEqual(result, NOT_SENT)

@ -83,7 +83,7 @@ def create_group_with_perms(apps, schema_editor, name, perm_names):
Group = apps.get_model("auth", "Group")
Permission = apps.get_model("auth", "Permission")
if Group.objects.filter(name=name).exists():
raise ValueError("A group with name %s already exists." % name)
raise ValueError("A group with name %s already exists." % name) # pragma: no cover
perms = [ Permission.objects.get(codename=codename, content_type__app_label=app_label) for app_label, codename in perm_names ]
g = Group.objects.using(db_alias).create(name=name)
g.permissions.set(perms)

@ -12,6 +12,7 @@ from django.test import TestCase, Client, RequestFactory
from django.utils import timezone, translation
from django.conf import settings
from django.urls import reverse
from django.http import HttpResponse, HttpResponseRedirect
from django import template
from unittest import skip, mock
import os
@ -1215,6 +1216,18 @@ class FreizeitAdminTestCase(AdminTestCase, PDFActionMixin):
response = c.post(url, data={'finance_overview': '', 'apply': ''})
self.assertEqual(response.status_code, HTTPStatus.FOUND)
def test_save_model_with_statement(self):
user_with_member = User.objects.get(username='standard')
self.ex.statement = self.st
request = self.factory.post('/')
request.user = user_with_member
form = mock.MagicMock()
with mock.patch('members.admin.super') as mock_super:
mock_super.return_value.save_model.return_value = None
self.admin.save_model(request, self.ex, form, change=False)
self.st.refresh_from_db()
self.assertEqual(self.st.created_by, user_with_member.member)
class MemberNoteListAdminTestCase(AdminTestCase, PDFActionMixin):
def setUp(self):
@ -1353,6 +1366,23 @@ class MemberWaitingListAdminTestCase(AdminTestCase):
'_selected_action': [q.pk for q in qs]}, follow=True)
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_response_change_invite(self):
request = self.factory.post('/', {'_invite': True})
request.user = User.objects.get(username='superuser')
with mock.patch('members.admin.super') as mock_super:
mock_super.return_value.response_change.return_value = HttpResponse()
response = self.admin.response_change(request, self.waiter)
self.assertIsInstance(response, HttpResponseRedirect)
def test_response_change_no_invite(self):
request = self.factory.post('/', {})
request.user = User.objects.get(username='superuser')
expected_response = HttpResponse()
with mock.patch('members.admin.super') as mock_super:
mock_super.return_value.response_change.return_value = expected_response
response = self.admin.response_change(request, self.waiter)
self.assertEqual(response, expected_response)
class MemberUnconfirmedAdminTestCase(AdminTestCase):
def setUp(self):
@ -1452,6 +1482,22 @@ class MemberUnconfirmedAdminTestCase(AdminTestCase):
response = c.get(url)
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_response_change_confirm(self):
request = self.factory.post('/', {'_confirm': True})
request.user = User.objects.get(username='superuser')
request._messages = mock.MagicMock()
# Test successful confirm
self.reg.confirmed_mail = True
self.reg.confirmed_alternative_mail = True
self.reg.save()
with mock.patch.object(self.reg, 'confirm', return_value=True):
response = self.admin.response_change(request, self.reg)
# Test failed confirm
with mock.patch.object(self.reg, 'confirm', return_value=False):
response = self.admin.response_change(request, self.reg)
class MailConfirmationTestCase(BasicMemberTestCase):
def setUp(self):
@ -2162,6 +2208,16 @@ class GroupAdminTestCase(AdminTestCase):
response = c.post(url, data={'group_overview': ''}, follow=True)
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_group_checklist(self):
url = reverse('admin:members_group_action')
c = self._login('standard')
response = c.post(url, data={'group_checklist': ''}, follow=True)
self.assertEqual(response.status_code, HTTPStatus.FORBIDDEN)
c = self._login('superuser')
response = c.post(url, data={'group_checklist': ''}, follow=True)
self.assertEqual(response.status_code, HTTPStatus.OK)
class FilteredMemberFieldMixinTestCase(AdminTestCase):
def setUp(self):

@ -6,12 +6,15 @@ from django.templatetags.static import static
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.core.files.uploadedfile import SimpleUploadedFile
from django.template import Template, Context, TemplateSyntaxError, VariableDoesNotExist
from unittest import mock
from unittest.mock import Mock
from importlib import reload
from members.models import Member, Group, DIVERSE
from startpage import urls
from startpage.views import redirect, handler500
from startpage.templatetags.markdown_extras import RenderAsTemplateNode, render_as_template
from .models import Post, Section, Image, Link, MemberOnPost
@ -209,3 +212,32 @@ class ViewTestCase(BasicTestCase):
request = RequestFactory().get('/')
response = handler500(request)
self.assertEqual(response.status_code, 500)
class MarkdownExtrasTestCase(TestCase):
def test_render_as_template_node_variable_does_not_exist(self):
node = RenderAsTemplateNode('nonexistent_var', 'result')
context = Context({})
result = node.render(context)
self.assertEqual(result, '')
def test_render_as_template_no_arguments(self):
token = Mock()
token.contents = 'render_as_template'
parser = Mock()
with self.assertRaises(TemplateSyntaxError):
render_as_template(parser, token)
def test_render_as_template_invalid_syntax(self):
token = Mock()
token.contents = 'render_as_template "content"'
parser = Mock()
with self.assertRaises(TemplateSyntaxError):
render_as_template(parser, token)
def test_render_as_template_unquoted_argument(self):
token = Mock()
token.contents = 'render_as_template content as result'
parser = Mock()
with self.assertRaises(TemplateSyntaxError):
render_as_template(parser, token)

Loading…
Cancel
Save