def test_update_question_order_page(self): listing_form = ListingTemplate.objects.create(name='l12', description='desc1') kwargs = {'name': 'survey11', 'description': 'survey description demo12', 'has_sampling': True, 'sample_size': 10,'listing_form_id':listing_form.id} survey_obj = Survey.objects.create(**kwargs) batch_obj = Batch.objects.create(name='b1',description='d1', survey=survey_obj) qset = QuestionSet.get(id=batch_obj.id) question1 = mommy.make(Question, qset=qset, answer_type=NumericalAnswer.choice_name()) QuestionOption.objects.create( question=question1, order=1, text="q7" ) question2 = mommy.make(Question, qset=qset, answer_type=NumericalAnswer.choice_name()) QuestionOption.objects.create( question=question1, order=4, text="q4" ) QuestionFlow.objects.create( name = 'a1', desc = 'descq', question = question2, question_type = TextAnswer.choice_name(), next_question = question1, next_question_type = TextAnswer.choice_name() ) QuestionLoop.objects.create( loop_starter = question2, loop_ender = question1 ) url = reverse('update_question_order_page', kwargs={"batch_id" : batch_obj.id}) response = self.client.post(url,data={"order_information": [batch_obj.id]}) self.assertIn(response.status_code, [200, 302])
def test_list_batches(self): survey_obj = Survey.objects.create(name="s21111", description="desc1") batch_obj = Batch.objects.create(order=1, name="b21", description='bdesc' ,survey=survey_obj) qset = QuestionSet.get(pk=batch_obj.id) question1 = mommy.make(Question, qset=qset, answer_type=TextAnswer.choice_name()) question2 = mommy.make(Question, qset=qset, answer_type=TextAnswer.choice_name()) url = reverse('list_batches') response = self.client.get(url) self.assertIn(response.status_code, [200, 302]) response = self.client.get(reverse('survey_list_page'))
def test_batch_check_name(self): survey_obj = Survey.objects.create(name="s21111", description="desc1") batch_obj = Batch.objects.create(order=1, name="b21", description='bdesc' ,survey=survey_obj) qset = QuestionSet.get(pk=batch_obj.id) question1 = mommy.make(Question, qset=qset, answer_type=TextAnswer.choice_name()) question2 = mommy.make(Question, qset=qset, answer_type=TextAnswer.choice_name()) url = reverse('check_batches_name', kwargs={"survey_id":survey_obj.id}) url = url+"?name=%s"%batch_obj.name response = self.client.get(url) self.assertIn(response.status_code, [200, 302])
def test_list_batch_questions(self): survey_obj = Survey.objects.create(name="s21111", description="desc1") batch_obj = Batch.objects.create(order=1, name="b21", description='bdesc' ,survey=survey_obj) qset = QuestionSet.get(pk=batch_obj.id) question1 = mommy.make(Question, qset=qset, answer_type=TextAnswer.choice_name()) question2 = mommy.make(Question, qset=qset, answer_type=TextAnswer.choice_name()) url = reverse('list_all_questions') url = url + "?id=%s"%batch_obj.id response = self.client.get(url, data={"id": batch_obj.id}) self.assertIn(response.status_code, [200, 302]) response = self.client.get(reverse('batch_index_page', kwargs={"survey_id" : survey_obj.id}))
def test_subquestion_selection_in_form_question_creates_branch_flow(self): ''' :return: ''' q1 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1, identifier='test1', text='test1', answer_type=TextAnswer.choice_name()) q2 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1, identifier='test2', text='test2', answer_type=TextAnswer.choice_name()) q3 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1, identifier='test3', text='test3', answer_type=TextAnswer.choice_name()) q4 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1, identifier='test4', text='test4', answer_type=TextAnswer.choice_name()) q5 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1, identifier='test5', text='test5', answer_type=TextAnswer.choice_name()) self.batch.start_question = q1 QuestionFlow.objects.create(question_id=q1.id, next_question_id=q3.id) QuestionFlow.objects.create(question_id=q3.id, next_question_id=q5.id) test_condition = TextAnswer.validators()[0].__name__ test_param = 'Hey you!!' form_data = { 'action': LogicForm.ASK_SUBQUESTION, 'next_question': q4.pk, 'condition': test_condition, 'value': test_param } l = LogicForm(q1, 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=q1.id, next_question_id=q4.id) TextArgument.objects.get(flow=qf, param=test_param) qf = QuestionFlow.objects.get( question_id=q1.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.assertTrue(False, 'Invalid form')
def setUp(self): self.client = Client() user_without_permission = User.objects.create_user( username='******', email='*****@*****.**', password='******') raj = self.assign_permission_to( User.objects.create_user('demo12', '*****@*****.**', 'demo12'), 'can_view_batches') self.listing_form = mommy.make(ListingTemplate) question1 = mommy.make(Question, qset=self.listing_form, answer_type=NumericalAnswer.choice_name()) question2 = mommy.make(Question, qset=self.listing_form, answer_type=TextAnswer.choice_name()) question3 = mommy.make(Question, qset=self.listing_form, answer_type=VideoAnswer.choice_name()) self.client.login(username='******', password='******') self.form_data = { 'name': 'survey demo12', 'description': 'survey description demo12', 'has_sampling': True, 'sample_size': 10, 'random_sample_label': 'q1 {{%s}} q2: {{%s}}' % (question1.identifier, question2.identifier) }
def test_list_batches(self): survey_obj = Survey.objects.create(name="s21111", description="desc1") batch_obj = Batch.objects.create(order=1, name="b21", description='bdesc', survey=survey_obj) qset = QuestionSet.get(pk=batch_obj.id) question1 = mommy.make(Question, qset=qset, answer_type=TextAnswer.choice_name()) question2 = mommy.make(Question, qset=qset, answer_type=TextAnswer.choice_name()) url = reverse('list_batches') response = self.client.get(url) self.assertIn(response.status_code, [200, 302]) response = self.client.get(reverse('survey_list_page'))
def test_batch_check_name(self): survey_obj = Survey.objects.create(name="s21111", description="desc1") batch_obj = Batch.objects.create(order=1, name="b21", description='bdesc', survey=survey_obj) qset = QuestionSet.get(pk=batch_obj.id) question1 = mommy.make(Question, qset=qset, answer_type=TextAnswer.choice_name()) question2 = mommy.make(Question, qset=qset, answer_type=TextAnswer.choice_name()) url = reverse('check_batches_name', kwargs={"survey_id": survey_obj.id}) url = url + "?name=%s" % batch_obj.name response = self.client.get(url) self.assertIn(response.status_code, [200, 302])
def _prep_answers(self): self._create_test_non_group_questions(self.qset) answers = [] n_quest = Question.objects.get( answer_type=NumericalAnswer.choice_name()) t_quest = Question.objects.get(answer_type=TextAnswer.choice_name()) m_quest = Question.objects.get( answer_type=MultiChoiceAnswer.choice_name()) # first is numeric, then text, then multichioice answers = [{ n_quest.id: 1, t_quest.id: 'Hey Man', m_quest.id: 'Y' }, { n_quest.id: 5, t_quest.id: 'Our Hey Boy', m_quest.id: 'Y' }, { n_quest.id: 27, t_quest.id: 'Hey Girl!', m_quest.id: 'N' }, { n_quest.id: 12, t_quest.id: 'Hey Raster!', m_quest.id: 'N' }, { n_quest.id: 19, t_quest.id: 'This bad boy' }] question_map = { n_quest.id: n_quest, t_quest.id: t_quest, m_quest.id: m_quest } interview = self.interview interviews = Interview.save_answers(self.qset, self.survey, self.ea, self.access_channel, question_map, answers) # confirm that 11 answers has been created self.assertEquals(NumericalAnswer.objects.count(), 5) self.assertEquals(TextAnswer.objects.count(), 5) self.assertEquals(MultiChoiceAnswer.objects.count(), 4) self.assertEquals(TextAnswer.objects.first().to_text().lower(), 'Hey Man'.lower()) self.assertEquals(MultiChoiceAnswer.objects.first().as_text.lower(), 'Y'.lower()) multichoice = MultiChoiceAnswer.objects.first() self.assertEquals( multichoice.as_value, str( QuestionOption.objects.get( text='Y', question=multichoice.question).order)) return Interview.objects.filter(id__in=[i.id for i in interviews])
def test_create_variable_from_existing_indicator(self): indicator, data = self._test_create_indicator() text_question = Question.objects.filter(answer_type=TextAnswer.choice_name(), qset__id=self.qset.id).first() data = self.variable_data.copy() data['test_question'] = text_question.id data['name'] = 'varaiabe_again' data['contains'] = 'tee boy' url = reverse('add_indicator_variable', args=(indicator.id, )) response = self.client.post(url, data=data) self.assertIn(response.status_code, [200, 302]) self.assertEquals(IndicatorVariable.objects.filter(name=data['name']).count(), 1)
def test_bulk_answer_questions(self): self._create_ussd_non_group_questions(self.qset) answers = [] n_quest = Question.objects.get( answer_type=NumericalAnswer.choice_name()) t_quest = Question.objects.get(answer_type=TextAnswer.choice_name()) m_quest = Question.objects.get( answer_type=MultiChoiceAnswer.choice_name()) # first is numeric, then text, then multichioice answers = [{ n_quest.id: 1, t_quest.id: 'Hey Man', m_quest.id: 'Y' }, { n_quest.id: 5, t_quest.id: 'Hey Boy', m_quest.id: 'Y' }, { n_quest.id: 15, t_quest.id: 'Hey Girl!', m_quest.id: 'N' }, { n_quest.id: 15, t_quest.id: 'Hey Part!' }] question_map = { n_quest.id: n_quest, t_quest.id: t_quest, m_quest.id: m_quest } interview = self.interview Interview.save_answers(self.qset, self.survey, self.ea, self.access_channel, question_map, answers) # confirm that 11 answers has been created self.assertEquals(NumericalAnswer.objects.count(), 4) self.assertEquals(TextAnswer.objects.count(), 4) self.assertEquals(MultiChoiceAnswer.objects.count(), 3) self.assertEquals(TextAnswer.objects.first().to_text().lower(), 'Hey Man'.lower()) self.assertEquals(MultiChoiceAnswer.objects.first().as_text.lower(), 'Y'.lower()) self.assertEquals(MultiChoiceAnswer.objects.first().as_value, str(QuestionOption.objects.get(text='Y').order)) # now test wipe data request = RequestFactory().get('.') request.user = self._load_other_client() activate_super_powers(request) url = reverse('wipe_survey_data', args=(self.survey.id, )) answer_count = Answer.objects.count() self.assertTrue(answer_count > 0) response = self.client.get(url) self.assertEquals(Answer.objects.count(), 0)
def test_create_variable_from_existing_indicator(self): indicator, data = self._test_create_indicator() text_question = Question.objects.filter( answer_type=TextAnswer.choice_name(), qset__id=self.qset.id).last() data = self.variable_data.copy() data['test_question'] = text_question.id data['name'] = 'varaiabe_again' data['contains'] = 'tee boy' url = reverse('add_indicator_variable', args=(indicator.id, )) response = self.client.post(url, data=data) self.assertIn(response.status_code, [200, 302]) self.assertEquals( IndicatorVariable.objects.filter(name=data['name']).count(), 1)
def _bulk_answer_questions(self): answers = [] n_quest = Question.objects.filter( answer_type=NumericalAnswer.choice_name()).last() t_quest = Question.objects.filter( answer_type=TextAnswer.choice_name()).last() m_quest = Question.objects.filter( answer_type=MultiChoiceAnswer.choice_name()).last() # first is numeric, then text, then multichioice answers = [ { n_quest.id: 5, t_quest.id: 'Hey Boy', m_quest.id: 'Y' }, { n_quest.id: 15, t_quest.id: 'Hey Girl!', m_quest.id: 'N' }, { n_quest.id: 15, t_quest.id: 'Hey Part!' }, { n_quest.id: 1, t_quest.id: 'Privet malishka, kach di la', m_quest.id: 'Y' }, ] question_map = { n_quest.id: n_quest, t_quest.id: t_quest, m_quest.id: m_quest } Interview.save_answers(self.qset, self.survey, self.ea, self.access_channel, question_map, answers) # confirm that 11 answers has been created self.assertEquals(NumericalAnswer.objects.count(), 4) self.assertEquals(TextAnswer.objects.count(), 4) self.assertEquals(MultiChoiceAnswer.objects.count(), 3) self.assertEquals(TextAnswer.objects.last().to_text().lower(), 'Privet malishka, kach di la'.lower()) m_answer = MultiChoiceAnswer.objects.last() self.assertEquals(m_answer.as_text.lower(), 'Y'.lower()) self.assertEquals( m_answer.as_value, str( QuestionOption.objects.get(text='Y', question__id=m_quest.id).order))
def setUp(self): self.client = Client() user_without_permission = User.objects.create_user(username='******', email='*****@*****.**', password='******') raj = self.assign_permission_to(User.objects.create_user('demo12', '*****@*****.**', 'demo12'), 'can_view_batches') self.listing_form = mommy.make(ListingTemplate) question1 = mommy.make(Question, qset=self.listing_form, answer_type=NumericalAnswer.choice_name()) question2 = mommy.make(Question, qset=self.listing_form, answer_type=TextAnswer.choice_name()) question3 = mommy.make(Question, qset=self.listing_form, answer_type=VideoAnswer.choice_name()) self.client.login(username='******', password='******') self.form_data = {'name': 'survey demo12', 'description': 'survey description demo12', 'has_sampling': True, 'sample_size': 10, 'random_sample_label': 'q1 {{%s}} q2: {{%s}}' % (question1.identifier, question2.identifier)}
def test_bulk_answer_questions(self): self._create_ussd_non_group_questions(self.qset) answers = [] n_quest = Question.objects.get( answer_type=NumericalAnswer.choice_name()) t_quest = Question.objects.get(answer_type=TextAnswer.choice_name()) m_quest = Question.objects.get( answer_type=MultiChoiceAnswer.choice_name()) # first is numeric, then text, then multichioice answers = [{ n_quest.id: 1, t_quest.id: 'Hey Man', m_quest.id: 'Y' }, { n_quest.id: 5, t_quest.id: 'Hey Boy', m_quest.id: 'Y' }, { n_quest.id: 15, t_quest.id: 'Hey Girl!', m_quest.id: 'N' }, { n_quest.id: 15, t_quest.id: 'Hey Part!' }] question_map = { n_quest.id: n_quest, t_quest.id: t_quest, m_quest.id: m_quest } interview = self.interview Interview.save_answers(self.qset, self.survey, self.ea, self.access_channel, question_map, answers) # confirm that 11 answers has been created self.assertEquals(NumericalAnswer.objects.count(), 4) self.assertEquals(TextAnswer.objects.count(), 4) self.assertEquals(MultiChoiceAnswer.objects.count(), 3) self.assertEquals(TextAnswer.objects.first().to_text().lower(), 'Hey Man'.lower()) self.assertEquals(MultiChoiceAnswer.objects.first().as_text.lower(), 'Y'.lower()) self.assertEquals(MultiChoiceAnswer.objects.first().as_value, str(QuestionOption.objects.get(text='Y').order))
def _create_ussd_non_group_questions(self, qset=None): if qset is None: qset = self.qset # numeric answer data = { 'answer_type': NumericalAnswer.choice_name(), 'text': 'num text', 'identifier': 'num1_identifier_%s' % random.randint(1, 100), 'qset': qset.id } question = self._save_question(qset, data) qset.refresh_from_db( ) # qset is updated by question (start_question attribute is updated) # since it's the first question saved it must reflect as first question of the question set self.assertEquals(qset.start_question.id, question.id) # text answer data = { 'answer_type': TextAnswer.choice_name(), 'text': 'texts text', 'identifier': 'text1_identifier_%s' % random.randint(1, 100), 'qset': qset.id } self._save_question(qset, data) # Multichoice questions data = { 'answer_type': MultiChoiceAnswer.choice_name(), 'text': 'multichoice answer text', 'identifier': 'multi1_choice_identifier_%s' % random.randint(1, 100), 'qset': qset.id, 'options': ['Y', 'N'] } self._save_question(qset, data) # Auto questions data = { 'answer_type': AutoResponse.choice_name(), 'text': 'auto answer text', 'identifier': 'auto1_identifier_%s' % random.randint(1, 100), 'qset': qset.id, } self._save_question(qset, data) self.qset.refresh_from_db()
def _create_ussd_non_group_questions(self, qset=None): if qset is None: qset = self.qset # numeric answer data = { 'answer_type': NumericalAnswer.choice_name(), 'text': 'num text', 'identifier': 'num1_identifier_%s' % random.randint(1, 100), 'qset': qset.id } question = self._save_question(qset, data) qset.refresh_from_db() # qset is updated by question (start_question attribute is updated) # since it's the first question saved it must reflect as first question of the question set self.assertEquals(qset.start_question.id, question.id) # text answer data = { 'answer_type': TextAnswer.choice_name(), 'text': 'texts text', 'identifier': 'text1_identifier_%s' % random.randint(1, 100), 'qset': qset.id } self._save_question(qset, data) # Multichoice questions data = { 'answer_type': MultiChoiceAnswer.choice_name(), 'text': 'multichoice answer text', 'identifier': 'multi1_choice_identifier_%s' % random.randint(1, 100), 'qset': qset.id, 'options': ['Y', 'N'] } self._save_question(qset, data) # Auto questions data = { 'answer_type': AutoResponse.choice_name(), 'text': 'auto answer text', 'identifier': 'auto1_identifier_%s' % random.randint(1, 100), 'qset': qset.id, } self._save_question(qset, data) self.qset.refresh_from_db()
def test_bulk_answer_questions(self): self._create_ussd_non_group_questions(self.qset) answers = [] n_quest = Question.objects.get(answer_type=NumericalAnswer.choice_name()) t_quest = Question.objects.get(answer_type=TextAnswer.choice_name()) m_quest = Question.objects.get(answer_type=MultiChoiceAnswer.choice_name()) # first is numeric, then text, then multichioice answers = [{n_quest.id: 1, t_quest.id: 'Hey Man', m_quest.id: 'Y'}, {n_quest.id: 5, t_quest.id: 'Hey Boy', m_quest.id: 'Y'}, {n_quest.id: 15, t_quest.id: 'Hey Girl!', m_quest.id: 'N'}, {n_quest.id: 15, t_quest.id: 'Hey Part!'} ] question_map = {n_quest.id: n_quest, t_quest.id: t_quest, m_quest.id: m_quest} interview = self.interview Interview.save_answers(self.qset, self.survey, self.ea, self.access_channel, question_map, answers) # confirm that 11 answers has been created self.assertEquals(NumericalAnswer.objects.count(), 4) self.assertEquals(TextAnswer.objects.count(), 4) self.assertEquals(MultiChoiceAnswer.objects.count(), 3) self.assertEquals(TextAnswer.objects.first().to_text().lower(), 'Hey Man'.lower()) self.assertEquals(MultiChoiceAnswer.objects.first().as_text.lower(), 'Y'.lower()) self.assertEquals(MultiChoiceAnswer.objects.first().as_value, str(QuestionOption.objects.get(text='Y').order))
def _bulk_answer_questions(self): answers = [] n_quest = Question.objects.filter(answer_type=NumericalAnswer.choice_name()).first() t_quest = Question.objects.filter(answer_type=TextAnswer.choice_name()).first() m_quest = Question.objects.filter(answer_type=MultiChoiceAnswer.choice_name()).first() # first is numeric, then text, then multichioice answers = [{n_quest.id: 1, t_quest.id: 'Privet malishka, kach di la', m_quest.id: 'Y'}, {n_quest.id: 5, t_quest.id: 'Hey Boy', m_quest.id: 'Y'}, {n_quest.id: 15, t_quest.id: 'Hey Girl!', m_quest.id: 'N'}, {n_quest.id: 15, t_quest.id: 'Hey Part!'} ] question_map = {n_quest.id: n_quest, t_quest.id: t_quest, m_quest.id: m_quest} interview = self.interview Interview.save_answers(self.qset, self.survey, self.ea, self.access_channel, question_map, answers) # confirm that 11 answers has been created self.assertEquals(NumericalAnswer.objects.count(), 4) self.assertEquals(TextAnswer.objects.count(), 4) self.assertEquals(MultiChoiceAnswer.objects.count(), 3) self.assertEquals(TextAnswer.objects.first().to_text().lower(), 'Privet malishka, kach di la'.lower()) m_answer = MultiChoiceAnswer.objects.first() self.assertEquals(m_answer.as_text.lower(), 'Y'.lower()) self.assertEquals(m_answer.as_value, str(QuestionOption.objects.get(text='Y', question__id=m_quest.id).order))
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
def test_subquestion_selection_in_form_question_creates_branch_flow(self): ''' :return: ''' q1 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1, identifier='test1', text='test1', answer_type=TextAnswer.choice_name()) q2 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1, identifier='test2', text='test2', answer_type=TextAnswer.choice_name()) q3 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1, identifier='test3', text='test3', answer_type=TextAnswer.choice_name()) q4 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1, identifier='test4', text='test4', answer_type=TextAnswer.choice_name()) q5 = Question.objects.create(qset_id=self.qset.id, response_validation_id=1, identifier='test5', text='test5', answer_type=TextAnswer.choice_name()) self.batch.start_question = q1 QuestionFlow.objects.create(question_id=q1.id, next_question_id=q3.id) QuestionFlow.objects.create(question_id=q3.id, next_question_id=q5.id) test_condition = TextAnswer.validators()[0].__name__ test_param = 'Hey you!!' form_data = { 'action': LogicForm.ASK_SUBQUESTION, 'next_question': q4.pk, 'condition': test_condition, 'value': test_param } l = LogicForm(q1, 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=q1.id, next_question_id=q4.id) TextArgument.objects.get(flow=qf, param=test_param) qf = QuestionFlow.objects.get(question_id=q1.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.assertTrue(False, 'Invalid form')
def test_create_listing_sample(self): # create two conditions self._test_create_sampling_criteria() self._test_create_sampling_criteria_with_multichoice() # now answers to test listing sample listing_question = self.qset.questions.filter( answer_type=MultiChoiceAnswer.choice_name()).first() n_quest = Question.objects.get( answer_type=NumericalAnswer.choice_name()) t_quest = Question.objects.get(answer_type=TextAnswer.choice_name()) m_quest = Question.objects.get( answer_type=MultiChoiceAnswer.choice_name()) first_option = listing_question.options.first().text second_option = listing_question.options.last().text # first is numeric, then text, then multichioice answers = [ { n_quest.id: 1, t_quest.id: 'Hey Man', m_quest.id: first_option }, { n_quest.id: 5, t_quest.id: 'Hey Boy', m_quest.id: second_option }, { n_quest.id: 15, m_quest.id: first_option }, { n_quest.id: 18, t_quest.id: 'Hey Part!' }, { n_quest.id: 12, t_quest.id: 'Hey Gerry!', m_quest.id: first_option }, { n_quest.id: 10, t_quest.id: 'Hey My guy!', m_quest.id: second_option }, { n_quest.id: 17, t_quest.id: 'Hey my Girl!', m_quest.id: second_option }, { n_quest.id: 6, m_quest.id: first_option }, { n_quest.id: 133, m_quest.id: first_option }, { n_quest.id: 4, m_quest.id: first_option }, { n_quest.id: 9, m_quest.id: first_option }, ] question_map = { n_quest.id: n_quest, t_quest.id: t_quest, m_quest.id: m_quest } Interview.save_answers(self.qset, self.survey, self.ea, self.access_channel, question_map, answers) survey = self.survey self.assertEquals(Interview.objects.count(), len(answers)) ListingSample.get_or_create_samples(survey, self.ea) # This should create samples with interviews where numeric answers are btween 1 and 10 self.assertEquals(ListingSample.objects.count(), survey.sample_size) for sample in ListingSample.objects.all(): answers = sample.interview.answer.all() self.assertTrue( int(answers.get(question__id=n_quest.id).as_value) >= 1) # from first criteria creation self.assertTrue( int(answers.get(question__id=n_quest.id).as_value) < 10) # from second criteria creation self.assertTrue( answers.get(question__id=m_quest.id).as_text.upper(), first_option.upper()) # since we did not define any random_sample_label for the survey # and since the questonset is not empty, the label should be the very first question self.assertEquals(sample.interview.answer.first().as_text, sample.get_display_label()) # now test the case where some questions have no response for the random label self.survey.random_sample_label = '{{%s}}' % t_quest.identifier self.survey.save() self.survey.refresh_from_db() for sample in ListingSample.samples(self.survey, self.ea): answers = sample.interview.answer.all() first_text = sample.interview.answer.first().as_text try: expected_label = '%s' % answers.get( question__id=t_quest.id).as_text except Answer.DoesNotExist: expected_label = '%s' % first_text self.assertEquals(string.capwords(expected_label), sample.get_display_label()) self.assertEquals(get_sample_data_display(sample), sample.get_display_label())
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!')