Beispiel #1
0
    def test_questionnaire_factory(self):
        QuestionnaireFactory.create()

        self.assertEqual(Answer.objects.count(), 0)
        self.assertEqual(Session.objects.count(), 0)
        self.assertEqual(Questionnaire.objects.count(), 1)
        self.assertEqual(Question.objects.count(), 1)
    def test_create_answers_null_keys(self):
        q_yesno, q_yes, q_no = _question_graph_with_decision_null_keys()
        questionnaire = QuestionnaireFactory.create(first_question=q_yesno)

        question = questionnaire.first_question
        answer_str = 'yes'

        # We will answer the questionnaire, until we reach a None next question.
        # In the first step we have no Session reference yet.
        answer = QuestionnairesService.create_answer(
            answer_payload=answer_str, question=question, questionnaire=questionnaire, session=None)
        self.assertIsInstance(answer, Answer)
        self.assertEqual(answer.question, question)

        session = answer.session
        session_id = session.id
        self.assertIsNotNone(session)
        self.assertIsNone(session.submit_before)
        self.assertEqual(session.duration, timedelta(seconds=SESSION_DURATION))

        question2 = QuestionnairesService.get_next_question(answer, question)
        self.assertEqual(question2.ref, q_yes.uuid)

        answer2_str = 'yes'

        answer2 = QuestionnairesService.create_answer(
            answer_payload=answer2_str, question=question2, questionnaire=questionnaire, session=session)
        self.assertIsInstance(answer2, Answer)
        self.assertEqual(answer2.question, question2)
        self.assertEqual(answer2.session_id, session_id)

        next_question = QuestionnairesService.get_next_question(answer2, question2)
        self.assertEqual(next_question.key, 'submit')
    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)
Beispiel #4
0
    def setUp(self):
        self.questionnaire = QuestionnaireFactory.create()
        self.session = SessionFactory.create(questionnaire=self.questionnaire)

        self.detail_schema = self.load_json_schema(
            os.path.join(THIS_DIR,
                         '../json_schema/public_get_session_detail.json'))
Beispiel #5
0
    def test_question_not_required(self):
        # set up our questions and questionnaires
        graph = _question_graph_no_required_answers()
        questionnaire = QuestionnaireFactory.create(graph=graph)
        session = SessionFactory.create(questionnaire__graph=graph)
        session_service = get_session_service(session.uuid)
        session_service.refresh_from_db()

        question_1 = questionnaire.graph.first_question
        answer_payload_1 = None

        # We will answer the questionnaire, until we reach a None next question.
        # In the first step we have no Session reference yet.
        answer_1 = session_service.create_answer(answer_payload_1, question_1)
        self.assertIsInstance(answer_1, Answer)
        self.assertEqual(answer_1.question, question_1)

        session = answer_1.session
        session_id = session.id
        self.assertIsNotNone(session)
        self.assertIsNone(session.submit_before)
        self.assertEqual(session.duration, timedelta(seconds=SESSION_DURATION))

        question_2 = session_service.get_next_question(question_1, answer_1)
        self.assertEqual(question_2.ref, 'two')

        answer_payload_2 = None

        answer_2 = session_service.create_answer(answer_payload_2, question_2)
        self.assertIsInstance(answer_2, Answer)
        self.assertEqual(answer_2.question, question_2)
        self.assertEqual(answer_2.session_id, session_id)

        next_question = session_service.get_next_question(question_2, answer_2)
        self.assertIsNone(next_question)
