Skip to content

Commit

Permalink
Add relevant checks to serializers. Update tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
bohare authored and amplifi committed Jul 14, 2017
1 parent 710d66a commit ba847ad
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 8 deletions.
2 changes: 1 addition & 1 deletion cadasta/questionnaires/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def create_attrs_schema(project=None, dict=None, content_type=None,
if relevant:
check_relevant_clause(relevant)
clauses = relevant.split('=')
selector = re.sub("'", '', clauses[1])
selector = re.sub("('|\"|”)", '', clauses[1])
selectors += (selector,)

try:
Expand Down
17 changes: 11 additions & 6 deletions cadasta/questionnaires/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from .messages import MISSING_RELEVANT
from .exceptions import InvalidQuestionnaire
from .validators import validate_questionnaire
from .managers import fix_labels
from .managers import fix_labels, check_relevant_clause
from . import models


Expand Down Expand Up @@ -94,15 +94,18 @@ def to_representation(self, instance):
def create(self, validated_data):
initial_data = self.find_initial_data(validated_data['name'])
validated_data['label_xlat'] = initial_data['label']
relevant = initial_data.get('relevant', None)
if relevant:
check_relevant_clause(relevant)
question = models.Question.objects.create(
questionnaire_id=self.context['questionnaire_id'],
question_group_id=self.context.get('question_group_id'),
**validated_data)

option_serializer = QuestionOptionSerializer(
data=initial_data.get('options', []),
many=True,
context={'question_id': question.id})
data=initial_data.get('options', []),
many=True,
context={'question_id': question.id})

option_serializer.is_valid(raise_exception=True)
option_serializer.save()
Expand All @@ -117,7 +120,7 @@ class QuestionGroupSerializer(FindInitialMixin, serializers.ModelSerializer):

class Meta:
model = models.QuestionGroup
fields = ('id', 'name', 'label', 'type', 'questions',
fields = ('id', 'name', 'label', 'type', 'questions',
'question_groups', 'label_xlat', 'relevant', 'index', )
read_only_fields = ('id', 'questions', 'question_groups', )
write_only_fields = ('label_xlat', )
Expand All @@ -139,6 +142,7 @@ def get_question_groups(self, group):
def create(self, validated_data):
initial_data = self.find_initial_data(validated_data['name'])
validated_data['label_xlat'] = initial_data['label']

group = models.QuestionGroup.objects.create(
questionnaire_id=self.context['questionnaire_id'],
question_group_id=self.context.get('question_group_id'),
Expand All @@ -162,8 +166,9 @@ def create(self, validated_data):

relevant = initial_data.get('relevant', None)
if relevant:
check_relevant_clause(relevant)
clauses = relevant.split('=')
selector = re.sub("'", '', clauses[1])
selector = re.sub("('|\"|”)", '', clauses[1])
selectors += (selector,)

app_label = ATTRIBUTE_GROUPS[attr_group]['app_label']
Expand Down
76 changes: 75 additions & 1 deletion cadasta/questionnaires/tests/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ def test_huge(self):
"default": None,
"hint": None,
"index": 1,
"relevant": "${start}>='IN'"
"relevant": None
},
{
"id": "rw7mt32858cu2w5urbf9z3a4",
Expand Down Expand Up @@ -593,6 +593,9 @@ def test_huge(self):
"label": "Label",
"type": 'group',
"index": 13,
"bind": {
"relevant": "$party_type='IN'"
},
"questions": [
{
"id": "8v5znbuyvtyinsdd96ytyrui",
Expand Down Expand Up @@ -959,6 +962,37 @@ def test_huge(self):
assert questionnaire.question_groups.count() == 7
assert Attribute.objects.count() == 13

def test_invalid_relevant_clause(self):
data = {
'title': 'yx8sqx6488wbc4yysnkrbnfq',
'id_string': 'yx8sqx6488wbc4yysnkrbnfq',
'default_language': 'en',
'questions': [{
'name': "start",
'label': 'Label',
'type': "ST",
'required': False,
'constraint': None,
'index': 0,
'relevant': "$party_type='IN'"
}, {
'name': "end",
'label': 'Label',
'type': "EN",
'index': 1
}]
}
project = ProjectFactory.create()

serializer = serializers.QuestionnaireSerializer(
data=data,
context={'project': project}
)
serializer.is_valid(raise_exception=True)
with pytest.raises(InvalidQuestionnaire) as e:
serializer.save()
assert str(e.value) == "Invalid relevant clause: $party_type='IN'"


class QuestionGroupSerializerTest(UserTestCase, TestCase):
def test_serialize(self):
Expand Down Expand Up @@ -1187,6 +1221,30 @@ def test_create_numeric_attribute_with_default_0(self):
assert questionnaire.question_groups.count() == 1
assert Attribute.objects.get(name='number').default == '0'

def test_question_group_with_invalid_relevant(self):
questionnaire = factories.QuestionnaireFactory.create()
data = [{
'label': 'A group',
'name': 'party_attributes_individual',
"relevant": "$party_type='IN'",
'questions': [{
'name': "start",
'label': 'Start',
'type': "TX",
'index': 0
}]
}]
serializer = serializers.QuestionGroupSerializer(
data=data,
many=True,
context={'questionnaire_id': questionnaire.id,
'project': questionnaire.project,
'default_language': 'en'})
serializer.is_valid(raise_exception=True)
with pytest.raises(InvalidQuestionnaire) as e:
serializer.save()
assert str(e.value) == "Invalid relevant clause: $party_type='IN'"


class QuestionSerializerTest(TestCase):
def test_serialize(self):
Expand Down Expand Up @@ -1326,6 +1384,22 @@ def test_bulk_create(self):
assert q.type == 'S1'
assert q.options.count() == 1

def test_create_question_with_invalid_relevant(self):
questionnaire = factories.QuestionnaireFactory.create()
data = {
'label': 'A question',
'name': 'question',
'type': 'TX',
'relevant': "$party_type='IN'"
}
serializer = serializers.QuestionSerializer(
data=data,
context={'questionnaire_id': questionnaire.id})
serializer.is_valid(raise_exception=True)
with pytest.raises(InvalidQuestionnaire) as e:
serializer.save()
assert str(e.value) == "Invalid relevant clause: $party_type='IN'"


class QuestionOptionSerializerTest(TestCase):
def test_serialize(self):
Expand Down

0 comments on commit ba847ad

Please sign in to comment.