* adds workflow tests or deductions in InterventionWorkflowTestCase
* fixes bugs detected by testing
pull/40/head
mpeltriaux 3 years ago
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…
Cancel
Save