Beispiel #6
0
    def test_validate_answer_payload_choices(self):
        graph = _question_graph_one_question()
        questionnaire = QuestionnaireFactory.create(graph=graph)

        payloads = ['only', 'yes', 'no']
        question = questionnaire.graph.first_question
        question.enforce_choices = True
        question.save()

        for payload in payloads:
            Choice.objects.create(question=question, payload=payload)

        self.assertEqual(question.choices.count(), 3)
        for payload in payloads:
            self.assertEqual(
                payload,
                AnswerService.validate_answer_payload(payload, question))

        no_choice = 'NOT A VALID ANSWER GIVEN PREDEFINED CHOICES'
        with self.assertRaises(django_validation_error):
            AnswerService.validate_answer_payload(no_choice, question)

        question.enforce_choices = False
        question.save()

        self.assertEqual(
            no_choice,
            AnswerService.validate_answer_payload(no_choice, question))
    def test_question_not_required(self):
        # set up our questions and questionnaires
        q1, q2 = _question_graph_no_required_answers()
        questionnaire = QuestionnaireFactory.create(first_question=q1)

        question = questionnaire.first_question
        answer_str = None

        # We will answer the questionnaire, until we reach a None next question.
        # In the first step we have no Session reference yet.
        answer = QuestionnairesService.create_answer(
            answer_payload=answer_str, question=question, questionnaire=questionnaire, session=None)
        self.assertIsInstance(answer, Answer)
        self.assertEqual(answer.question, question)

        session = answer.session
        session_id = session.id
        self.assertIsNotNone(session)
        self.assertIsNone(session.submit_before)
        self.assertEqual(session.duration, timedelta(seconds=SESSION_DURATION))

        question2 = QuestionnairesService.get_next_question(answer, question)
        self.assertEqual(question2.ref, q2.ref)

        answer2_str = None

        answer2 = QuestionnairesService.create_answer(
            answer_payload=answer2_str, question=question2, questionnaire=questionnaire, session=session)
        self.assertIsInstance(answer2, Answer)
        self.assertEqual(answer2.question, question2)
        self.assertEqual(answer2.session_id, session_id)

        next_question = QuestionnairesService.get_next_question(answer2, question2)
        self.assertEqual(next_question.key, 'submit')
    def test_question_with_default_next(self):
        # set up our questions and questionnaires
        q_yesno, q_yes, q_no = _question_graph_with_decision_with_default()
        questionnaire = QuestionnaireFactory.create(first_question=q_yesno)

        question = questionnaire.first_question
        answer_str = 'WILL NOT MATCH ANYTHING'  # to trigger default

        # We will answer the questionnaire, until we reach a None next question.
        # In the first step we have no Session reference yet.
        answer = QuestionnairesService.create_answer(
            answer_payload=answer_str, question=question, questionnaire=questionnaire, session=None)
        self.assertIsInstance(answer, Answer)
        self.assertEqual(answer.question, question)

        session = answer.session
        session_id = session.id
        self.assertIsNotNone(session)
        self.assertIsNone(session.submit_before)
        self.assertEqual(session.duration, timedelta(seconds=SESSION_DURATION))

        question2 = QuestionnairesService.get_next_question(answer, question)
        self.assertEqual(question2.ref, q_yes.ref)  # get the default option

        answer2_str = 'Yippee'

        answer2 = QuestionnairesService.create_answer(
            answer_payload=answer2_str, question=question2, questionnaire=questionnaire, session=session)
        self.assertIsInstance(answer2, Answer)
        self.assertEqual(answer2.question, question2)
        self.assertEqual(answer2.session_id, session_id)

        next_question = QuestionnairesService.get_next_question(answer2, question2)
        self.assertEqual(next_question.key, 'submit')
    def test_session_detail_reaction_requested(self):
        questionnaire = QuestionnaireFactory.create(flow=Questionnaire.REACTION_REQUEST)

        session = SessionFactory.create(questionnaire=questionnaire)

        response = self.client.get(f'{self.base_endpoint}{session.uuid}')
        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.json()['detail'], f'Session {session.uuid} is not associated with a Signal.')

        signal = SignalFactory.create(status__state=GEMELD)
        session._signal = signal
        session.save()

        response = self.client.get(f'{self.base_endpoint}{session.uuid}')
        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.json()['detail'],
                         f'Session {session.uuid} is invalidated, associated signal not in state REACTIE_GEVRAAGD.')

        status = StatusFactory(state=REACTIE_GEVRAAGD, _signal=signal)
        signal.status = status
        signal.save()

        latest_session = SessionFactory.create(questionnaire=questionnaire, _signal=signal)

        response = self.client.get(f'{self.base_endpoint}{session.uuid}')
        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.json()['detail'],
                         f'Session {session.uuid} is invalidated, a newer reaction request was issued.')

        response = self.client.get(f'{self.base_endpoint}{latest_session.uuid}')
        self.assertEqual(response.status_code, 200)
Beispiel #10
0
    def setUp(self):
        self.questionnaire = QuestionnaireFactory.create()

        self.detail_schema = self.load_json_schema(
            os.path.join(THIS_DIR, '../../json_schema/public_get_questionnaire_detail.json')
        )
        self.list_schema = self.load_json_schema(
            os.path.join(THIS_DIR, '../../json_schema/public_get_questionnaire_list.json')
        )
    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):
        # 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)
