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:
commit
39abfceb76
4 changed files with 1482 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
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("Bad request"))
|
||||
else:
|
||||
if type_ope == Operation.DEPOSIT and amount <= 0:
|
||||
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
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue