Skip to content

Commit

Permalink
Added a test for SubchoicesPositiveIntegerField
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasRychtecky committed Jan 7, 2017
1 parent 658a51c commit f1f21ab
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 19 deletions.
39 changes: 25 additions & 14 deletions chamber/models/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import os
from uuid import uuid4 as uuid

from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import FileField as OriginFileField
from django.core.exceptions import ValidationError
from django.db.models.fields import DecimalField as OriginDecimalField
from django.forms import forms
from django.template.defaultfilters import filesizeformat
Expand All @@ -15,15 +15,15 @@

from chamber import config
from chamber.forms.fields import DecimalField as DecimalFormField
from chamber.utils.datastructures import SubstatesChoicesNumEnum, SequenceChoicesEnumMixin
from chamber.utils.datastructures import SequenceChoicesEnumMixin, SubstatesChoicesNumEnum


try:
from sorl.thumbnail import ImageField as OriginImageField
except ImportError:
from django.db.models import ImageField as OriginImageField



class SouthMixin(object):

def south_field_triple(self):
Expand Down Expand Up @@ -138,23 +138,34 @@ def __init__(self, *args, **kwargs):
kwargs['choices'] = self.enum.choices
super(SubchoicesPositiveIntegerField, self).__init__(*args, **kwargs)

def _get_subvalue(self, model_instance):
return getattr(model_instance, self.subchoices_field_name)

def clean(self, value, model_instance):
supvalue = getattr(model_instance, self.subchoices_field_name)
if self.enum and supvalue not in self.enum.categories:
if self.enum and self._get_subvalue(model_instance) not in self.enum.categories:
return None
else:
return super(SubchoicesPositiveIntegerField, self).clean(value, model_instance)

def _raise_error_if_value_suppose_to_be_empty(self, value, subvalue):
if self.enum and subvalue not in self.enum.categories and value is not None:
raise ValidationError(ugettext('Value must be empty'))

def _raise_error_if_value_is_not_allowed(self, value, subvalue, model_instance):
allowed_values = self.enum.get_allowed_states(getattr(model_instance, self.subchoices_field_name))
if subvalue in self.enum.categories and value not in allowed_values:
raise ValidationError(ugettext('Allowed choices are {}.').format(
', '.join(('{} ({})'.format(*(self.enum.get_label(val), val)) for val in allowed_values))
))

def validate(self, value, model_instance):
if self.enum:
supvalue = getattr(model_instance, self.subchoices_field_name)
allowed_values = self.enum.get_allowed_states(getattr(model_instance, self.subchoices_field_name))
if self.enum and supvalue not in self.enum.categories and value is not None:
raise ValidationError(ugettext('Value must be empty'))
elif supvalue in self.enum.categories and value not in allowed_values:
raise ValidationError(ugettext('Allowed choices are {}.').format(
', '.join(('{} ({})'.format(*(self.enum.get_label(val), val)) for val in allowed_values))
))
if not self.enum:
return

subvalue = self._get_subvalue(model_instance)

self._raise_error_if_value_suppose_to_be_empty(value, subvalue)
self._raise_error_if_value_is_not_allowed(value, subvalue, model_instance)


class EnumSequenceFieldMixin(object):
Expand Down
2 changes: 1 addition & 1 deletion example/dj/apps/test_chamber/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from chamber import models as chamber_models
from chamber.models import fields as chamber_fields
from chamber.utils.datastructures import SubstatesChoicesNumEnum, ChoicesNumEnum, SequenceChoicesNumEnum
from chamber.utils.datastructures import ChoicesNumEnum, SequenceChoicesNumEnum, SubstatesChoicesNumEnum


class ShortcutsModel(models.Model):
Expand Down
20 changes: 16 additions & 4 deletions example/dj/apps/test_chamber/tests/models/fields.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from django.core.exceptions import ValidationError
from django.test import TransactionTestCase

from chamber.shortcuts import change_and_save
from chamber.exceptions import PersistenceException
from chamber.models.fields import generate_random_upload_path
from germanium.tools import assert_equal, assert_raises, assert_true, assert_is_none
from chamber.shortcuts import change_and_save

from chamber.exceptions import PersistenceException
from germanium.tools import assert_equal, assert_is_none, assert_raises, assert_true # NOQA

from test_chamber.models import TestFieldsModel, CSVRecord
from test_chamber.models import CSVRecord, TestFieldsModel # NOQA


class ModelFieldsTestCase(TransactionTestCase):
Expand Down Expand Up @@ -45,6 +46,17 @@ def test_subchoices_field(self):
assert_equal(self.inst.state, TestFieldsModel.STATE.NOT_OK)
assert_equal(self.inst.state_reason, TestFieldsModel.STATE_REASON.SUB_NOT_OK_2)

def test_subchoices_field_value_should_be_empty(self):
self.inst.state = 4 # setting an invalid value
try:
TestFieldsModel._meta.get_field_by_name('state_reason')[0].validate(
TestFieldsModel.STATE_REASON.SUB_NOT_OK_2, self.inst)
assert_true(False, 'Field validation should raise an error')
except ValidationError as ex:
assert_equal(['Value must be empty'], ex.messages)
assert_is_none(TestFieldsModel._meta.get_field_by_name('state_reason')[0].clean(
TestFieldsModel.STATE_REASON.SUB_NOT_OK_2, self.inst))

def test_prev_value_field(self):
# In case of `add`, value of state is copied to state_prev
change_and_save(self.inst, state=TestFieldsModel.STATE.OK,
Expand Down

0 comments on commit f1f21ab

Please sign in to comment.