Beispiel #13
0
    def test_category_detail_questionnaire(self):
        questionnaire = QuestionnaireFactory.create()
        parent_category = ParentCategoryFactory.create(
            questionnaire=questionnaire)

        url = f'/signals/v1/public/terms/categories/{parent_category.slug}'
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        data = response.json()

        # JSONSchema validation
        self.assertJsonSchema(self.retrieve_category_schema, data)
        self.assertIsNotNone(data['_links']['sia:questionnaire'])
    def setUp(self):
        user_model = get_user_model()
        self.superuser, _ = user_model.objects.get_or_create(
            email='*****@*****.**', is_superuser=True,
            defaults={'first_name': 'John', 'last_name': 'Doe', 'is_staff': True}
        )
        self.questionnaire = QuestionnaireFactory.create()
        self.question = self.questionnaire.first_question

        self.detail_schema = self.load_json_schema(
            os.path.join(THIS_DIR, '../json_schema/private_get_question_detail.json')
        )
        self.list_schema = self.load_json_schema(
            os.path.join(THIS_DIR, '../json_schema/private_get_question_list.json')
        )
Beispiel #15
0
    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 test_submit(self, patched_callback):
        q1 = _question_graph_one_question()
        questionnaire = QuestionnaireFactory.create(first_question=q1)

        question = questionnaire.first_question
        answer_str = 'ONLY'

        # We will answer the questionnaire, until we reach a None next question.
        # In the first step we have no Session reference yet.
        with self.captureOnCommitCallbacks(execute=True):
            answer = QuestionnairesService.create_answer(
                answer_payload=answer_str, question=question, questionnaire=questionnaire, session=None)
        patched_callback.assert_not_called()

        self.assertIsInstance(answer, Answer)
        self.assertEqual(answer.question, question)

        session = answer.session
        session_id = session.id
        self.assertIsNotNone(session)
        self.assertIsNone(session.submit_before)
        self.assertEqual(session.duration, timedelta(seconds=SESSION_DURATION))

        question2 = QuestionnairesService.get_next_question(answer, question)
        self.assertEqual(question2.ref, 'submit')

        answer2_str = None

        with self.captureOnCommitCallbacks(execute=True):
            answer2 = QuestionnairesService.create_answer(
                answer_payload=answer2_str, question=question2, questionnaire=questionnaire, session=session)
        self.assertIsInstance(answer2, Answer)
        self.assertEqual(answer2.question, question2)
        self.assertEqual(answer2.session_id, session_id)
        patched_callback.assert_called_with(session)

        next_question = QuestionnairesService.get_next_question(answer2, question2)
        self.assertIsNone(next_question)
Beispiel #17
0
    def test_create_answers_retrieval_keys(self):
        graph = _question_graph_with_decision_null_retrieval_keys()
        questionnaire = QuestionnaireFactory.create(graph=graph)
        session = SessionFactory.create(questionnaire=questionnaire)
        session_service = get_session_service(session.uuid)
        session_service.refresh_from_db()

        question_1 = questionnaire.first_question
        answer_payload_1 = 'yes'

        # We will answer the questionnaire, until we reach a None next question.
        # In the first step we have no Session reference yet.
        answer_1 = session_service.create_answer(answer_payload_1, question_1)
        self.assertIsInstance(answer_1, Answer)
        self.assertEqual(answer_1.question, question_1)

        session = answer_1.session
        session_id = session.id
        self.assertIsNotNone(session)
        self.assertIsNone(session.submit_before)
        self.assertEqual(session.duration, timedelta(seconds=SESSION_DURATION))

        question_2 = session_service.get_next_question(question_1, answer_1)

        # We want the yes branch followed, here we grab the relevant question
        edge_match = graph.edges.filter(
            question=question_1, choice__payload=answer_payload_1).first()
        self.assertEqual(question_2, edge_match.next_question)

        answer_payload_2 = 'yes'

        answer_2 = session_service.create_answer(answer_payload_2, question_2)
        self.assertIsInstance(answer_2, Answer)
        self.assertEqual(answer_2.question, question_2)
        self.assertEqual(answer_2.session_id, session_id)

        next_question = session_service.get_next_question(question_2, answer_2)
        self.assertIsNone(next_question)
