Merge branch 'aureplop/kfet-tests_perform_operations' into 'master'

kfet.tests -- Add tests for perform_operations view + small things

See merge request cof-geek/gestioCOF!313
This commit is contained in:
Martin Pepin 2018-10-04 23:59:30 +02:00
commit 39abfceb76
4 changed files with 1482 additions and 23 deletions

View file

@ -1,25 +1,39 @@
from django.core.exceptions import ValidationError
from django.db import models
from djconfig import config
import djconfig
class KFetConfig(object):
"""kfet app configuration.
Enhance isolation with backend used to store config.
Usable after DjConfig middleware was called.
"""
prefix = 'kfet_'
def __init__(self):
# Set this to False again to reload the config, e.g for testing
# purposes.
self._conf_init = False
def _check_init(self):
# For initialization purposes, we call 'reload_maybe' directly
# (normaly done once per request in middleware).
# Note it should be called only once across requests, if you use
# kfet_config instance below.
if not self._conf_init:
djconfig.reload_maybe()
self._conf_init = True
def __getattr__(self, key):
self._check_init()
if key == 'subvention_cof':
# Allows accessing to the reduction as a subvention
# Other reason: backward compatibility
reduction_mult = 1 - self.reduction_cof/100
return (1/reduction_mult - 1) * 100
return getattr(config, self._get_dj_key(key))
return getattr(djconfig.config, self._get_dj_key(key))
def list(self):
"""Get list of kfet app configuration.
@ -30,7 +44,8 @@ class KFetConfig(object):
"""
# prevent circular imports
from kfet.forms import KFetConfigForm
return [(field.label, getattr(config, name), )
self._check_init()
return [(field.label, getattr(djconfig.config, name), )
for name, field in KFetConfigForm.base_fields.items()]
def _get_dj_key(self, key):
@ -47,6 +62,7 @@ class KFetConfig(object):
# prevent circular imports
from kfet.forms import KFetConfigForm
self._check_init()
# get old config
new_cfg = KFetConfigForm().initial
# update to new config

View file

@ -3,6 +3,7 @@ from decimal import Decimal
from django import forms
from django.core.exceptions import ValidationError
from django.core import validators
from django.contrib.auth.models import User
from django.forms import modelformset_factory
from django.utils import timezone
@ -273,6 +274,10 @@ class ArticleRestrictForm(ArticleForm):
# -----
class KPsulOperationGroupForm(forms.ModelForm):
# FIXME(AD): Use timezone.now instead of timezone.now() to avoid using a
# fixed datetime (application boot here).
# One may even use: Checkout.objects.is_valid() if changing
# to now = timezone.now is ok in 'is_valid' definition.
checkout = forms.ModelChoiceField(
queryset = Checkout.objects.filter(
is_protected=False, valid_from__lte=timezone.now(),
@ -317,13 +322,18 @@ class KPsulOperationForm(forms.ModelForm):
queryset=Article.objects.select_related('category').all(),
required=False,
widget = forms.HiddenInput())
article_nb = forms.IntegerField(
required=False,
initial=None,
validators=[validators.MinValueValidator(1)],
widget=forms.HiddenInput(),
)
class Meta:
model = Operation
fields = ['type', 'amount', 'article', 'article_nb']
widgets = {
'type': forms.HiddenInput(),
'amount': forms.HiddenInput(),
'article_nb': forms.HiddenInput(),
}
def clean(self):
@ -332,22 +342,26 @@ class KPsulOperationForm(forms.ModelForm):
amount = self.cleaned_data.get('amount')
article = self.cleaned_data.get('article')
article_nb = self.cleaned_data.get('article_nb')
errors = []
if type_ope and type_ope == Operation.PURCHASE:
if not article or not article_nb:
raise ValidationError(
"Un achat nécessite un article et une quantité")
if article_nb < 1:
raise ValidationError("Impossible d'acheter moins de 1 article")
if not article or article_nb is None or article_nb < 1:
errors.append(ValidationError(
"Un achat nécessite un article et une quantité"))
elif type_ope and type_ope in [Operation.DEPOSIT, Operation.WITHDRAW]:
if not amount or article or article_nb:
raise ValidationError("Bad request")
errors.append(ValidationError("Bad request"))
else:
if type_ope == Operation.DEPOSIT and amount <= 0:
raise ValidationError("Charge non positive")
if type_ope == Operation.WITHDRAW and amount >= 0:
raise ValidationError("Retrait non négatif")
errors.append(ValidationError("Charge non positive"))
elif type_ope == Operation.WITHDRAW and amount >= 0:
errors.append(ValidationError("Retrait non négatif"))
self.cleaned_data['article'] = None
self.cleaned_data['article_nb'] = None
if errors:
raise ValidationError(errors)
KPsulOperationFormSet = modelformset_factory(
Operation,
form = KPsulOperationForm,

File diff suppressed because it is too large Load diff

View file

@ -178,7 +178,9 @@ class ViewTestCaseMixin(TestCaseMixin):
During setup, three users are created with their kfet account:
- 'user': a basic user without any permission, account trigramme: 000,
- 'team': a user with kfet.is_team permission, account trigramme: 100,
- 'root': a superuser, account trigramme: 200.
- 'root': a superuser, account trigramme: 200,
- 'liq': if class attribute 'with_liq' is 'True', account
trigramme: LIQ.
Their password is their username.
One can create additionnal users with 'get_users_extra' method, or prevent
@ -221,6 +223,8 @@ class ViewTestCaseMixin(TestCaseMixin):
auth_user = None
auth_forbidden = []
with_liq = False
def setUp(self):
"""
Warning: Do not forget to call super().setUp() in subclasses.
@ -262,7 +266,7 @@ class ViewTestCaseMixin(TestCaseMixin):
"""
# Format desc: username, password, trigramme
return {
users_base = {
# user, user, 000
'user': create_user(),
# team, team, 100
@ -270,6 +274,9 @@ class ViewTestCaseMixin(TestCaseMixin):
# root, root, 200
'root': create_root(),
}
if self.with_liq:
users_base['liq'] = create_user('liq', 'LIQ')
return users_base
@cached_property
def users_base(self):