summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_operations/tests.py82
-rw-r--r--ishtar_common/forms.py43
-rw-r--r--ishtar_common/tests.py70
3 files changed, 154 insertions, 41 deletions
diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py
index ec7ae44c5..9f07aff45 100644
--- a/archaeological_operations/tests.py
+++ b/archaeological_operations/tests.py
@@ -40,7 +40,7 @@ from ishtar_common.models import OrganizationType, Organization, ItemKey, \
ImporterType, IshtarUser, TargetKey, ImporterModel, IshtarSiteProfile, \
Town, ImporterColumn, Person, Author, SourceType, AuthorType, \
DocumentTemplate, PersonType, TargetKeyGroup, JsonDataField, \
- JsonDataSection, ImportTarget, FormaterType
+ JsonDataSection, ImportTarget, FormaterType, CustomForm, ExcludedField
from archaeological_files.models import File, FileType
from archaeological_context_records.models import Unit
@@ -1142,6 +1142,86 @@ class OperationTest(TestCase, OperationInitTest):
self.assertNotIn(u"Marmotte".encode('utf-8'), response.content)
+class CustomFormTest(TestCase, OperationInitTest):
+ fixtures = FILE_FIXTURES
+
+ def setUp(self):
+ IshtarSiteProfile.objects.get_or_create(
+ slug='default', active=True)
+ self.username, self.password, self.user = create_superuser()
+ self.alt_username, self.alt_password, self.alt_user = create_user()
+ self.alt_user.user_permissions.add(Permission.objects.get(
+ codename='view_own_operation'))
+ self.orgas = self.create_orgas(self.user)
+ self.operations = self.create_operation(self.user, self.orgas[0])
+ self.operations += self.create_operation(self.alt_user, self.orgas[0])
+ self.item = self.operations[0]
+
+ def test_filters(self):
+ c = Client()
+ c.login(username=self.username, password=self.password)
+
+ cls_wiz = OperationWizardModifTest
+ url = reverse(cls_wiz.url_name)
+ # first wizard step
+ step = 'selec-operation_modification'
+ cls_wiz.wizard_post(c, url, step, {'pk': self.operations[0].pk})
+
+ step = 'general-operation_modification'
+ data = {
+ '{}{}-current_step'.format(cls_wiz.url_name,
+ cls_wiz.wizard_name): [step],
+ }
+ key_in_charge = "in_charge"
+ response = c.post(url, data)
+ self.assertIn(
+ key_in_charge, response.content,
+ msg="filter all - 'in charge' field not found on the modification "
+ "wizard")
+ f = CustomForm.objects.create(name="Test", form="operation-general",
+ available=True, apply_to_all=True)
+ ExcludedField.objects.create(custom_form=f, field="in_charge")
+
+ response = c.post(url, data)
+ self.assertNotIn(
+ key_in_charge, response.content,
+ msg="filter all - 'in charge' field found on the modification "
+ "wizard. It should have been filtered.")
+
+ # user type form prevail on "all"
+ f_scientist = CustomForm.objects.create(
+ name="Test", form="operation-general", available=True)
+ tpe = PersonType.objects.get(txt_idx='head_scientist')
+ key_address = "address"
+ f_scientist.user_types.add(tpe)
+ self.user.ishtaruser.person.person_types.add(tpe)
+ ExcludedField.objects.create(custom_form=f_scientist, field="address")
+ response = c.post(url, data)
+ self.assertIn(
+ key_in_charge, response.content,
+ msg="filter user type - 'in charge' field not found on the "
+ "modification wizard. It should not have been filtered.")
+ self.assertNotIn(
+ key_address, response.content,
+ msg="filter user type - 'address' field found on the "
+ "modification wizard. It should have been filtered.")
+
+ # user prevail on "all" and "user_types"
+ f_user = CustomForm.objects.create(
+ name="Test", form="operation-general", available=True)
+ f_user.users.add(self.user.ishtaruser)
+ self.user.ishtaruser.person.person_types.add(tpe)
+ response = c.post(url, data)
+ self.assertIn(
+ key_in_charge, response.content,
+ msg="filter user - 'in charge' field not found on the modification "
+ "wizard. It should not have been filtered.")
+ self.assertIn(
+ key_address, response.content,
+ msg="filter user - 'address' field not found on the modification "
+ "wizard. It should not have been filtered.")
+
+
class OperationSearchTest(TestCase, OperationInitTest):
fixtures = FILE_FIXTURES
diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py
index 0f1fa20f8..683726e67 100644
--- a/ishtar_common/forms.py
+++ b/ishtar_common/forms.py
@@ -301,20 +301,41 @@ class ManageOldType(object):
class CustomForm(object):
form_admin_name = ""
form_slug = ""
+ need_user_for_initialization = True
def __init__(self, *args, **kwargs):
+ current_user = None
+ if 'user' in kwargs:
+ try:
+ current_user = kwargs.pop('user').ishtaruser
+ except AttributeError:
+ pass
super(CustomForm, self).__init__(*args, **kwargs)
- # todo: filter by user / group...
- q = models.CustomForm.objects.filter(form=self.form_slug,
- available=True, apply_to_all=True)
- if not q.count():
- return
- # todo: prevent multiple result in database
- form = q.all()[0]
- for excluded in form.excluded_fields.all():
- # could have be filtered previously
- if excluded.field in self.fields:
- self.fields.pop(excluded.field)
+ base_q = {"form": self.form_slug, 'available': True}
+ # order is important : try for user, user type then all
+ query_dicts = []
+ if current_user:
+ dct = base_q.copy()
+ dct.update({'users__pk': current_user.pk})
+ query_dicts = [dct]
+ for user_type in current_user.person.person_types.all():
+ dct = base_q.copy()
+ dct.update({'user_types__pk': user_type.pk}),
+ query_dicts.append(dct)
+ dct = base_q.copy()
+ dct.update({'apply_to_all': True})
+ query_dicts.append(dct)
+ for query_dict in query_dicts:
+ q = models.CustomForm.objects.filter(**query_dict)
+ if not q.count():
+ continue
+ # todo: prevent multiple result in database
+ form = q.all()[0]
+ for excluded in form.excluded_fields.all():
+ # could have be filtered previously
+ if excluded.field in self.fields:
+ self.fields.pop(excluded.field)
+ break
@classmethod
def get_custom_fields(cls):
diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py
index 63d80d5ab..016596772 100644
--- a/ishtar_common/tests.py
+++ b/ishtar_common/tests.py
@@ -288,6 +288,38 @@ class WizardTest(object):
raise ValidationError(u"Errors: {} on {}.".format(
u" ".join(errors), current_step))
+ @classmethod
+ def wizard_post(cls, client, url, current_step, form_data=None,
+ follow=True):
+ if not url:
+ url = reverse(cls.url_name)
+ data = {
+ '{}{}-current_step'.format(cls.url_name,
+ cls.wizard_name): [current_step],
+ }
+ if not form_data:
+ form_data = []
+
+ # reconstruct a POST request
+ if type(form_data) in (list, tuple): # is a formset
+ for d_idx, item in enumerate(form_data):
+ for k in item:
+ data['{}-{}-{}'.format(
+ current_step, d_idx, k)] = item[k]
+ else:
+ for k in form_data:
+ data['{}-{}'.format(current_step, k)] = form_data[k]
+
+ try:
+ response = client.post(url, data, follow=follow)
+ except ValidationError as e:
+ msg = u"Errors: {} on {}. On \"ManagementForm data is " \
+ u"missing or...\" error verify the wizard_name or " \
+ u"step name".format(u" - ".join(e.messages),
+ current_step)
+ raise ValidationError(msg)
+ return response
+
def test_wizard(self):
if self.pass_test():
return
@@ -301,35 +333,14 @@ class WizardTest(object):
current_step, current_form = step
if current_step in ignored:
continue
- data = {
- '{}{}-current_step'.format(self.url_name,
- self.wizard_name):
- [current_step],
- }
-
- # reconstruct a POST request
- if current_step in form_data:
- d = form_data[current_step]
- if type(d) in (list, tuple): # is a formset
- for d_idx, item in enumerate(d):
- for k in item:
- data['{}-{}-{}'.format(
- current_step, d_idx, k)] = item[k]
- else:
- for k in d:
- data['{}-{}'.format(current_step, k)] = d[k]
-
next_form_is_checked = len(self.steps) > idx + 1 and \
- self.steps[idx + 1][0] not in ignored
- try:
- response = self.client.post(
- url, data, follow=not next_form_is_checked)
- except ValidationError as e:
- msg = u"Errors: {} on {}. On \"ManagementForm data is " \
- u"missing or...\" error verify the wizard_name or " \
- u"step name".format(u" - ".join(e.messages),
- current_step)
- raise ValidationError(msg)
+ self.steps[idx + 1][0] not in ignored
+ data = []
+ if current_step in form_data:
+ data = form_data[current_step]
+ response = self.wizard_post(
+ self.client, url, current_step, data,
+ not next_form_is_checked)
self.check_response(response, current_step)
if next_form_is_checked:
next_form = self.steps[idx + 1][0]
@@ -402,7 +413,8 @@ class AdminGenTypeTest(TestCase):
gen_models = [
models.OrganizationType, models.PersonType, models.TitleType,
models.AuthorType, models.SourceType, models.OperationType,
- models.SpatialReferenceSystem, models.Format, models.SupportType]
+ models.SpatialReferenceSystem, models.Format, models.SupportType,
+ ]
models_with_data = gen_models + [models.ImporterModel]
models = models_with_data
module_name = 'ishtar_common'