#19 Tests
* adds workflow tests or deductions in InterventionWorkflowTestCase * fixes bugs detected by testing
This commit is contained in:
parent
08d023092f
commit
bcee58700a
@ -32,7 +32,7 @@ urlpatterns = [
|
||||
path('document/<doc_id>/remove/', remove_document_view, name='acc-remove-doc'),
|
||||
|
||||
# Eco-account deductions
|
||||
path('<id>/remove/<deduction_id>', deduction_remove_view, name='deduction-remove'),
|
||||
path('<id>/remove/<deduction_id>', deduction_remove_view, name='acc-remove-deduction'),
|
||||
path('<id>/deduct/new', new_deduction_view, name='acc-new-deduction'),
|
||||
|
||||
]
|
@ -60,7 +60,7 @@
|
||||
<td class="align-middle">{{ deduction.created.timestamp|default_if_none:""|naturalday}}</td>
|
||||
<td>
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'compensation:deduction-remove' deduction.account.id deduction.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove Deduction' %}">
|
||||
<button data-form-url="{% url 'compensation:acc-remove-deduction' deduction.account.id deduction.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove Deduction' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
@ -55,7 +55,7 @@
|
||||
<td class="align-middle">{{ deduction.created.timestamp|default_if_none:""|naturalday}}</td>
|
||||
<td>
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'compensation:deduction-remove' deduction.account.id deduction.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove Deduction' %}">
|
||||
<button data-form-url="{% url 'compensation:acc-remove-deduction' deduction.account.id deduction.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove Deduction' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
@ -11,10 +11,11 @@ from django.contrib.auth.models import Group
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.urls import reverse
|
||||
|
||||
from compensation.models import Payment
|
||||
from compensation.models import Payment, EcoAccountDeduction
|
||||
from intervention.models import Intervention
|
||||
from konova.settings import DEFAULT_GROUP
|
||||
from konova.tests.test_views import BaseWorkflowTestCase
|
||||
from user.models import UserActionLogEntry, UserAction
|
||||
|
||||
|
||||
class InterventionWorkflowTestCase(BaseWorkflowTestCase):
|
||||
@ -31,7 +32,7 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
|
||||
default_group = Group.objects.get(name=DEFAULT_GROUP)
|
||||
cls.superuser.groups.set([default_group])
|
||||
|
||||
def test_new_normal_case(self):
|
||||
def test_new(self):
|
||||
"""
|
||||
Checks a 'normal' case of creating a new intervention.
|
||||
We expect the user to be redirected as expected right away to the detail page of the new intervention.
|
||||
@ -93,9 +94,6 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
|
||||
## BUT: Payments are added on the intervention detail page. Therefore it's part of a regular intervention workflow.
|
||||
new_payment_url = reverse("compensation:pay-new", args=(self.intervention.id,))
|
||||
|
||||
# Create default detail page of intervention
|
||||
detail_url = reverse("intervention:detail", args=(self.intervention.id,))
|
||||
|
||||
# Make sure there are no payments on the intervention, yet
|
||||
self.assertEqual(0, self.intervention.payments.count())
|
||||
|
||||
@ -145,22 +143,16 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
|
||||
)
|
||||
|
||||
# Expect the payment to be gone from the db and therefore from the intervention as well
|
||||
try:
|
||||
payment.refresh_from_db()
|
||||
# Well, we should not reach this next line of code, since the payment should be gone, therefore not
|
||||
# refreshable -> fail!
|
||||
self.fail()
|
||||
except ObjectDoesNotExist:
|
||||
# If we get in here, the test was fine
|
||||
pass
|
||||
self.assert_object_is_deleted(payment)
|
||||
|
||||
# Now make sure the intervention has no payments anymore
|
||||
self.assertEqual(0, self.intervention.payments.count())
|
||||
|
||||
def test_changing_payment_test_case(self):
|
||||
def test_payments(self):
|
||||
"""
|
||||
Checks a 'normal' case of adding a payment.
|
||||
We expect a new payment to be addable to an existing intervention
|
||||
We expect a payment to be deletable to an existing intervention
|
||||
We expect a payment to be deletable from an existing intervention
|
||||
|
||||
Returns:
|
||||
|
||||
@ -170,3 +162,171 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
|
||||
|
||||
# Now remove the payment again
|
||||
self.subtest_delete_payment(payment)
|
||||
|
||||
def subtest_add_deduction_fail_positive(self, new_url: str, post_data: dict, test_surface: float):
|
||||
""" Holds tests for postivie fails of new deduction creation
|
||||
|
||||
Reasons for failing are:
|
||||
* EcoAccount does not provide enough 'deductable_surface'
|
||||
* EcoAccount is not recorded (not "approved"), yet
|
||||
* EcoAccount is not shared with performing user
|
||||
|
||||
Args:
|
||||
new_url (str): The url to send the post data to
|
||||
post_data (dict): The form post data to be sent
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
# Before running fail positive tests, we need to have an account in a (normally) fine working state
|
||||
self.assertIsNotNone(self.eco_account.recorded) # -> is recorded
|
||||
self.assertGreater(self.eco_account.deductable_surface, test_surface) # -> has more deductable surface than we need
|
||||
self.assertIn(self.superuser, self.eco_account.users.all()) # -> is shared with the performing user
|
||||
|
||||
# Count the number of already existing deductions in total and for the account for later comparison
|
||||
num_deductions = self.eco_account.deductions.count()
|
||||
num_deductions_total = EcoAccountDeduction.objects.count()
|
||||
|
||||
# First test that a deduction can not be created, if the account does not provide
|
||||
# enough surface for the deduction. So we modify the deductable surface of the account
|
||||
self.eco_account.deductable_surface = 0
|
||||
self.eco_account.save()
|
||||
|
||||
# Now perform the (expected) failing request
|
||||
self.client_user.post(new_url, post_data)
|
||||
|
||||
# Expect no changes at all, since the deduction should not have been created
|
||||
self.assertEqual(num_deductions, self.eco_account.deductions.count())
|
||||
self.assertEqual(num_deductions_total, EcoAccountDeduction.objects.count())
|
||||
|
||||
# Now restore the deductable surface to a valid size back again but remove the user from the shared list
|
||||
self.eco_account.deductable_surface = test_surface + 100.00
|
||||
self.eco_account.users.set([])
|
||||
self.eco_account.save()
|
||||
|
||||
# Now perform the (expected) failing request (again)
|
||||
self.client_user.post(new_url, post_data)
|
||||
|
||||
# Expect no changes at all, since the account is not shared
|
||||
self.assertEqual(num_deductions, self.eco_account.deductions.count())
|
||||
self.assertEqual(num_deductions_total, EcoAccountDeduction.objects.count())
|
||||
|
||||
# Restore the sharing but remove the recording state
|
||||
self.eco_account.users.set([self.superuser])
|
||||
self.eco_account.recorded.delete()
|
||||
self.eco_account.refresh_from_db()
|
||||
self.eco_account.save()
|
||||
|
||||
# Now perform the (expected) failing request (again)
|
||||
self.client_user.post(new_url, post_data)
|
||||
|
||||
# Expect no changes at all, since the account is no shared with the user, yet
|
||||
self.assertEqual(num_deductions, self.eco_account.deductions.count())
|
||||
self.assertEqual(num_deductions_total, EcoAccountDeduction.objects.count())
|
||||
|
||||
def subtest_add_deduction_normal(self, new_url: str, post_data: dict, test_surface: float):
|
||||
""" Holds tests on working ("normal") deduction creation
|
||||
|
||||
Args:
|
||||
new_url (str): The url to send the post data to
|
||||
post_data (dict): The form post data to be sent
|
||||
test_surface (float): The expected surface of the deduction
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
# Prepare the account for a working situation (enough deductable surface, recorded and shared)
|
||||
self.eco_account.deductable_surface = 10000.00
|
||||
if self.eco_account.recorded is None:
|
||||
rec_action = UserActionLogEntry.objects.create(
|
||||
user=self.superuser,
|
||||
action=UserAction.RECORDED
|
||||
)
|
||||
self.eco_account.recorded = rec_action
|
||||
self.eco_account.users.set([self.superuser])
|
||||
self.eco_account.save()
|
||||
|
||||
# Run the request
|
||||
self.client_user.post(new_url, post_data)
|
||||
|
||||
# Expect the deduction to be created, since all constraints are fulfilled
|
||||
self.assertEqual(1, self.eco_account.deductions.count())
|
||||
self.assertEqual(1, EcoAccountDeduction.objects.count())
|
||||
|
||||
# Make sure the deduction contains the expected data
|
||||
deduction = EcoAccountDeduction.objects.first()
|
||||
self.assertEqual(deduction.surface, test_surface)
|
||||
self.assertEqual(deduction.intervention, self.intervention)
|
||||
self.assertEqual(deduction.account, self.eco_account)
|
||||
|
||||
# Return deduction for further usage in tests
|
||||
return deduction
|
||||
|
||||
def subtest_add_deduction(self):
|
||||
""" Holds test for adding a new deduction
|
||||
|
||||
Contains tests for
|
||||
* positive fails (as expected)
|
||||
* normal cases
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
# Create the url for creating a new deduction
|
||||
new_url = reverse("compensation:acc-new-deduction", args=(self.eco_account.id,))
|
||||
|
||||
# Prepare the form data
|
||||
test_surface = 100.00
|
||||
post_data = {
|
||||
"surface": test_surface,
|
||||
"account": self.eco_account.id,
|
||||
"intervention": self.intervention.id,
|
||||
}
|
||||
# Run some tests for regular, working cases
|
||||
deduction = self.subtest_add_deduction_normal(new_url, post_data, test_surface)
|
||||
|
||||
# Run some tests where we expect the creation of a deduction to fail (as expected)
|
||||
self.subtest_add_deduction_fail_positive(new_url, post_data, test_surface)
|
||||
|
||||
# Return deduction for further usage in tests
|
||||
return deduction
|
||||
|
||||
def subtest_delete_deduction(self, deduction: EcoAccountDeduction):
|
||||
""" Holds test for deleting a deduction
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
# Prepare url for deleting of this deduction
|
||||
delete_url = reverse("compensation:acc-remove-deduction", args=(self.eco_account.id, deduction.id,))
|
||||
post_data = {
|
||||
"confirm": True
|
||||
}
|
||||
# Save number of current deductions for later comparison
|
||||
num_deductions = self.eco_account.deductions.count()
|
||||
num_deductions_total = EcoAccountDeduction.objects.count()
|
||||
|
||||
# Run request
|
||||
self.client_user.post(delete_url, post_data)
|
||||
|
||||
# Expect the deduction to be gone from the db and relations
|
||||
self.assertEqual(num_deductions - 1, self.eco_account.deductions.count())
|
||||
self.assertEqual(num_deductions_total - 1, EcoAccountDeduction.objects.count())
|
||||
|
||||
# Expect the deduction to be totally gone
|
||||
self.assert_object_is_deleted(deduction)
|
||||
|
||||
def test_deduction(self):
|
||||
"""
|
||||
Checks a 'normal case of adding a deduction.
|
||||
We expect a new deduction to be addable to an existing intervention
|
||||
We expect a deduction to be deletable
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
# Create a new deduction for the default intervention
|
||||
deduction = self.subtest_add_deduction()
|
||||
|
||||
# Now remove the deduction again
|
||||
self.subtest_delete_deduction(deduction)
|
||||
|
@ -8,6 +8,7 @@ Created on: 26.10.21
|
||||
from abc import abstractmethod
|
||||
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.test import TestCase, Client
|
||||
from django.urls import reverse
|
||||
|
||||
@ -355,3 +356,22 @@ class BaseWorkflowTestCase(BaseTestCase):
|
||||
cls.client_user = Client()
|
||||
cls.client_user.login(username=cls.superuser.username, password=cls.superuser_pw)
|
||||
cls.client_anon = Client()
|
||||
|
||||
def assert_object_is_deleted(self, obj):
|
||||
""" Provides a quick check whether an object has been removed from the database or not
|
||||
|
||||
Args:
|
||||
obj ():
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
# Expect the object to be gone from the db
|
||||
try:
|
||||
obj.refresh_from_db()
|
||||
# Well, we should not reach this next line of code, since the object should be gone, therefore not
|
||||
# refreshable -> fail!
|
||||
self.fail()
|
||||
except ObjectDoesNotExist:
|
||||
# If we get in here, the test was fine
|
||||
pass
|
Loading…
Reference in New Issue
Block a user