def test_reanswer_selection_in_form_question_creates_flow_to_same_question(self):
        '''

        :return:
        '''
        q1 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                     identifier='test1',
                                     text='test1', answer_type=DateAnswer.choice_name())
        q2 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                     identifier='test2',
                                     text='test2', answer_type=DateAnswer.choice_name())
        q3 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                     identifier='test3',
                                     text='test3', answer_type=DateAnswer.choice_name())
        q4 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                     identifier='test4',
                                     text='test4', answer_type=DateAnswer.choice_name())
        q5 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                     identifier='test5',
                                     text='test5', answer_type=DateAnswer.choice_name())
        self.batch.start_question = q1
        QuestionFlow.objects.create(question_id=q1.id, next_question_id=q2.id)
        QuestionFlow.objects.create(question_id=q2.id, next_question_id=q3.id)
        QuestionFlow.objects.create(question_id=q3.id, next_question_id=q4.id)
        QuestionFlow.objects.create(question_id=q4.id, next_question_id=q5.id)
        test_condition = 'between'
        test_param_upper = datetime.now()
        test_param_lower = datetime.now() - timedelta(days=3)
        form_data = {
            'action': LogicForm.REANSWER,
            'condition': test_condition,
            'min_value': test_param_lower,
            'max_value': test_param_upper
        }
        l = LogicForm(q2, data=form_data)
        if l.is_valid():
            l.save()
            # now check if equivalent Question flow and test arguments were
            # created
            try:
                qf = QuestionFlow.objects.get(
                    question_id=q2.id, next_question_id=q2.id)
                TextArgument.objects.get(
                    flow=qf, position=0, param=test_param_lower)
                TextArgument.objects.create(
                    flow=qf, position=1, param=test_param_upper)
                QuestionFlow.objects.get(
                    question_id=q1.id, next_question_id=q2.id)
                QuestionFlow.objects.get(
                    question_id=q2.id, next_question_id=q3.id)
                self.assertTrue(True)
                return
            except QuestionFlow.DoesNotExist:
                self.assertFalse(False, 'flow not existing')
                pass
            except TextArgument:
                self.assertTrue(False, 'text agrunments not saved')
                pass
        else:
            self.assertTrue(False, 'Invalid form')
 def test_end_interview_selection_in_form_question_creates_flow_to_with_no_next_question(self):
     '''
     :return:
     '''
     yes = 'yes'
     no = 'no'
     q1 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                  identifier='test1',
                                  text='test1', answer_type=DateAnswer.choice_name())
     q2 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                  identifier='test2',
                                  text='test2', answer_type=MultiChoiceAnswer.choice_name())
     q_o1 = QuestionOption.objects.create(question_id=q2.id, text=yes, order=1)
     QuestionOption.objects.create(question_id=q2.id, text=no, order=2)
     q3 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                  identifier='test3',
                                  text='test3', answer_type=DateAnswer.choice_name())
     q4 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                  identifier='test4',
                                  text='test4', answer_type=DateAnswer.choice_name())
     q5 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                  identifier='test5',
                                  text='test5', answer_type=DateAnswer.choice_name())
     self.batch.start_question = q1
     QuestionFlow.objects.create(question_id=q1.id, next_question_id=q2.id)
     QuestionFlow.objects.create(question_id=q2.id, next_question_id=q3.id)
     QuestionFlow.objects.create(question_id=q3.id, next_question_id=q4.id)
     QuestionFlow.objects.create(question_id=q4.id, next_question_id=q5.id)
     test_condition = MultiChoiceAnswer.validators()[0].__name__
     form_data = {
         'action': LogicForm.END_INTERVIEW,
         'condition': test_condition,
         'option': q_o1.order
     }
     l = LogicForm(q2, data=form_data)
     if l.is_valid():
         l.save()
         # now check if equivalent Question flow and test arguments were
         # created
         try:
             qf = QuestionFlow.objects.get(
                 question_id=q2.id, next_question_id__isnull=True)
             TextArgument.objects.get(flow=qf, position=0, param=q_o1.order)
             QuestionFlow.objects.get(
                 question_id=q1.id, next_question_id=q2.id)
             QuestionFlow.objects.get(
                 question_id=q2.id, next_question_id=q3.id)
             self.assertTrue(True)
             return
         except QuestionFlow.DoesNotExist:
             self.assertTrue(False, 'flow not existing')
             pass
         except TextArgument:
             self.assertTrue(False, 'text agrunments not saved')
             pass
     else:
         self.assertFalse(False, 'Invalid form')
Exemplo n.º 3
0
    def __init__(self, question, initial=None, *args, **kwargs):
        super(LogicForm, self).__init__(initial=initial, *args, **kwargs)
        data = kwargs.get('data', None)
        batch = question.qset
        self.question = question
        self.batch = batch
        self.fields['condition'] = forms.ChoiceField(
            label='Eligibility criteria',
            choices=[],
            widget=forms.Select,
            required=False)
        self.fields['attribute'] = forms.ChoiceField(
            label='Attribute', choices=[
                ('value', 'Value'), ], widget=forms.Select, required=False)
        self.fields['condition'].choices = [
            (validator.__name__,
             validator.__name__.upper()) for validator in Answer.get_class(
                question.answer_type).validators()]
        if question.answer_type in [
                MultiChoiceAnswer.choice_name(),
                MultiSelectAnswer.choice_name()]:
            self.fields['option'] = forms.ChoiceField(
                label='', choices=[], widget=forms.Select, required=True)
            self.fields['option'].choices = [
                (option.text, option.text) for option in question.options.all()]
        else:
            self.fields['value'] = forms.CharField(label='', required=False)
            self.fields['min_value'] = forms.CharField(
                label='', required=False, widget=forms.TextInput(
                    attrs={
                        'placeholder': 'Min Value'}))
            self.fields['max_value'] = forms.CharField(
                label='', required=False, widget=forms.TextInput(
                    attrs={
                        'placeholder': 'Max Value'}))
            if question.answer_type == DateAnswer.choice_name():
                self.fields['value'].widget.attrs['class'] = 'datepicker'
                self.fields['min_value'].widget.attrs['class'] = 'datepicker'
                self.fields['max_value'].widget.attrs['class'] = 'datepicker'
            # validate_with_question = forms.ChoiceField(label='', choices=[], widget=forms.Select, required=False)
        self.fields['action'] = forms.ChoiceField(
            label='Then', choices=[], widget=forms.Select, required=True)
        flows = self.question.flows.all()
        [f.next_question.pk for f in flows if f.next_question]
        next_q_choices = [(q.pk, q.text) for q in batch.questions_inline(
        ) if q.pk is not self.question.pk]
        # and q.pk not in existing_nexts]
        next_q_choices.extend([(q.pk, q.text)
                               for q in batch.zombie_questions()])
        self.fields['next_question'] = forms.ChoiceField(
            label='', choices=next_q_choices, widget=forms.Select, required=False)
        #self.fields['next_question'].widget.attrs['class'] = 'chzn-select'
        self.fields['action'].choices = self.ACTIONS.items()

        data.get('action', None) if data else None