Beispiel #18
0
    def test_create_answers(self):
        # set up our questions and questionnaires
        graph = _question_graph_with_decision()
        questionnaire = QuestionnaireFactory.create(
            graph=graph, flow=Questionnaire.EXTRA_PROPERTIES)
        session = SessionFactory.create(questionnaire=questionnaire)
        session_service = get_session_service(session.uuid)
        session_service.refresh_from_db()

        question_1 = questionnaire.first_question
        answer_payload = 'yes'

        # We will answer the questionnaire, until we reach a None next question.
        # In the first step we have no Session reference yet.

        answer_1 = session_service.create_answer(answer_payload, question_1)
        self.assertIsInstance(answer_1, Answer)
        self.assertEqual(answer_1.question, question_1)

        session = answer_1.session
        session_id = session.id
        self.assertIsNotNone(session)
        self.assertIsNone(session.submit_before)
        self.assertEqual(session.duration, timedelta(seconds=SESSION_DURATION))

        question_2 = session_service.get_next_question(question_1, answer_1)
        self.assertEqual(question_2.ref, 'q_yes')

        answer_payload_2 = 'yes'
        answer_2 = session_service.create_answer(answer_payload_2, question_2)

        self.assertIsInstance(answer_2, Answer)
        self.assertEqual(answer_2.question, question_2)
        self.assertEqual(answer_2.session_id, session_id)

        next_question = session_service.get_next_question(question_2, answer_2)
        self.assertIsNone(next_question)
    def test_answer_a_complete_questionnaire_branching_flow(self):
        self.assertEqual(0, Answer.objects.count())
        self.assertEqual(0, Session.objects.count())

        questionnaire = QuestionnaireFactory.create(
            first_question__key='test-question-1',
            first_question__next_rules=[{
                'payload': 'yes',
                'ref': 'test-question-2'
            }, {
                'payload': 'no',
                'ref': 'test-question-3'
            }, {
                'ref': 'test-question-4'
            }])

        second_question = QuestionFactory.create(key='test-question-2')
        third_question = QuestionFactory.create(key='test-question-3')
        fourth_question = QuestionFactory.create(key='test-question-4')

        first_post_answer_endpoint = f'{self.base_endpoint}{questionnaire.first_question.uuid}/answer'

        # Flow: question 1 -> question 2 -> done
        data = {'payload': 'yes', 'questionnaire': questionnaire.uuid}
        response = self.client.post(first_post_answer_endpoint,
                                    data=data,
                                    format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response_data['next_question']['uuid'],
                         str(second_question.uuid))

        data = {'payload': 'test', 'session': response_data['session']}
        second_post_answer_endpoint = response_data['next_question']['_links'][
            'sia:post-answer']['href']
        response = self.client.post(second_post_answer_endpoint,
                                    data=data,
                                    format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertIsNotNone(response_data['next_question'])
        self.assertEqual(response_data['next_question']['field_type'],
                         'submit')

        # Flow: question 1 -> question 3 -> done
        data = {'payload': 'no', 'questionnaire': questionnaire.uuid}
        response = self.client.post(first_post_answer_endpoint,
                                    data=data,
                                    format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response_data['next_question']['uuid'],
                         str(third_question.uuid))

        data = {'payload': 'test', 'session': response_data['session']}
        response = self.client.post(second_post_answer_endpoint,
                                    data=data,
                                    format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertIsNotNone(response_data['next_question'])
        self.assertEqual(response_data['next_question']['field_type'],
                         'submit')

        # Flow: question 1 -> question 4 -> done
        data = {'payload': 'default', 'questionnaire': questionnaire.uuid}
        response = self.client.post(first_post_answer_endpoint,
                                    data=data,
                                    format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response_data['next_question']['uuid'],
                         str(fourth_question.uuid))

        data = {'payload': 'test', 'session': response_data['session']}
        second_post_answer_endpoint = response_data['next_question']['_links'][
            'sia:post-answer']['href']
        response = self.client.post(second_post_answer_endpoint,
                                    data=data,
                                    format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertIsNotNone(response_data['next_question'])
        self.assertEqual(response_data['next_question']['field_type'],
                         'submit')

        self.assertEqual(3, Session.objects.count())
        self.assertEqual(6, Answer.objects.count())
    def test_answer_a_complete_questionnaire(self):
        self.assertEqual(0, Answer.objects.count())
        self.assertEqual(0, Session.objects.count())

        # Setup questions
        test_question_1 = QuestionFactory(retrieval_key='test-question-1')
        test_question_2 = QuestionFactory(retrieval_key='test-question-2')
        test_question_3 = QuestionFactory(retrieval_key='test-question-3')
        test_question_4 = QuestionFactory(retrieval_key='test-question-4')
        test_question_5 = QuestionFactory(retrieval_key='test-question-5')

        # Setup graph relations between questions
        graph = QuestionGraphFactory.create(first_question=test_question_1)
        EdgeFactory.create(graph=graph, question=test_question_1, next_question=test_question_2, choice=None)
        EdgeFactory.create(graph=graph, question=test_question_2, next_question=test_question_3, choice=None)
        EdgeFactory.create(graph=graph, question=test_question_3, next_question=test_question_4, choice=None)
        EdgeFactory.create(graph=graph, question=test_question_4, next_question=test_question_5, choice=None)

        # Create our questionnaire
        questionnaire = QuestionnaireFactory.create(graph=graph)

        # Answer our questionnaire
        data = {'payload': 'answer-1', 'questionnaire': questionnaire.uuid}
        first_post_answer_endpoint = f'{self.base_endpoint}{questionnaire.first_question.uuid}/answer'
        response = self.client.post(first_post_answer_endpoint, data=data, format='json')
        self.assertEqual(response.status_code, 201)

        response_data = response.json()
        self.assertJsonSchema(self.post_answer_schema, response_data)
        self.assertIsNotNone(response_data['next_question'])

        self.assertEqual(1, Answer.objects.count())
        self.assertEqual(1, Session.objects.count())

        next_post_answer_endpoint = response_data['next_question']['_links']['sia:post-answer']['href']
        session = Session.objects.first()

        for x in range(2, 6):
            data = {'payload': f'answer-{x}', 'session': session.uuid}
            response = self.client.post(next_post_answer_endpoint, data=data, format='json')
            self.assertEqual(response.status_code, 201)

            response_data = response.json()
            self.assertJsonSchema(self.post_answer_schema, response_data)

            self.assertEqual(x, Answer.objects.count())
            self.assertEqual(1, Session.objects.count())

            if x < 5:
                self.assertIsNotNone(response_data['next_question'])
                next_post_answer_endpoint = response_data['next_question']['_links']['sia:post-answer']['href']
            else:
                self.assertIsNone(response_data['next_question'])  # session must be frozen using ../submit endpoint

        answer_qs = Answer.objects.filter(
            question_id__in=[
                questionnaire.graph.first_question.id,
                test_question_2.id,
                test_question_3.id,
                test_question_4.id,
                test_question_5.id,
            ],
            session_id=session.pk,
        )

        self.assertTrue(answer_qs.exists())
        self.assertEqual(5, answer_qs.count())
    def test_answer_a_complete_questionnaire_branching_flow(self):
        self.assertEqual(0, Answer.objects.count())
        self.assertEqual(0, Session.objects.count())

        # Setup questions
        test_question_1 = QuestionFactory(retrieval_key='test-question-1')
        test_question_2 = QuestionFactory(retrieval_key='test-question-2')
        test_question_3 = QuestionFactory(retrieval_key='test-question-3')
        test_question_4 = QuestionFactory(retrieval_key='test-question-4')

        # Setup graph relations between questions
        graph = QuestionGraphFactory.create(first_question=test_question_1)
        EdgeFactory.create(graph=graph,
                           question=test_question_1,
                           next_question=test_question_2,
                           choice__payload='yes',
                           choice__question=test_question_1)
        EdgeFactory.create(graph=graph,
                           question=test_question_1,
                           next_question=test_question_3,
                           choice__payload='no',
                           choice__question=test_question_1)
        EdgeFactory.create(graph=graph, question=test_question_1, next_question=test_question_4, choice=None)

        # Create our questionnaire
        questionnaire = QuestionnaireFactory.create(graph=graph)

        # Answer our questionnaire
        first_post_answer_endpoint = f'{self.base_endpoint}{questionnaire.first_question.uuid}/answer'

        # Flow: question 1 -> question 2 -> done
        data = {'payload': 'yes', 'questionnaire': questionnaire.uuid}
        response = self.client.post(first_post_answer_endpoint, data=data, format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response_data['next_question']['uuid'], str(test_question_2.uuid))

        data = {'payload': 'test', 'session': response_data['session']}
        second_post_answer_endpoint = response_data['next_question']['_links']['sia:post-answer']['href']
        response = self.client.post(second_post_answer_endpoint, data=data, format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertIsNone(response_data['next_question'])

        # Flow: question 1 -> question 3 -> done
        data = {'payload': 'no', 'questionnaire': questionnaire.uuid}
        response = self.client.post(first_post_answer_endpoint, data=data, format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response_data['next_question']['uuid'], str(test_question_3.uuid))

        data = {'payload': 'test', 'session': response_data['session']}
        response = self.client.post(second_post_answer_endpoint, data=data, format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertIsNone(response_data['next_question'])

        # Flow: question 1 -> question 4 -> done
        data = {'payload': 'default', 'questionnaire': questionnaire.uuid}
        response = self.client.post(first_post_answer_endpoint, data=data, format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response_data['next_question']['uuid'], str(test_question_4.uuid))

        data = {'payload': 'test', 'session': response_data['session']}
        second_post_answer_endpoint = response_data['next_question']['_links']['sia:post-answer']['href']
        response = self.client.post(second_post_answer_endpoint, data=data, format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, 201)
        self.assertIsNone(response_data['next_question'])

        self.assertEqual(3, Session.objects.count())
        self.assertEqual(6, Answer.objects.count())
    def test_answer_a_complete_questionnaire(self):
        self.assertEqual(0, Answer.objects.count())
        self.assertEqual(0, Session.objects.count())

        questionnaire = QuestionnaireFactory.create(
            first_question__key='test-question-1',
            first_question__next_rules=[{
                'ref': 'test-question-2'
            }])

        second_question = QuestionFactory.create(key='test-question-2',
                                                 next_rules=[{
                                                     'ref':
                                                     'test-question-3'
                                                 }])
        third_question = QuestionFactory.create(key='test-question-3',
                                                next_rules=[{
                                                    'ref':
                                                    'test-question-4'
                                                }])
        fourth_question = QuestionFactory.create(key='test-question-4',
                                                 next_rules=[{
                                                     'ref':
                                                     'test-question-5'
                                                 }])
        fifth_question = QuestionFactory.create(key='test-question-5')

        data = {'payload': 'answer-1', 'questionnaire': questionnaire.uuid}
        first_post_answer_endpoint = f'{self.base_endpoint}{questionnaire.first_question.uuid}/answer'
        response = self.client.post(first_post_answer_endpoint,
                                    data=data,
                                    format='json')
        self.assertEqual(response.status_code, 201)

        response_data = response.json()
        self.assertJsonSchema(self.post_answer_schema, response_data)
        self.assertIsNotNone(response_data['next_question'])

        self.assertEqual(1, Answer.objects.count())
        self.assertEqual(1, Session.objects.count())

        next_post_answer_endpoint = response_data['next_question']['_links'][
            'sia:post-answer']['href']
        session = Session.objects.first()

        for x in range(2, 6):
            data = {'payload': f'answer-{x}', 'session': session.uuid}
            response = self.client.post(next_post_answer_endpoint,
                                        data=data,
                                        format='json')
            self.assertEqual(response.status_code, 201)

            response_data = response.json()
            self.assertJsonSchema(self.post_answer_schema, response_data)

            self.assertEqual(x, Answer.objects.count())
            self.assertEqual(1, Session.objects.count())

            if x < 5:
                self.assertIsNotNone(response_data['next_question'])
                next_post_answer_endpoint = response_data['next_question'][
                    '_links']['sia:post-answer']['href']
            else:
                self.assertIsNotNone(response_data['next_question'])
                self.assertEqual(response_data['next_question']['field_type'],
                                 'submit')
                next_post_answer_endpoint = None

        answer_qs = Answer.objects.filter(
            question_id__in=[
                questionnaire.first_question.id,
                second_question.id,
                third_question.id,
                fourth_question.id,
                fifth_question.id,
            ],
            session_id=session.pk,
        )

        self.assertTrue(answer_qs.exists())
        self.assertEqual(5, answer_qs.count())