From 1ed1d7a591c089c59cf1a8ce8fecfb798d98c74a Mon Sep 17 00:00:00 2001 From: Piotr Gawron <piotr.gawron@uni.lu> Date: Mon, 11 Dec 2017 12:41:10 +0100 Subject: [PATCH] unit tests for voucher forms --- smash/web/forms/__init__.py | 4 +- smash/web/forms/forms.py | 68 +--------------- smash/web/forms/voucher_forms.py | 77 +++++++++++++++++++ smash/web/tests/__init__.py | 3 + smash/web/tests/forms/test_subject_forms.py | 2 +- smash/web/tests/forms/test_voucher_forms.py | 71 +++++++++++++++++ smash/web/tests/view/test_voucher.py | 2 +- .../web/tests/view/test_voucher_type_price.py | 2 +- smash/web/views/voucher.py | 2 +- smash/web/views/voucher_type.py | 2 +- smash/web/views/voucher_type_price.py | 2 +- 11 files changed, 162 insertions(+), 73 deletions(-) create mode 100644 smash/web/forms/voucher_forms.py create mode 100644 smash/web/tests/forms/test_voucher_forms.py diff --git a/smash/web/forms/__init__.py b/smash/web/forms/__init__.py index 41432b74..23d44c94 100644 --- a/smash/web/forms/__init__.py +++ b/smash/web/forms/__init__.py @@ -4,8 +4,10 @@ from forms import WorkerAddForm, \ AvailabilityEditForm, HolidayAddForm from study_subject_forms import StudySubjectAddForm, StudySubjectDetailForm, StudySubjectEditForm from subject_forms import SubjectAddForm, SubjectEditForm, SubjectDetailForm +from voucher_forms import VoucherTypeForm, VoucherTypePriceForm, VoucherForm __all__ = [StudySubjectAddForm, StudySubjectDetailForm, StudySubjectEditForm, WorkerAddForm, WorkerEditForm, AppointmentDetailForm, AppointmentEditForm, AppointmentAddForm, VisitDetailForm, VisitAddForm, ContactAttemptForm, ContactAttemptEditForm, KitRequestForm, StatisticsForm, AvailabilityAddForm, - AvailabilityEditForm, HolidayAddForm, SubjectAddForm, SubjectEditForm, SubjectDetailForm] + AvailabilityEditForm, HolidayAddForm, SubjectAddForm, SubjectEditForm, SubjectDetailForm, VoucherTypeForm, + VoucherTypePriceForm, VoucherForm] diff --git a/smash/web/forms/forms.py b/smash/web/forms/forms.py index 836874bf..e59536a3 100644 --- a/smash/web/forms/forms.py +++ b/smash/web/forms/forms.py @@ -4,13 +4,11 @@ from collections import OrderedDict from django import forms from django.forms import ModelForm, Form -from django.utils import timezone from django.utils.dates import MONTHS -from web.algorithm import VerhoeffAlgorithm from web.models import StudySubject, Worker, Appointment, Visit, AppointmentType, ContactAttempt, AppointmentTypeLink, \ - Availability, Holiday, VoucherType, VoucherTypePrice, Voucher -from web.models.constants import SUBJECT_TYPE_CHOICES, VOUCHER_STATUS_NEW, VOUCHER_STATUS_USED + Availability, Holiday +from web.models.constants import SUBJECT_TYPE_CHOICES from web.views.notifications import get_filter_locations """ @@ -389,65 +387,3 @@ class HolidayAddForm(ModelForm): validate_availability_conflict(self, self.cleaned_data, availability) -class VoucherTypeForm(ModelForm): - class Meta: - model = VoucherType - exclude = ['study'] - - -class VoucherTypePriceForm(ModelForm): - start_date = forms.DateField(label="Start date", - widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d") - ) - end_date = forms.DateField(label="End date", - widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d") - ) - - class Meta: - model = VoucherTypePrice - exclude = ['voucher_type'] - - -class VoucherForm(ModelForm): - class Meta: - model = Voucher - fields = '__all__' - - def __init__(self, *args, **kwargs): - super(VoucherForm, self).__init__(*args, **kwargs) - self.fields['number'].widget.attrs['readonly'] = True - self.fields['number'].required = False - - self.fields['issue_date'].widget.attrs['readonly'] = True - self.fields['issue_date'].required = False - self.fields['expiry_date'].widget.attrs['readonly'] = True - self.fields['expiry_date'].required = False - self.fields['use_date'].widget.attrs['readonly'] = True - instance = getattr(self, 'instance', None) - if instance and instance.pk: - self.fields['voucher_type'].widget.attrs['readonly'] = True - if instance.status != VOUCHER_STATUS_NEW: - self.fields['status'].widget.attrs['readonly'] = True - self.fields['feedback'].widget.attrs['readonly'] = True - self.fields['usage_partner'].widget.attrs['readonly'] = True - - def clean(self): - if self.cleaned_data["status"] == VOUCHER_STATUS_USED and not self.cleaned_data["usage_partner"]: - self.add_error('usage_partner', "Partner must be defined for used voucher") - if self.cleaned_data["status"] != VOUCHER_STATUS_USED and self.cleaned_data["usage_partner"]: - self.add_error('status', "Status must be used for voucher with defined partner") - - def save(self, commit=True): - instance = super(VoucherForm, self).save(commit=False) - if not instance.id: - instance.issue_date = timezone.now() - instance.expiry_date = instance.issue_date + datetime.timedelta(days=92) - max_id = str(0).zfill(5) - if Voucher.objects.all().count() > 0: - max_id = str(Voucher.objects.latest('id').id).zfill(5) - instance.number = max_id + VerhoeffAlgorithm.calculate_verhoeff_check_sum(max_id) - if instance.status == VOUCHER_STATUS_USED and not instance.use_date: - instance.use_date = timezone.now() - - if commit: - instance.save() diff --git a/smash/web/forms/voucher_forms.py b/smash/web/forms/voucher_forms.py new file mode 100644 index 00000000..68de4581 --- /dev/null +++ b/smash/web/forms/voucher_forms.py @@ -0,0 +1,77 @@ +import datetime +import logging + +from django import forms +from django.forms import ModelForm +from django.utils import timezone + +from web.algorithm import VerhoeffAlgorithm +from web.forms.forms import DATEPICKER_DATE_ATTRS +from web.models import VoucherType, VoucherTypePrice, Voucher +from web.models.constants import VOUCHER_STATUS_NEW, VOUCHER_STATUS_USED + +logger = logging.getLogger(__name__) + + +class VoucherTypeForm(ModelForm): + class Meta: + model = VoucherType + exclude = ['study'] + + +class VoucherTypePriceForm(ModelForm): + start_date = forms.DateField(label="Start date", + widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d") + ) + end_date = forms.DateField(label="End date", + widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d") + ) + + class Meta: + model = VoucherTypePrice + exclude = ['voucher_type'] + + +class VoucherForm(ModelForm): + class Meta: + model = Voucher + fields = '__all__' + + def __init__(self, *args, **kwargs): + super(VoucherForm, self).__init__(*args, **kwargs) + self.fields['number'].widget.attrs['readonly'] = True + self.fields['number'].required = False + + self.fields['issue_date'].widget.attrs['readonly'] = True + self.fields['issue_date'].required = False + self.fields['expiry_date'].widget.attrs['readonly'] = True + self.fields['expiry_date'].required = False + self.fields['use_date'].widget.attrs['readonly'] = True + instance = getattr(self, 'instance', None) + if instance and instance.pk: + self.fields['voucher_type'].widget.attrs['readonly'] = True + if instance.status != VOUCHER_STATUS_NEW: + self.fields['status'].widget.attrs['readonly'] = True + self.fields['feedback'].widget.attrs['readonly'] = True + self.fields['usage_partner'].widget.attrs['readonly'] = True + + def clean(self): + if self.cleaned_data["status"] == VOUCHER_STATUS_USED and not self.cleaned_data["usage_partner"]: + self.add_error('usage_partner', "Partner must be defined for used voucher") + if self.cleaned_data["status"] != VOUCHER_STATUS_USED and self.cleaned_data["usage_partner"]: + self.add_error('status', "Status must be used for voucher with defined partner") + + def save(self, commit=True): + instance = super(VoucherForm, self).save(commit=False) + if not instance.id: + instance.issue_date = timezone.now() + instance.expiry_date = instance.issue_date + datetime.timedelta(days=92) + max_id = str(0).zfill(5) + if Voucher.objects.all().count() > 0: + max_id = str(Voucher.objects.latest('id').id).zfill(5) + instance.number = max_id + VerhoeffAlgorithm.calculate_verhoeff_check_sum(max_id) + if instance.status == VOUCHER_STATUS_USED and not instance.use_date: + instance.use_date = timezone.now() + + if commit: + instance.save() diff --git a/smash/web/tests/__init__.py b/smash/web/tests/__init__.py index 4d84e299..69223267 100644 --- a/smash/web/tests/__init__.py +++ b/smash/web/tests/__init__.py @@ -1,3 +1,4 @@ +import logging import os from django.conf import settings from django.contrib.auth.models import User @@ -8,6 +9,8 @@ from functions import create_worker settings.MEDIA_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data') +logger = logging.getLogger(__name__) + class LoggedInTestCase(TestCase): def setUp(self): diff --git a/smash/web/tests/forms/test_subject_forms.py b/smash/web/tests/forms/test_subject_forms.py index beb2bcbd..fe109455 100644 --- a/smash/web/tests/forms/test_subject_forms.py +++ b/smash/web/tests/forms/test_subject_forms.py @@ -9,7 +9,7 @@ logger = logging.getLogger(__name__) class StudySubjectAddFormTests(LoggedInWithWorkerTestCase): def setUp(self): - super(LoggedInWithWorkerTestCase, self).setUp() + super(StudySubjectAddFormTests, self).setUp() self.subject = create_subject() def test_is_valid_social_security_number_too_short(self): diff --git a/smash/web/tests/forms/test_voucher_forms.py b/smash/web/tests/forms/test_voucher_forms.py new file mode 100644 index 00000000..e7310f34 --- /dev/null +++ b/smash/web/tests/forms/test_voucher_forms.py @@ -0,0 +1,71 @@ +import logging + +from django.urls import reverse + +from web.forms import VoucherForm +from web.models import Voucher +from web.models.constants import VOUCHER_STATUS_USED +from web.tests import LoggedInWithWorkerTestCase +from web.tests.functions import create_study_subject, create_voucher_type, format_form_field, create_voucher + +logger = logging.getLogger(__name__) + + +class VoucherFormTests(LoggedInWithWorkerTestCase): + def setUp(self): + super(VoucherFormTests, self).setUp() + + def test_auto_generated_use_date(self): + study_subject = create_study_subject() + create_voucher(study_subject) + + voucher_form = VoucherForm() + form_data = { + "status": VOUCHER_STATUS_USED, + "usage_partner": str(self.worker.id), + "voucher_type": create_voucher_type().id + } + for key, value in voucher_form.initial.items(): + form_data[key] = format_form_field(value) + + url = reverse('web.views.voucher_add') + '?study_subject_id=' + str(study_subject.id) + response = self.client.post(url, data=form_data) + self.assertEqual(response.status_code, 302) + + self.assertEqual(2, Voucher.objects.all().count()) + self.assertEqual(1, Voucher.objects.filter(use_date__isnull=False).count()) + + def test_valid_usage_partner(self): + study_subject = create_study_subject() + voucher = create_voucher(study_subject) + voucher.status = VOUCHER_STATUS_USED + voucher.save() + + voucher_form = VoucherForm(instance=voucher) + + form_data = {} + for key, value in voucher_form.initial.items(): + form_data[key] = format_form_field(value) + form_data["usage_partner"] = "" + + voucher_form = VoucherForm(instance=voucher, data=form_data) + + self.assertFalse(voucher_form.is_valid()) + self.assertTrue("usage_partner" in voucher_form.errors) + + def test_valid_status(self): + study_subject = create_study_subject() + voucher = create_voucher(study_subject) + voucher.usage_partner = self.worker + voucher.save() + + voucher_form = VoucherForm(instance=voucher) + + form_data = {} + for key, value in voucher_form.initial.items(): + form_data[key] = format_form_field(value) + + voucher_form = VoucherForm(instance=voucher, data=form_data) + + self.assertFalse(voucher_form.is_valid()) + self.assertTrue("status" in voucher_form.errors) diff --git a/smash/web/tests/view/test_voucher.py b/smash/web/tests/view/test_voucher.py index 3d2b0233..871bf563 100644 --- a/smash/web/tests/view/test_voucher.py +++ b/smash/web/tests/view/test_voucher.py @@ -2,7 +2,7 @@ import logging from django.urls import reverse -from web.forms.forms import VoucherForm +from web.forms import VoucherForm from web.models import Voucher from web.models.constants import VOUCHER_STATUS_NEW from web.tests.functions import create_voucher, create_study_subject, format_form_field, create_voucher_type diff --git a/smash/web/tests/view/test_voucher_type_price.py b/smash/web/tests/view/test_voucher_type_price.py index 60c20dd2..5032c40b 100644 --- a/smash/web/tests/view/test_voucher_type_price.py +++ b/smash/web/tests/view/test_voucher_type_price.py @@ -2,7 +2,7 @@ import logging from django.urls import reverse -from web.forms.forms import VoucherTypePriceForm +from web.forms import VoucherTypePriceForm from web.models import VoucherType, VoucherTypePrice from web.tests.functions import create_voucher_type, create_voucher_type_price, format_form_field from .. import LoggedInTestCase diff --git a/smash/web/views/voucher.py b/smash/web/views/voucher.py index a054d9d0..840e5d34 100644 --- a/smash/web/views/voucher.py +++ b/smash/web/views/voucher.py @@ -7,7 +7,7 @@ from django.views.generic import CreateView from django.views.generic import ListView from django.views.generic import UpdateView -from web.forms.forms import VoucherForm +from web.forms import VoucherForm from web.models import Voucher from web.models.constants import GLOBAL_STUDY_ID from . import WrappedView diff --git a/smash/web/views/voucher_type.py b/smash/web/views/voucher_type.py index 87b13059..5cb45eb5 100644 --- a/smash/web/views/voucher_type.py +++ b/smash/web/views/voucher_type.py @@ -4,7 +4,7 @@ from django.views.generic import CreateView from django.views.generic import ListView from django.views.generic import UpdateView -from web.forms.forms import VoucherTypeForm +from web.forms import VoucherTypeForm from web.models import VoucherType from web.models.constants import GLOBAL_STUDY_ID from . import WrappedView diff --git a/smash/web/views/voucher_type_price.py b/smash/web/views/voucher_type_price.py index f93a045f..11f6f4dd 100644 --- a/smash/web/views/voucher_type_price.py +++ b/smash/web/views/voucher_type_price.py @@ -5,7 +5,7 @@ from django.urls import reverse_lazy from django.views.generic import CreateView from django.views.generic import UpdateView -from web.forms.forms import VoucherTypePriceForm +from web.forms import VoucherTypePriceForm from web.models import VoucherTypePrice from . import WrappedView -- GitLab