Exemplo n.º 4
0
 def __init__(self, *args, **kwargs):
     super(AnswerForm, self).__init__(*args, **kwargs)
     # self.fields['uid'] = forms.CharField(initial=access.user_identifier, widget=forms.HiddenInput)
     if question.answer_type == DateAnswer.choice_name():
         self.fields['value'] = forms.DateField(
             label='Answer',
             input_formats=[
                 settings.DATE_FORMAT,
             ],
             widget=forms.DateInput(attrs={
                 'placeholder': 'Answer',
                 'class': 'datepicker'
             },
                                    format=settings.DATE_FORMAT))
     if question.answer_type == GeopointAnswer.choice_name():
         model_field = get_form_field_no_validation(forms.CharField)
         self.fields['value'] = model_field(
             label='Answer',
             widget=forms.TextInput(
                 attrs={
                     'placeholder':
                     'Lat[space4]Long[space4'
                     'Altitude[space4]Precision'
                 }))
     if question.answer_type == MultiChoiceAnswer.choice_name():
         self.fields['value'] = forms.ChoiceField(
             choices=[(opt.order, opt.text)
                      for opt in question.options.all()],
             widget=forms.RadioSelect)
         self.fields['value'].empty_label = None
     if access.choice_name() == USSDAccess.choice_name():
         self.fields['value'].widget = forms.NumberInput()
     if question.answer_type == MultiSelectAnswer.choice_name():
         self.fields['value'] = forms.ModelMultipleChoiceField(
             queryset=question.options.all(),
             widget=forms.CheckboxSelectMultiple)
     accept_types = {
         AudioAnswer.choice_name(): 'audio/*',
         VideoAnswer.choice_name(): 'video/*',
         ImageAnswer.choice_name(): 'image/*'
     }
     if question.answer_type in [
             AudioAnswer.choice_name(),
             VideoAnswer.choice_name(),
             ImageAnswer.choice_name()
     ]:
         self.fields['value'].widget.attrs = {
             'accept':
             accept_types.get(question.answer_type,
                              '|'.join(accept_types.values()))
         }
     if access.choice_name() == USSDAccess.choice_name():
         self.fields['value'].label = ''
     else:
         self.fields['value'].label = 'Answer'
Exemplo n.º 5
0
 def _create_test_non_group_questions(self, qset):
     # Basically create questions for this question set which is not having groups
     self._create_ussd_non_group_questions(qset)
     # Multiselect questions
     data = {
         'answer_type': MultiSelectAnswer.choice_name(),
         'text': 'multi select answer text',
         'identifier':
         'multi2_select_identifier_%s' % random.randint(1, 100),
         'qset': qset.id,
         'options': ['Y', 'N', 'MB']
     }
     self._save_question(qset, data)
     # Date answer
     data = {
         'answer_type': DateAnswer.choice_name(),
         'text': 'date answer text',
         'identifier': 'date2_identifier_%s' % random.randint(1, 100),
         'qset': qset.id,
     }
     self._save_question(qset, data)
     # Geopoint answer
     data = {
         'answer_type': GeopointAnswer.choice_name(),
         'text': 'geo point text',
         'identifier': 'geo2_identifier_%s' % random.randint(1, 100),
         'qset': qset.id
     }
     self._save_question(qset, data)
     # Image answer
     data = {
         'answer_type': ImageAnswer.choice_name(),
         'text': 'image answer text',
         'identifier': 'image2_identifier_%s' % random.randint(1, 100),
         'qset': qset.id
     }
     self._save_question(qset, data)
     # Audio answer
     data = {
         'answer_type': AudioAnswer.choice_name(),
         'text': 'audio answer text',
         'identifier': 'audio2_identifier_%s' % random.randint(1, 100),
         'qset': qset.id
     }
     self._save_question(qset, data)
     # Video answer
     data = {
         'answer_type': VideoAnswer.choice_name(),
         'text': 'video answer text',
         'identifier': 'video2_identifier_%s' % random.randint(1, 100),
         'qset': qset.id
     }
     self._save_question(qset, data)
     self.qset.refresh_from_db()
Exemplo n.º 6
0
 def _create_test_non_group_questions(self, qset):
     # Basically create questions for this question set which is not having groups
     self._create_ussd_non_group_questions(qset)
     # Multiselect questions
     data = {
         'answer_type': MultiSelectAnswer.choice_name(),
         'text': 'multi select answer text',
         'identifier': 'multi2_select_identifier_%s' % random.randint(1, 100),
         'qset': qset.id,
         'options': ['Y', 'N', 'MB']
     }
     self._save_question(qset, data)
     # Date answer
     data = {
         'answer_type': DateAnswer.choice_name(),
         'text': 'date answer text',
         'identifier': 'date2_identifier_%s' % random.randint(1, 100),
         'qset': qset.id,
     }
     self._save_question(qset, data)
     # Geopoint answer
     data = {
         'answer_type': GeopointAnswer.choice_name(),
         'text': 'geo point text',
         'identifier': 'geo2_identifier_%s' % random.randint(1, 100),
         'qset': qset.id
     }
     self._save_question(qset, data)
     # Image answer
     data = {
         'answer_type': ImageAnswer.choice_name(),
         'text': 'image answer text',
         'identifier': 'image2_identifier_%s' % random.randint(1, 100),
         'qset': qset.id
     }
     self._save_question(qset, data)
     # Audio answer
     data = {
         'answer_type': AudioAnswer.choice_name(),
         'text': 'audio answer text',
         'identifier': 'audio2_identifier_%s' % random.randint(1, 100),
         'qset': qset.id
     }
     self._save_question(qset, data)
     # Video answer
     data = {
         'answer_type': VideoAnswer.choice_name(),
         'text': 'video answer text',
         'identifier': 'video2_identifier_%s' % random.randint(1, 100),
         'qset': qset.id
     }
     self._save_question(qset, data)
     self.qset.refresh_from_db()
