def _get_questionnaire(self): q1 = QuestionFactory.create(analysis_key='q1', label='q1', short_label='q1') choice1_q2 = ChoiceFactory(question=q1, payload='q2', display='q2') choice1_q3 = ChoiceFactory(question=q1, payload='q3', display='q3') q2 = QuestionFactory.create(analysis_key='q2', label='q2', short_label='q2') q3 = QuestionFactory.create(analysis_key='q3', label='q3', short_label='q3') q4 = QuestionFactory.create(analysis_key='q4', label='q4', short_label='q4', required=True) q5 = QuestionFactory.create(analysis_key='q5', label='q5', short_label='q5') # sketch: # q1 <- first_question # / \ # q2 q3 # \ / # q4 # | # q5 graph = QuestionGraphFactory.create(name='testgraph', first_question=q1) EdgeFactory.create(graph=graph, question=q1, next_question=q2, choice=choice1_q2) EdgeFactory.create(graph=graph, question=q2, next_question=q4, choice=None) EdgeFactory.create(graph=graph, question=q1, next_question=q3, choice=choice1_q3) EdgeFactory.create(graph=graph, question=q3, next_question=q4, choice=None) EdgeFactory.create(graph=graph, question=q4, next_question=q5, choice=None) return QuestionnaireFactory.create(graph=graph, name='diamond', flow=Questionnaire.EXTRA_PROPERTIES)
def _question_graph_with_decision_with_default(): q1 = QuestionFactory.create( retrieval_key='q_yesno', short_label='Yes or no?', label='Yes or no, what do you choose?', ) q_yes = QuestionFactory.create(retrieval_key='q_yes', short_label='yes', label='The yes question. Happy now?') q_no = QuestionFactory.create(retrieval_key='q_no', short_label='no', label='The no question. Still unhappy?') graph = QuestionGraphFactory.create( name='Graph with decision with default', first_question=q1) EdgeFactory.create(graph=graph, question=q1, next_question=q_yes, choice__payload='yes', choice__question=q1) EdgeFactory.create(graph=graph, question=q1, next_question=q_no, choice__payload='no', choice__question=q1) # Default option, last edge without choice property: EdgeFactory.create(graph=graph, question=q1, next_question=q_yes, choice=None) return graph
def test_question_factory(self): QuestionFactory.create() self.assertEqual(Answer.objects.count(), 0) self.assertEqual(Session.objects.count(), 0) self.assertEqual(Questionnaire.objects.count(), 0) self.assertEqual(Question.objects.count(), 1)
def _question_graph_with_decision_null_retrieval_keys(): q1 = QuestionFactory.create( retrieval_key=None, short_label='Yes or no?', label='Yes or no, what do you choose?', ) q_yes = QuestionFactory.create(retrieval_key=None, short_label='yes', label='The yes question. Happy now?') q_no = QuestionFactory.create(retrieval_key=None, short_label='no', label='The no question. Still unhappy?') graph = QuestionGraphFactory.create( name='Graph with decision and null keys', first_question=q1) EdgeFactory.create(graph=graph, question=q1, next_question=q_yes, choice__payload='yes', choice__question=q1) EdgeFactory.create(graph=graph, question=q1, next_question=q_no, choice__payload='no', choice__question=q1) return graph
def _create_graph_no_defaults(graph_name='diamond'): """ Seed the database with a diamond shaped graph formed by questions. """ q1 = QuestionFactory.create() q2 = QuestionFactory.create() q3 = QuestionFactory.create() # sketch: # q1 <- first_question # / \ # q2 q3 graph = QuestionGraphFactory.create(name=graph_name, first_question=q1) EdgeFactory.create(graph=graph, question=q1, next_question=q2, choice__payload='yes', choice__question=q1) EdgeFactory.create(graph=graph, question=q1, next_question=q3, choice__payload='no', choice__question=q1) return graph
def create_diamond(graph_name='diamond'): """ Seed the database with a diamond shaped graph formed by questions. """ q1 = QuestionFactory.create(analysis_key='q1') q2 = QuestionFactory.create(analysis_key='q2') q3 = QuestionFactory.create(analysis_key='q3') q4 = QuestionFactory.create(analysis_key='q4') q5 = QuestionFactory.create(analysis_key='q5') # sketch: # q1 <- first_question # / \ # q2 q3 # \ / # q4 # | # q5 graph = QuestionGraphFactory.create(name=graph_name, first_question=q1) EdgeFactory.create(graph=graph, question=q1, next_question=q2, choice=None) EdgeFactory.create(graph=graph, question=q2, next_question=q4, choice=None) EdgeFactory.create(graph=graph, question=q1, next_question=q3, choice=None) EdgeFactory.create(graph=graph, question=q3, next_question=q4, choice=None) EdgeFactory.create(graph=graph, question=q4, next_question=q5, choice=None) return graph
def create_cycle(graph_name='cycle'): q1 = QuestionFactory.create(analysis_key='q1') q2 = QuestionFactory.create(analysis_key='q2') # sketch: # q1 <- first_question # ( ) # q2 graph = QuestionGraphFactory.create(name=graph_name, first_question=q1) EdgeFactory(graph=graph, question=q1, next_question=q2, choice=None) EdgeFactory(graph=graph, question=q2, next_question=q1, choice=None) return graph
def setUp(self): # sketch: # q1 <- first question (PlainText) # | # q2 <- second question (Image) self.q1 = QuestionFactory.create(analysis_key='q1', label='q1', short_label='q1', required=True) self.q2 = QuestionFactory.create(analysis_key='q2', label='q2', short_label='q2', field_type='image', required=True) graph = QuestionGraphFactory.create(name='testgraph', first_question=self.q1) EdgeFactory.create(graph=graph, question=self.q1, next_question=self.q2) self.questionnaire = QuestionnaireFactory.create(graph=graph, name='test', flow=Questionnaire.EXTRA_PROPERTIES) self.session = SessionFactory(questionnaire=self.questionnaire, submit_before=None, duration=None, frozen=False)
def create_disconnected(graph_name='disconnected'): q1 = QuestionFactory.create(analysis_key='q1') q2 = QuestionFactory.create(analysis_key='q2') q3 = QuestionFactory.create(analysis_key='q3') # sketch: # q1 <- first_question # # q2 # | # q3 graph = QuestionGraphFactory.create(name=graph_name, first_question=q1) EdgeFactory.create(graph=graph, question=q2, next_question=q3, choice=None) return graph
def test_validate_answer_payload_do_enforce_choices(self): q = QuestionFactory.create(required=False, enforce_choices=True) ChoiceFactory.create(question=q, payload='VALID') self.assertEqual(AnswerService.validate_answer_payload('VALID', q), 'VALID') with self.assertRaises(django_validation_error): AnswerService.validate_answer_payload('BLAH', q)
def test_handle_frozen_session_on_commit_triggered(self): question = QuestionFactory.create(field_type='plain_text', label='Is het goed weer?', short_label='Goed weer?') session = SessionFactory.create( questionnaire__flow=Questionnaire.REACTION_REQUEST, questionnaire__first_question=question, frozen=False, _signal=self.signal_reaction_requested) answer = AnswerFactory(session=session, payload='Het antwoord!') submit_question = Question.objects.get_by_reference('submit') with self.captureOnCommitCallbacks(execute=False) as callbacks: QuestionnairesService.create_answer( answer_payload=None, question=submit_question, questionnaire=session.questionnaire, session=session) self.assertEqual(len(callbacks), 1) callbacks[0]() self.signal_reaction_requested.refresh_from_db() self.assertEqual(self.signal_reaction_requested.status.state, workflow.REACTIE_ONTVANGEN) self.assertEqual(self.signal_reaction_requested.status.text, answer.payload)
def test_validate_answer_payload_do_not_enforce_choices(self): q = QuestionFactory.create(required=False, enforce_choices=False) ChoiceFactory.create(question=q, payload='VALID') self.assertEqual(AnswerService.validate_answer_payload('VALID', q), 'VALID') self.assertEqual(AnswerService.validate_answer_payload('BLAH', q), 'BLAH')
def test_validated_answer_payload_not_required(self): q = QuestionFactory.create(required=False) self.assertEqual(AnswerService.validate_answer_payload(None, q), None) self.assertEqual(AnswerService.validate_answer_payload('BLAH', q), 'BLAH') with self.assertRaises(django_validation_error): AnswerService.validate_answer_payload(['NOT', 'A', 'STRING'], q)
def _question_graph_one_question(): q1 = QuestionFactory.create( key='only', short_label='Only question.', label='Only question.', ) return q1
def setUp(self): q1 = QuestionFactory.create(field_type='plain_text') self.graph = QuestionGraphFactory.create(name='info_trigger_order', first_question=q1) choice_payloads = ['one', 'two', 'three'] for payload in choice_payloads: ChoiceFactory.create(question=q1, payload=payload)
def _question_graph_one_question(): q1 = QuestionFactory.create( retrieval_key='only', short_label='Only question.', label='Only question.', ) return QuestionGraphFactory.create(name='Graph with only one question', first_question=q1)
def _question_graph_with_cycle(): q1 = QuestionFactory.create( retrieval_key='one', short_label='First question.', label='First question.', ) q2 = QuestionFactory.create( retrieval_key='two', short_label='Second question.', label='Second question.', ) graph = QuestionGraphFactory.create(name='Graph with cycle', first_question=q1) EdgeFactory.create(graph=graph, question=q1, next_question=q2, choice=None) EdgeFactory.create(graph=graph, question=q2, next_question=q1, choice=None) return graph
def create_diamond_plus(graph_name='diamond_plus'): graph = create_diamond(graph_name=graph_name) # sketch: # q1 <- first_question # / \ # q2 q3 # \ / # q4 q6 # | | # q5 q7 # Add an edge to the graph that cannot be reached from the first # question of the question_graph q6 = QuestionFactory.create(analysis_key='q6') q7 = QuestionFactory.create(analysis_key='q7') EdgeFactory.create(graph=graph, question=q6, next_question=q7, choice=None) return graph
def _question_graph_with_cycle(): q1 = QuestionFactory.create( key='one', short_label='First question.', label='First question.', next_rules=[ {'ref': 'two'} ], ) q2 = QuestionFactory.create( key='two', short_label='Second question.', label='Second question.', next_rules=[ {'ref': 'one'} ], ) return q1, q2
def setUp(self): q1 = QuestionFactory.create(field_type='plain_text') self.graph = QuestionGraphFactory.create(name='trigger_order', first_question=q1) trigger_payloads = ['one', 'two', 'three'] for payload in trigger_payloads: TriggerFactory.create(graph=self.graph, question=q1, payload=payload)
def test_create_answer_not_associated_to_questionnaire(self): # you cannot answer questions not part of the questionnaire associated with current session q_graph = create_diamond_plus() session = SessionFactory.create(questionnaire__graph=q_graph) service = SessionService(session) bad_question = QuestionFactory.create() with self.assertRaises(django_validation_error) as cm: service.create_answer('WILL NOT BE ACCEPTED', bad_question) self.assertIn('not in questionnaire', cm.exception.message)
def test_create_session_for_questionnaire(self): q1 = QuestionFactory.create(analysis_key='q1', label='q1', short_label='q1') choice1_q2 = ChoiceFactory(question=q1, payload='q2', display='q2') choice1_q3 = ChoiceFactory(question=q1, payload='q3', display='q3') q2 = QuestionFactory.create(analysis_key='q2', label='q2', short_label='q2') q3 = QuestionFactory.create(analysis_key='q3', label='q3', short_label='q3') q4 = QuestionFactory.create(analysis_key='q4', label='q4', short_label='q4', required=True) q5 = QuestionFactory.create(analysis_key='q5', label='q5', short_label='q5') # sketch: # q1 <- first_question # / \ # q2 q3 # \ / # q4 # | # q5 graph = QuestionGraphFactory.create(name='testgraph', first_question=q1) EdgeFactory.create(graph=graph, question=q1, next_question=q2, choice=choice1_q2) EdgeFactory.create(graph=graph, question=q2, next_question=q4, choice=None) EdgeFactory.create(graph=graph, question=q1, next_question=q3, choice=choice1_q3) EdgeFactory.create(graph=graph, question=q3, next_question=q4, choice=None) EdgeFactory.create(graph=graph, question=q4, next_question=q5, choice=None) questionnaire = QuestionnaireFactory.create(graph=graph, name='diamond', flow=Questionnaire.EXTRA_PROPERTIES) response = self.client.post(f'{self.base_endpoint}{questionnaire.uuid}/session', data=None, format='json') self.assertEqual(response.status_code, 201) response_json = response.json() self.assertIn('path_questions', response_json) self.assertEqual(len(response_json['path_questions']), 1) self.assertIn('path_answered_question_uuids', response_json) self.assertEqual(len(response_json['path_answered_question_uuids']), 0) self.assertIn('path_unanswered_question_uuids', response_json) self.assertEqual(len(response_json['path_unanswered_question_uuids']), 1) self.assertIn('path_validation_errors_by_uuid', response_json) self.assertEqual(len(response_json['path_validation_errors_by_uuid']), 0) self.assertIn('can_freeze', response_json) self.assertEqual(response_json['can_freeze'], False)
def _question_graph_with_decision(): q1 = QuestionFactory.create( key='q_yesno', short_label='Yes or no?', label='Yes or no, what do you choose?', next_rules=[ {'ref': 'q_yes', 'payload': 'yes'}, {'ref': 'q_no', 'payload': 'no'}, ], ) q2 = QuestionFactory.create( key='q_yes', short_label='yes', label='The yes question. Happy now?' ) q3 = QuestionFactory.create( key='q_no', short_label='no', label='The no question. Still unhappy?' ) return q1, q2, q3
def _question_graph_with_decision_null_keys(): q2 = QuestionFactory.create( key=None, short_label='yes', label='The yes question. Happy now?' ) q3 = QuestionFactory.create( key=None, short_label='no', label='The no question. Still unhappy?' ) q1 = QuestionFactory.create( key=None, short_label='Yes or no?', label='Yes or no, what do you choose?', next_rules=[ {'ref': str(q2.uuid), 'payload': 'yes'}, {'ref': str(q3.uuid), 'payload': 'no'}, ], ) return q1, q2, q3
def create_too_many_questions(graph_name='too_many'): questions = [QuestionFactory.create() for i in range(100) ] # TODO: make MAX_QUESTIONS an app setting graph = QuestionGraphFactory.create(name=graph_name, first_question=questions[0]) for i in range(len(questions) - 1): EdgeFactory.create(graph=graph, question=questions[i], next_question=questions[i + 1], choice=None) return graph
def setUp(self): self.question = QuestionFactory.create() graph = QuestionGraphFactory.create(first_question=self.question) self.questionnaire = QuestionnaireFactory.create(graph=graph) self.detail_schema = self.load_json_schema( os.path.join(THIS_DIR, '../../json_schema/public_get_question_detail.json') ) self.list_schema = self.load_json_schema( os.path.join(THIS_DIR, '../../json_schema/public_get_question_list.json') ) self.post_answer_schema = self.load_json_schema( os.path.join(THIS_DIR, '../../json_schema/public_post_question_answer_response.json') )
def setUp(self): # q1 # / | \ # q2 q3 q4 q1 = QuestionFactory.create() q2 = QuestionFactory.create() q3 = QuestionFactory.create() q4 = QuestionFactory.create() self.graph = QuestionGraphFactory.create(name='edge_order', first_question=q1) EdgeFactory.create(graph=self.graph, question=q1, next_question=q2, choice=None) EdgeFactory.create(graph=self.graph, question=q1, next_question=q3, choice=None) EdgeFactory.create(graph=self.graph, question=q1, next_question=q4, choice=None)
def _question_graph_with_decision_with_default_no_required_answers(): q1 = QuestionFactory.create( key='q_yesno', required=False, short_label='Yes or no?', label='Yes or no, what do you choose?', next_rules=[ {'ref': 'q_yes', 'payload': 'yes'}, {'ref': 'q_no', 'payload': 'no'}, {'ref': 'q_yes'} # Default option, always last and without 'payload' property! ], ) q2 = QuestionFactory.create( key='q_yes', short_label='yes', label='The yes question. Happy now?' ) q3 = QuestionFactory.create( key='q_no', short_label='no', label='The no question. Still unhappy?' ) return q1, q2, q3
def test_pathological_case_key_is_valid_uuid(self): # Set up a question that has a valid UUID as a key, make sure that # that one UUID does not match the question's `uuid` property. question = QuestionFactory.create() generated = uuid.uuid4() while generated == question.uuid: generated = uuid.uuid4() question.retrieval_key = generated question.save() question.refresh_from_db() retrieved = Question.objects.get_by_reference(str(generated)) self.assertEqual(retrieved, question)
def _question_graph_no_required_answers(): q1 = QuestionFactory.create( key='one', required=False, short_label='First not required', label='First not required', next_rules=[ {'ref': 'two'}, ] ) q2 = QuestionFactory( key='two', required=False, short_label='Second not required', label='Second not required', ) return q1, q2