Exemplo n.º 7
0
 def test_answer_value_methods(self):
     value = 'me doing somthing'
     test_answer1 = 'nothing good'
     self.assertFalse(Answer.equals(test_answer1, value))
     self.assertTrue(Answer.equals(value, value))
     self.assertTrue(Answer.starts_with(value, 'me d'))
     self.assertFalse(Answer.ends_with(value, 'no thing'))
     self.assertTrue(Answer.ends_with(value, 'somthing'))
     self.assertFalse(Answer.greater_than(5, 9))
     self.assertTrue(Answer.greater_than(9, 5))
     self.assertTrue(Answer.less_than(5, 9))
     self.assertFalse(Answer.less_than(9, 5))
     self.assertFalse(Answer.between(9, 5, 7))
     self.assertTrue(Answer.between(9, 5, 11))
     self.assertTrue(Answer.passes_test('17 > 10'))
     self.assertFalse(NumericalAnswer.greater_than(5, 9))
     self.assertTrue(NumericalAnswer.greater_than(9, 5))
     self.assertTrue(NumericalAnswer.less_than(5, 9))
     self.assertFalse(NumericalAnswer.less_than(9, 5))
     self.assertFalse(NumericalAnswer.between(9, 5, 7))
     self.assertTrue(NumericalAnswer.between(9, 5, 11))
     self.assertFalse(TextAnswer.equals(test_answer1, value))
     self.assertTrue(TextAnswer.equals(value, value))
     self.assertFalse(MultiChoiceAnswer.equals(test_answer1, value))
     self.assertTrue(MultiChoiceAnswer.equals(value, value))
     self.assertFalse(MultiSelectAnswer.equals(test_answer1, value))
     self.assertTrue(MultiSelectAnswer.equals(value, value))
     self.assertFalse(DateAnswer.greater_than('12-09-2017', '12-09-2017'))
     self.assertTrue(DateAnswer.greater_than('13-09-2017', '12-09-2017'))
     self.assertFalse(DateAnswer.less_than('18-09-2017', '12-09-2017'))
     self.assertTrue(DateAnswer.less_than('13-09-2017', '17-09-2017'))
     self.assertFalse(
         DateAnswer.between('18-09-2017', '12-09-2017', '16-09-2017'))
     self.assertTrue(
         DateAnswer.between('14-09-2017', '12-09-2017', '16-09-2017'))
Exemplo n.º 8
0
 def __init__(self, *args, **kwargs):
     super(AnswerForm, self).__init__(*args, **kwargs)
     # self.fields['uid'] = forms.CharField(initial=access.user_identifier, widget=forms.HiddenInput)
     if question.answer_type == DateAnswer.choice_name():
         self.fields['value'] = forms.DateField(
             label='Answer',
             input_formats=[
                 settings.DATE_FORMAT,
             ],
             widget=forms.DateInput(
                 attrs={
                     'placeholder': 'Answer',
                     'class': 'datepicker'},
                 format=settings.DATE_FORMAT))
     if question.answer_type == GeopointAnswer.choice_name():
         model_field = get_form_field_no_validation(forms.CharField)
         self.fields['value'] = model_field(label='Answer', widget=forms.TextInput(
             attrs={'placeholder': 'Lat[space4]Long[space4' 'Altitude[space4]Precision'}))
     if question.answer_type == MultiChoiceAnswer.choice_name():
         self.fields['value'] = forms.ChoiceField(choices=[(opt.order, opt.text) for opt
                                                           in question.options.all()], widget=forms.RadioSelect)
         self.fields['value'].empty_label = None
     if access.choice_name() == USSDAccess.choice_name():
         self.fields['value'].widget = forms.NumberInput()
     if question.answer_type == MultiSelectAnswer.choice_name():
         self.fields['value'] = forms.ModelMultipleChoiceField(
             queryset=question.options.all(), widget=forms.CheckboxSelectMultiple)
     accept_types = {AudioAnswer.choice_name(): 'audio/*',
                     VideoAnswer.choice_name(): 'video/*',
                     ImageAnswer.choice_name(): 'image/*'
                     }
     if question.answer_type in [
             AudioAnswer.choice_name(),
             VideoAnswer.choice_name(),
             ImageAnswer.choice_name()]:
         self.fields['value'].widget.attrs = {
             'accept': accept_types.get(
                 question.answer_type, '|'.join(
                     accept_types.values()))}
     if access.choice_name() == USSDAccess.choice_name():
         self.fields['value'].label = ''
     else:
         self.fields['value'].label = 'Answer'
Exemplo n.º 9
0
 def test_odk_answer_methods(self):
     # test odk contain
     path = '/qset/qset1/surveyQuestions/q1'
     value = 'me doing somthing'
     self.assertEquals(Answer.odk_contains(path, value),
                       "regex(%s, '.*(%s).*')" % (path, value))
     self.assertEquals(Answer.odk_starts_with(path, value),
                       "regex(%s, '^(%s).*')" % (path, value))
     self.assertEquals(Answer.odk_ends_with(path, value),
                       "regex(%s, '.*(%s)$')" % (path, value))
     value = 4
     upperlmt = 10
     self.assertEquals(Answer.odk_greater_than(path, value),
                       "%s > '%s'" % (path, value))
     self.assertEquals(Answer.odk_less_than(path, value),
                       "%s < '%s'" % (path, value))
     self.assertEquals(
         Answer.odk_between(path, value, upperlmt),
         "(%s > '%s') and (%s <= '%s')" %
         (path, value, path, upperlmt))
     self.assertEquals(NumericalAnswer.odk_less_than(path, value),
                       "%s < %s" % (path, value))
     self.assertEquals(
         NumericalAnswer.odk_between(path, value, upperlmt),
         "(%s > %s) and (%s <= %s)" % (path, value, path, upperlmt))
     value = '20-07-2017'
     self.assertEquals(DateAnswer.odk_greater_than(path, value),
                       "%s > %s" % (path, DateAnswer.to_odk_date(value)))
     self.assertEquals(DateAnswer.odk_less_than(path, value),
                       "%s < %s" % (path, DateAnswer.to_odk_date(value)))
     upperlmt = '25-08-2017'
     self.assertEquals(
         DateAnswer.odk_between(path, value, upperlmt),
         "(%s > %s) and (%s <= %s)" %
         (path, DateAnswer.to_odk_date(value), path,
          DateAnswer.to_odk_date(upperlmt)))
Exemplo n.º 10
0
    def __init__(self, initial=None, question=None, *args, **kwargs):
        super(LogicForm, self).__init__(initial=initial, *args, **kwargs)
        data = kwargs.get('data', None)
        batch = question.batch
        self.question = question
        self.batch = batch
        self.fields['condition'] = forms.ChoiceField(
            label='Eligibility criteria',
            choices=[],
            widget=forms.Select,
            required=False)
        self.fields['attribute'] = forms.ChoiceField(label='Attribute',
                                                     choices=[
                                                         ('value', 'Value'),
                                                     ],
                                                     widget=forms.Select,
                                                     required=False)
        self.fields['condition'].choices = [(validator.__name__, validator.__name__.upper()) \
                                           for validator in Answer.get_class(question.answer_type).validators()]
        if question.answer_type in [
                MultiChoiceAnswer.choice_name(),
                MultiSelectAnswer.choice_name()
        ]:
            self.fields['option'] = forms.ChoiceField(label='',
                                                      choices=[],
                                                      widget=forms.Select,
                                                      required=True)
            self.fields['option'].choices = [
                (option.order, option.text)
                for option in question.options.all()
            ]
        else:
            self.fields['value'] = forms.CharField(label='', required=False)
            self.fields['min_value'] = forms.CharField(
                label='',
                required=False,
                widget=forms.TextInput(attrs={'placeholder': 'Min Value'}))
            self.fields['max_value'] = forms.CharField(
                label='',
                required=False,
                widget=forms.TextInput(attrs={'placeholder': 'Max Value'}))
            if question.answer_type == DateAnswer.choice_name():
                self.fields['value'].widget.attrs['class'] = 'datepicker'
                self.fields['min_value'].widget.attrs['class'] = 'datepicker'
                self.fields['max_value'].widget.attrs['class'] = 'datepicker'
            # validate_with_question = forms.ChoiceField(label='', choices=[], widget=forms.Select, required=False)
        self.fields['action'] = forms.ChoiceField(label='Then',
                                                  choices=[],
                                                  widget=forms.Select,
                                                  required=True)
        flows = self.question.flows.all()
        existing_nexts = [f.next_question.pk for f in flows if f.next_question]
        next_q_choices = [(q.pk, q.text) for q in batch.questions_inline()
                          if q.pk is not self.question.pk]
        # and q.pk not in existing_nexts]
        next_q_choices.extend([(q.pk, q.text)
                               for q in batch.zombie_questions()])
        self.fields['next_question'] = forms.ChoiceField(
            label='',
            choices=next_q_choices,
            widget=forms.Select,
            required=False)
        self.fields['next_question'].widget.attrs['class'] = 'chzn-select'
        self.fields['action'].choices = self.ACTIONS.items()

        action_sent = data.get('action', None) if data else None
Exemplo n.º 11
0
    def handle(self, *args, **kwargs):
        self.stdout.write('Creating permissions....')
        content_type = ContentType.objects.get_for_model(User)
        Permission.objects.get_or_create(codename='can_enter_data', name='Can enter data', content_type=content_type)
        Permission.objects.get_or_create(codename='can_view_batches', name='Can view Batches', content_type=content_type)
        Permission.objects.get_or_create(codename='can_view_interviewers', name='Can view Interviewers', content_type=content_type)
        Permission.objects.get_or_create(codename='can_view_aggregates', name='Can view Aggregates', content_type=content_type)
        Permission.objects.get_or_create(codename='view_completed_survey', name='Can view Completed Surveys', content_type=content_type)
        Permission.objects.get_or_create(codename='can_view_households', name='Can view Households', content_type=content_type)
        Permission.objects.get_or_create(codename='can_view_locations', name='Can view Locations', content_type=content_type)
        Permission.objects.get_or_create(codename='can_view_users', name='Can view Users', content_type=content_type)
        Permission.objects.get_or_create(codename='can_view_household_groups', name='Can view Household Groups', content_type=content_type)

        self.stdout.write('Permissions.')
        self.stdout.write('Creating answer definition... ')
        #ussd definition
        AnswerAccessDefinition.objects.get_or_create(channel=USSDAccess.choice_name(),
                                                     answer_type=NumericalAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=USSDAccess.choice_name(),
                                                     answer_type=TextAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=USSDAccess.choice_name(),
                                                     answer_type=MultiChoiceAnswer.choice_name())

        #ODK definition
        AnswerAccessDefinition.objects.get_or_create(channel=ODKAccess.choice_name(),
                                                     answer_type=NumericalAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=ODKAccess.choice_name(),
                                                     answer_type=TextAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=ODKAccess.choice_name(),
                                                     answer_type=MultiChoiceAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=ODKAccess.choice_name(),
                                                     answer_type=MultiSelectAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=ODKAccess.choice_name(),
                                                     answer_type=ImageAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=ODKAccess.choice_name(),
                                                     answer_type=GeopointAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=ODKAccess.choice_name(),
                                                     answer_type=DateAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=ODKAccess.choice_name(),
                                                     answer_type=AudioAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=ODKAccess.choice_name(),
                                                     answer_type=VideoAnswer.choice_name())

        #web form definition
        AnswerAccessDefinition.objects.get_or_create(channel=WebAccess.choice_name(),
                                                     answer_type=NumericalAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=WebAccess.choice_name(),
                                                     answer_type=TextAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=WebAccess.choice_name(),
                                                     answer_type=MultiChoiceAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=WebAccess.choice_name(),
                                                     answer_type=MultiSelectAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=WebAccess.choice_name(),
                                                     answer_type=ImageAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=WebAccess.choice_name(),
                                                     answer_type=GeopointAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=WebAccess.choice_name(),
                                                     answer_type=DateAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=WebAccess.choice_name(),
                                                     answer_type=AudioAnswer.choice_name())
        AnswerAccessDefinition.objects.get_or_create(channel=WebAccess.choice_name(),
                                                     answer_type=VideoAnswer.choice_name())
        self.stdout.write('Successfully imported!')
 def test_end_interview_selection_in_form_question_creates_flow_to_with_no_next_question(
         self):
     '''
     :return:
     '''
     yes = 'yes'
     no = 'no'
     q1 = Question.objects.create(qset_id=self.qset.id,
                                  response_validation_id=1,
                                  identifier='test1',
                                  text='test1',
                                  answer_type=DateAnswer.choice_name())
     q2 = Question.objects.create(
         qset_id=self.qset.id,
         response_validation_id=1,
         identifier='test2',
         text='test2',
         answer_type=MultiChoiceAnswer.choice_name())
     q_o1 = QuestionOption.objects.create(question_id=q2.id,
                                          text=yes,
                                          order=1)
     QuestionOption.objects.create(question_id=q2.id, text=no, order=2)
     q3 = Question.objects.create(qset_id=self.qset.id,
                                  response_validation_id=1,
                                  identifier='test3',
                                  text='test3',
                                  answer_type=DateAnswer.choice_name())
     q4 = Question.objects.create(qset_id=self.qset.id,
                                  response_validation_id=1,
                                  identifier='test4',
                                  text='test4',
                                  answer_type=DateAnswer.choice_name())
     q5 = Question.objects.create(qset_id=self.qset.id,
                                  response_validation_id=1,
                                  identifier='test5',
                                  text='test5',
                                  answer_type=DateAnswer.choice_name())
     self.batch.start_question = q1
     QuestionFlow.objects.create(question_id=q1.id, next_question_id=q2.id)
     QuestionFlow.objects.create(question_id=q2.id, next_question_id=q3.id)
     QuestionFlow.objects.create(question_id=q3.id, next_question_id=q4.id)
     QuestionFlow.objects.create(question_id=q4.id, next_question_id=q5.id)
     test_condition = MultiChoiceAnswer.validators()[0].__name__
     form_data = {
         'action': LogicForm.END_INTERVIEW,
         'condition': test_condition,
         'option': q_o1.order
     }
     l = LogicForm(q2, data=form_data)
     if l.is_valid():
         l.save()
         # now check if equivalent Question flow and test arguments were
         # created
         try:
             qf = QuestionFlow.objects.get(question_id=q2.id,
                                           next_question_id__isnull=True)
             TextArgument.objects.get(flow=qf, position=0, param=q_o1.order)
             QuestionFlow.objects.get(question_id=q1.id,
                                      next_question_id=q2.id)
             QuestionFlow.objects.get(question_id=q2.id,
                                      next_question_id=q3.id)
             self.assertTrue(True)
             return
         except QuestionFlow.DoesNotExist:
             self.assertTrue(False, 'flow not existing')
             pass
         except TextArgument:
             self.assertTrue(False, 'text agrunments not saved')
             pass
     else:
         self.assertFalse(False, 'Invalid form')
 def test_specify_wrong_min_value_gives_form_error(self):
     '''
     :return:
     '''
     q1 = Question.objects.create(qset_id=self.qset.id,
                                  response_validation_id=1,
                                  identifier='test1',
                                  text='test1',
                                  answer_type=DateAnswer.choice_name())
     q2 = Question.objects.create(qset_id=self.qset.id,
                                  response_validation_id=1,
                                  identifier='test2',
                                  text='test2',
                                  answer_type=DateAnswer.choice_name())
     q3 = Question.objects.create(qset_id=self.qset.id,
                                  response_validation_id=1,
                                  identifier='test3',
                                  text='test3',
                                  answer_type=DateAnswer.choice_name())
     q4 = Question.objects.create(qset_id=self.qset.id,
                                  response_validation_id=1,
                                  identifier='test4',
                                  text='test4',
                                  answer_type=DateAnswer.choice_name())
     q5 = Question.objects.create(qset_id=self.qset.id,
                                  response_validation_id=1,
                                  identifier='test5',
                                  text='test5',
                                  answer_type=DateAnswer.choice_name())
     self.batch.start_question = q1
     QuestionFlow.objects.create(question_id=q1.id, next_question_id=q2.id)
     QuestionFlow.objects.create(question_id=q2.id, next_question_id=q3.id)
     QuestionFlow.objects.create(question_id=q3.id, next_question_id=q4.id)
     QuestionFlow.objects.create(question_id=q4.id, next_question_id=q5.id)
     test_condition = 'between'
     test_param_upper = datetime.now()
     test_param_lower = 'some time ago'
     form_data = {
         'action': LogicForm.REANSWER,
         'condition': test_condition,
         'min_value': test_param_lower,
         'max_value': test_param_upper
     }
     l = LogicForm(q2, data=form_data)
     if l.is_valid():
         l.save()
         # now check if equivalent Question flow and test arguments were
         # created
         try:
             qf = QuestionFlow.objects.get(question_id=q2.id,
                                           next_question_id=q2.id)
             TextArgument.objects.get(flow=qf,
                                      position=0,
                                      param=test_param_lower)
             TextArgument.objects.create(flow=qf,
                                         position=1,
                                         param=test_param_upper)
             QuestionFlow.objects.get(question_id=q1.id,
                                      next_question_id=q2.id)
             QuestionFlow.objects.get(question_id=q2.id,
                                      next_question_id=q3.id)
             self.assertTrue(
                 False, 'completely wrong. bad values was saved as good!!')
             return
         except QuestionFlow.DoesNotExist:
             self.assertTrue(False, 'form valid flow not existing')
             pass
         except TextArgument:
             self.assertTrue(False,
                             'Form valid but text agrunments not saved')
             pass
     else:
         self.assertTrue(True)
Exemplo n.º 14
0
 def test_fetch_methods(self):
     qset = self.qset
     self._create_test_non_group_questions(qset)
     date_question = Question.objects.filter(answer_type=DateAnswer.choice_name()).first()
     smallest = '2017-01-20'
     medium = '2017-05-12'
     largest = '2017-10-20'
     answer1 = DateAnswer.create(self.interview, date_question, medium)
     answer2 = DateAnswer.create(self.interview, date_question, smallest)
     answer3 = DateAnswer.create(self.interview, date_question, largest)
     self.assertEquals(DateAnswer.fetch_greater_than('as_value',
                                                     '2017-01-21').filter(as_text__in=[medium, largest]).count(), 2)
     self.assertEquals(DateAnswer.fetch_less_than('as_value', '2017-01-21').count(), 1)
     self.assertEquals(DateAnswer.fetch_less_than('as_value', '2017-01-21').first().as_text, smallest)
     fetched_inbetween = DateAnswer.fetch_between('as_value', '2017-01-21', '2017-05-13')
     self.assertEquals(fetched_inbetween.count(), 1)
     self.assertEquals(fetched_inbetween.first().as_text, medium)
     fetched_inbetween = DateAnswer.fetch_between('as_value', '2017-01-21', '2017-05-13')
     self.assertEquals(fetched_inbetween.count(), 1)
     self.assertEquals(fetched_inbetween.first().as_text, medium)
     self.assertEquals(DateAnswer.fetch_equals('as_value', medium).count(), 1)
     self.assertEquals(DateAnswer.fetch_equals('as_value', medium).first().as_text, medium)
     # check answers attribute is date class
     date_question = Question.objects.filter(answer_type=DateAnswer.choice_name()).first()
     self.assertEquals(date_question.answers().first().__class__, DateAnswer)
Exemplo n.º 15
0
 def test_answer_validators(self):
     validators = [                  # supported validators
         'starts_with',
         'ends_with',
         'equals',
         'between',
         'less_than',
         'greater_than',
         'contains',
     ]
     for func in Answer.validators():
         self.assertIn(func.__name__, validators)
     # test Numeric Answer Validators
     validators = [                  # supported validators
         'equals',
         'between',
         'less_than',
         'greater_than',
     ]
     for func in NumericalAnswer.validators():
         self.assertIn(func.__name__, validators)
     # test Text Answer Validators
     validators = [                  # supported validators
         'starts_with',
         'ends_with',
         'equals',
         'contains',
     ]
     for func in TextAnswer.validators():
         self.assertIn(func.__name__, validators)
     # Multichoice
     validators = [                  # supported validators
         'equals',
     ]
     for func in MultiChoiceAnswer.validators():
         self.assertIn(func.__name__, validators)
     # test Multiselect Answer Validators
     validators = [                  # supported validators
         'equals',
         'contains',
     ]
     for func in MultiSelectAnswer.validators():
         self.assertIn(func.__name__, validators)
     # test Date Answer Validators
     validators = [                  # supported validators
         'equals',
         'between',
         'less_than',
         'greater_than',
     ]
     for func in DateAnswer.validators():
         self.assertIn(func.__name__, validators)
     # GeoPoint Answer
     validators = [  # supported validators
         'equals',
     ]
     for func in GeopointAnswer.validators():
         self.assertIn(func.__name__, validators)
     # file answers should return no validators
     for answer_class in [VideoAnswer, AudioAnswer, ImageAnswer]:
         self.assertEquals(len(answer_class.validators()), 0)
    def test_reanswer_selection_in_form_question_creates_flow_to_same_question(
            self):
        '''

        :return:
        '''
        q1 = Question.objects.create(qset_id=self.qset.id,
                                     response_validation_id=1,
                                     identifier='test1',
                                     text='test1',
                                     answer_type=DateAnswer.choice_name())
        q2 = Question.objects.create(qset_id=self.qset.id,
                                     response_validation_id=1,
                                     identifier='test2',
                                     text='test2',
                                     answer_type=DateAnswer.choice_name())
        q3 = Question.objects.create(qset_id=self.qset.id,
                                     response_validation_id=1,
                                     identifier='test3',
                                     text='test3',
                                     answer_type=DateAnswer.choice_name())
        q4 = Question.objects.create(qset_id=self.qset.id,
                                     response_validation_id=1,
                                     identifier='test4',
                                     text='test4',
                                     answer_type=DateAnswer.choice_name())
        q5 = Question.objects.create(qset_id=self.qset.id,
                                     response_validation_id=1,
                                     identifier='test5',
                                     text='test5',
                                     answer_type=DateAnswer.choice_name())
        self.batch.start_question = q1
        QuestionFlow.objects.create(question_id=q1.id, next_question_id=q2.id)
        QuestionFlow.objects.create(question_id=q2.id, next_question_id=q3.id)
        QuestionFlow.objects.create(question_id=q3.id, next_question_id=q4.id)
        QuestionFlow.objects.create(question_id=q4.id, next_question_id=q5.id)
        test_condition = 'between'
        test_param_upper = datetime.now()
        test_param_lower = datetime.now() - timedelta(days=3)
        form_data = {
            'action': LogicForm.REANSWER,
            'condition': test_condition,
            'min_value': test_param_lower,
            'max_value': test_param_upper
        }
        l = LogicForm(q2, data=form_data)
        if l.is_valid():
            l.save()
            # now check if equivalent Question flow and test arguments were
            # created
            try:
                qf = QuestionFlow.objects.get(question_id=q2.id,
                                              next_question_id=q2.id)
                TextArgument.objects.get(flow=qf,
                                         position=0,
                                         param=test_param_lower)
                TextArgument.objects.create(flow=qf,
                                            position=1,
                                            param=test_param_upper)
                QuestionFlow.objects.get(question_id=q1.id,
                                         next_question_id=q2.id)
                QuestionFlow.objects.get(question_id=q2.id,
                                         next_question_id=q3.id)
                self.assertTrue(True)
                return
            except QuestionFlow.DoesNotExist:
                self.assertFalse(False, 'flow not existing')
                pass
            except TextArgument:
                self.assertTrue(False, 'text agrunments not saved')
                pass
        else:
            self.assertTrue(False, 'Invalid form')
Exemplo n.º 17
0
 def test_fetch_methods(self):
     qset = self.qset
     self._create_test_non_group_questions(qset)
     date_question = Question.objects.filter(
         answer_type=DateAnswer.choice_name()).first()
     smallest = '2017-01-20'
     medium = '2017-05-12'
     largest = '2017-10-20'
     answer1 = DateAnswer.create(self.interview, date_question, medium)
     answer2 = DateAnswer.create(self.interview, date_question, smallest)
     answer3 = DateAnswer.create(self.interview, date_question, largest)
     self.assertEquals(
         DateAnswer.fetch_greater_than(
             'as_value',
             '2017-01-21').filter(as_text__in=[medium, largest]).count(), 2)
     self.assertEquals(
         DateAnswer.fetch_less_than('as_value', '2017-01-21').count(), 1)
     self.assertEquals(
         DateAnswer.fetch_less_than('as_value',
                                    '2017-01-21').first().as_text, smallest)
     fetched_inbetween = DateAnswer.fetch_between('as_value', '2017-01-21',
                                                  '2017-05-13')
     self.assertEquals(fetched_inbetween.count(), 1)
     self.assertEquals(fetched_inbetween.first().as_text, medium)
     fetched_inbetween = DateAnswer.fetch_between('as_value', '2017-01-21',
                                                  '2017-05-13')
     self.assertEquals(fetched_inbetween.count(), 1)
     self.assertEquals(fetched_inbetween.first().as_text, medium)
     self.assertEquals(
         DateAnswer.fetch_equals('as_value', medium).count(), 1)
     self.assertEquals(
         DateAnswer.fetch_equals('as_value', medium).first().as_text,
         medium)
     # check answers attribute is date class
     date_question = Question.objects.filter(
         answer_type=DateAnswer.choice_name()).first()
     self.assertEquals(date_question.answers().first().__class__,
                       DateAnswer)
Exemplo n.º 18
0
    class QuestionForm(ModelForm, FormOrderMixin):
        VALIDATION_ANSWER_TYPES = [DateAnswer.choice_name(), TextAnswer.choice_name(),
                                   NumericalAnswer.choice_name(), AutoResponse.choice_name()]
        options = forms.CharField(max_length=50, widget=forms.HiddenInput(), required=False)
        response_validation = ValidationField(queryset=ResponseValidation.objects.all(), required=False)

        def __init__(
                self,
                qset,
                data=None,
                initial=None,
                parent_question=None,
                instance=None,
                prev_question=None):
            super(QuestionForm, self).__init__(
                data=data, initial=initial, instance=instance)
            self.fields['identifier'].label = "Variable name"
            self.fields['qset'].widget = forms.HiddenInput()
            self.fields['qset'].initial = qset.pk
            self.qset = qset
            self.prev_question = prev_question
            # depending on type of ussd/odk access of qset restrict the answer
            # type
            self.fields['answer_type'].choices = [
                choice for choice in self.fields['answer_type'].choices if choice[0] in qset.answer_types]
            self.fields['answer_type'].choices.insert(
                0, ('', '----Select Answer Type----'))
            if instance:
                self.help_text = ' and '.join(AnswerAccessDefinition.access_channels(instance.answer_type))
                self.fields['answer_type'].help_text = self.help_text
            self.answer_map = {}
            definitions = AnswerAccessDefinition.objects.all()
            for defi in definitions:
                self.answer_map[defi.answer_type] = self.answer_map.get(defi.answer_type, [])
                self.answer_map[defi.answer_type].append(defi.channel)
            self.fields['response_validation'].icons = {'add': {'data-toggle': "modal",
                                                                 'data-target': "#add_validation",
                                                                 'id': 'add_validation_button',
                                                                 'title': 'Add Validation'},
                                                        }
            self.parent_question = parent_question
            self.order_fields(['module', 'group', 'identifier',
                               'text', 'answer_type', 'mandatory'])

        class Meta:
            model = model_class
            exclude = []
            widgets = {
                'text': forms.Textarea(
                    attrs={
                        "rows": 5,
                        "cols": 30,
                        "maxlength": "150",
                    }),
            }

        def clean_group(self):
            group = self.cleaned_data['group']
            if group:
                qset = QuestionSet.get(id=self.qset.pk)
                identifiers = group.parameter_questions().values_list('identifier', flat=True)
                existing_identifiers = Question.objects.filter(identifier__in=identifiers,
                                                               qset__pk=self.qset.pk).values_list('identifier',
                                                                                                  flat=True)
                if existing_identifiers.exists():
                    raise ValidationError(
                        '%s already exist in this %s. '
                        'Consider creating a question with modified identifier name and using skip logic in your %s' %
                        (','.join(existing_identifiers), qset.verbose_name(), qset.verbose_name()))
                if hasattr(qset, 'survey') and qset.survey.listing_form:
                    existing_identifiers = qset.survey.listing_form.questions.filter(identifier__in=identifiers
                                                                                     ).values_list('identifier',
                                                                                                   flat=True)
                    if existing_identifiers.exists():
                        raise ValidationError(
                            '%s already exist as a listing question for this %s. '
                            'Consider creating a question with modified identifier name '
                            'and using skip logic in your %s' %
                            (','.join(existing_identifiers), qset.verbose_name(), qset.verbose_name()))
            return group

        def clean_options(self):
            options = dict(self.data).get('options')
            if options:
                options = filter(lambda text: text.strip(), options)
                # options = map(lambda option: re.sub("[%s]" % settings.USSD_IGNORED_CHARACTERS, '', option), options)
                options = map(
                    lambda option: re.sub(
                        "  ", ' ', option), options)
                options = map(lambda option: option.strip(), options)
                self.cleaned_data['options'] = options
            return options

        def clean_identifier(self):
            identifier = self.cleaned_data['identifier']
            pattern = '^[a-zA-Z][0-9a-zA-Z_]+$'
            if re.match(pattern, identifier) is None:
                raise ValidationError(
                    'Identifier must start with a letter, and must contain alphanumeric values or _')
            if Question.objects.filter(
                    identifier__iexact=identifier,
                    qset__pk=self.qset.pk).exists():
                if self.instance and self.instance.identifier == identifier:
                    pass
                else:
                    raise ValidationError(
                        '%s already in use for this %s' %
                        (identifier, model_class.type_name()))
            # if this is a batch question also check if there are parameter
            # questions with this name
            qset = QuestionSet.get(id=self.qset.pk)
            if hasattr(
                    qset,
                    'parameter_list') and qset.parameter_list and qset.parameter_list.parameters.filter(
                    identifier__iexact=identifier).exists():
                raise ValidationError(
                    '%s is already in captured as a group parameter for this %s' %
                    (identifier, qset.verbose_name()))
            # for sampled surveys, check if this is already implemented in listing
            if hasattr(qset, 'survey') and qset.survey.listing_form and qset.survey.listing_form.questions.filter(
                    identifier__iexact=identifier).exists():
                raise ValidationError(
                    '%s is already in captured as a listing question for this %s' %
                    (identifier, qset.verbose_name()))
            return self.cleaned_data['identifier']

        def clean_text(self):
            """Make sure any field referenced here belongs to same batch. Field refs are denoted by {{.+}} brackets
            :return:
            """
            pattern = '{{ *([0-9a-zA-Z_]+) *}}'
            label = self.data.get('text', '')
            requested_identifiers = re.findall(pattern, label)
            if requested_identifiers:
                ids = self.qset.questions.filter(
                    identifier__in=requested_identifiers).values_list(
                    'identifier', flat=True)
                ids = list(ids)
                if len(set(ids)) != len(set(requested_identifiers)):
                    raise ValidationError(
                        '%s is not in %s' %
                        (', '.join(
                            set(requested_identifiers).difference(ids)),
                            self.qset.name))
            return self.cleaned_data['text']

        def clean(self):
            answer_type = self.cleaned_data.get('answer_type', None)
            options = self.cleaned_data.get('options', None)
            response_validation = self.cleaned_data.get('response_validation', None)
            text = self.cleaned_data.get('text', None)
            self._check__multichoice_and_options_compatibility(
                answer_type, options)
            self._strip_special_characters_for_ussd(text)
            if answer_type:
                answer_class = Answer.get_class(answer_type)
                validator_names = [validator.__name__ for validator in answer_class.validators()]
                if response_validation and response_validation.validation_test not in validator_names:
                    raise ValidationError('Selected Validation is not compatible with chosen answer type')
            return self.cleaned_data

        def _check__multichoice_and_options_compatibility(
                self, answer_type, options):
            if answer_type in [
                    MultiChoiceAnswer.choice_name(),
                    MultiSelectAnswer.choice_name()] and not options:
                message = 'Question Options missing.'
                self._errors['answer_type'] = self.error_class([message])
                del self.cleaned_data['answer_type']

            if answer_type not in [
                    MultiChoiceAnswer.choice_name(),
                    MultiSelectAnswer.choice_name()] and options:
                del self.cleaned_data['options']

        def _strip_special_characters_for_ussd(self, text):
            if text:
                text = re.sub(
                    "[%s]" %
                    settings.USSD_IGNORED_CHARACTERS,
                    '',
                    text)
                self.cleaned_data['text'] = re.sub("  ", ' ', text)

        def kwargs_has_batch(self, **kwargs):
            return 'qset' in kwargs and isinstance(kwargs['qset'], Batch)

        def options_supplied(self, commit):
            return commit and self.cleaned_data.get('options', None)

        def save_question_options(self, question):
            order = 0
            options = self.cleaned_data['options']
            question.options.all().delete()
            # options.sort()
            for text in options:
                order += 1
                QuestionOption.objects.create(
                    question=question, text=text, order=order)

        def save(self, commit=True, zombie=False, **kwargs):
            question = super(QuestionForm, self).save(commit=False)
            qset = question.qset
            if commit:
                if question.pk is None:
                    question.save()
                    # get the last question inline
                    # create a inline flow with current qset
                    qset = question.qset
                    # qset = QuestionSet.get(id=qset.id)
                    if self.prev_question:
                        last_question = self.prev_question
                    else:
                        last_question = qset.last_question_inline()
                    if last_question:
                        if zombie is False:
                            # incase, inline flow with no next quest already
                            # exists
                            flow, _ = QuestionFlow.objects.get_or_create(
                                question=last_question, validation__isnull=True)
                            prev_next_question = flow.next_question
                            flow.next_question = question
                            flow.save()
                            # now connect present question back to the flow
                            QuestionFlow.objects.create(
                                question=question, next_question=prev_next_question)
                    elif qset.start_question is None:
                        qset.start_question = question
                        qset.save()
                else:
                    question.save()
                if hasattr(qset, 'survey'):     # basicallyy check for Batch scenario
                    SurveyParameterList.update_parameter_list(qset)

                # self.qset.questions_inline.invalidate()
            if self.options_supplied(commit):
                self.save_question_options(question)
            return question
Exemplo n.º 19
0
 def test_answer_validators(self):
     validators = [  # supported validators
         'starts_with',
         'ends_with',
         'equals',
         'between',
         'less_than',
         'greater_than',
         'contains',
     ]
     for func in Answer.validators():
         self.assertIn(func.__name__, validators)
     # test Numeric Answer Validators
     validators = [  # supported validators
         'equals',
         'between',
         'less_than',
         'greater_than',
     ]
     for func in NumericalAnswer.validators():
         self.assertIn(func.__name__, validators)
     # test Text Answer Validators
     validators = [  # supported validators
         'starts_with',
         'ends_with',
         'equals',
         'contains',
     ]
     for func in TextAnswer.validators():
         self.assertIn(func.__name__, validators)
     # Multichoice
     validators = [  # supported validators
         'equals',
     ]
     for func in MultiChoiceAnswer.validators():
         self.assertIn(func.__name__, validators)
     # test Multiselect Answer Validators
     validators = [  # supported validators
         'equals',
         'contains',
     ]
     for func in MultiSelectAnswer.validators():
         self.assertIn(func.__name__, validators)
     # test Date Answer Validators
     validators = [  # supported validators
         'equals',
         'between',
         'less_than',
         'greater_than',
     ]
     for func in DateAnswer.validators():
         self.assertIn(func.__name__, validators)
     # GeoPoint Answer
     validators = [  # supported validators
         'equals',
     ]
     for func in GeopointAnswer.validators():
         self.assertIn(func.__name__, validators)
     # file answers should return no validators
     for answer_class in [VideoAnswer, AudioAnswer, ImageAnswer]:
         self.assertEquals(len(answer_class.validators()), 0)
 def test_specify_wrong_min_value_gives_form_error(self):
     '''
     :return:
     '''
     q1 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                  identifier='test1',
                                  text='test1', answer_type=DateAnswer.choice_name())
     q2 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                  identifier='test2',
                                  text='test2', answer_type=DateAnswer.choice_name())
     q3 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                  identifier='test3',
                                  text='test3', answer_type=DateAnswer.choice_name())
     q4 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                  identifier='test4',
                                  text='test4', answer_type=DateAnswer.choice_name())
     q5 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1,
                                  identifier='test5',
                                  text='test5', answer_type=DateAnswer.choice_name())
     self.batch.start_question = q1
     QuestionFlow.objects.create(question_id=q1.id, next_question_id=q2.id)
     QuestionFlow.objects.create(question_id=q2.id, next_question_id=q3.id)
     QuestionFlow.objects.create(question_id=q3.id, next_question_id=q4.id)
     QuestionFlow.objects.create(question_id=q4.id, next_question_id=q5.id)
     test_condition = 'between'
     test_param_upper = datetime.now()
     test_param_lower = 'some time ago'
     form_data = {
         'action': LogicForm.REANSWER,
         'condition': test_condition,
         'min_value': test_param_lower,
         'max_value': test_param_upper
     }
     l = LogicForm(q2, data=form_data)
     if l.is_valid():
         l.save()
         # now check if equivalent Question flow and test arguments were
         # created
         try:
             qf = QuestionFlow.objects.get(
                 question_id=q2.id, next_question_id=q2.id)
             TextArgument.objects.get(
                 flow=qf, position=0, param=test_param_lower)
             TextArgument.objects.create(
                 flow=qf, position=1, param=test_param_upper)
             QuestionFlow.objects.get(
                 question_id=q1.id, next_question_id=q2.id)
             QuestionFlow.objects.get(
                 question_id=q2.id, next_question_id=q3.id)
             self.assertTrue(
                 False, 'completely wrong. bad values was saved as good!!')
             return
         except QuestionFlow.DoesNotExist:
             self.assertTrue(False, 'form valid flow not existing')
             pass
         except TextArgument:
             self.assertTrue(
                 False, 'Form valid but text agrunments not saved')
             pass
     else:
         self.assertTrue(True)