Пример #1
0
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 _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)
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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
Пример #6
0
    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)
Пример #7
0
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)
Пример #8
0
    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)
Пример #9
0
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
Пример #10
0
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):
        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)
Пример #13
0
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
Пример #14
0
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
Пример #15
0
def _question_graph_no_required_answers():
    q1 = QuestionFactory.create(
        retrieval_key='one',
        required=False,
        short_label='First not required',
        label='First not required',
    )
    q2 = QuestionFactory(
        retrieval_key='two',
        required=False,
        short_label='Second not required',
        label='Second not required',
    )

    graph = QuestionGraphFactory.create(
        name='Graph with questions that are not required.', first_question=q1)
    EdgeFactory.create(graph=graph, question=q1, next_question=q2, choice=None)

    return graph
Пример #16
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)
Пример #17
0
    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?',
            analysis_key='reaction',
        )
        graph = QuestionGraphFactory.create(name='Reactie gevraagd.', first_question=question)
        session = SessionFactory.create(
            questionnaire__flow=Questionnaire.REACTION_REQUEST,
            questionnaire__graph=graph,
            frozen=False,
            _signal=self.signal_reaction_requested
        )
        answer = AnswerFactory(session=session, payload='Het antwoord!')

        service = get_session_service(session.uuid)
        self.assertIsInstance(service, ReactionRequestSessionService)
        service.freeze()

        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)
Пример #18
0
    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)
Пример #19
0
    def test_get_next_question_private(self):
        q_start = QuestionFactory.create(retrieval_key='start',
                                         field_type='plain_text')

        # No next rules:
        empty_graph = QuestionGraphFactory.create(first_question=q_start)

        session = SessionFactory.create(questionnaire__graph=empty_graph)
        session_service = get_session_service(session.uuid)
        session_service.refresh_from_db()

        next_q = session_service._get_next_question(
            session_service.question_graph_service._nx_graph,
            session_service.question_graph_service._questions_by_id, q_start,
            'ANSWER')
        self.assertIsNone(next_q)

        # Unconditional next:
        q2 = QuestionFactory.create()
        unconditional_graph = QuestionGraphFactory.create(
            first_question=q_start)
        EdgeFactory(graph=unconditional_graph,
                    question=q_start,
                    next_question=q2,
                    choice=None)

        session = SessionFactory.create(
            questionnaire__graph=unconditional_graph)
        session_service = get_session_service(session.uuid)
        session_service.refresh_from_db()

        next_q = session_service._get_next_question(
            session_service.question_graph_service._nx_graph,
            session_service.question_graph_service._questions_by_id, q_start,
            'ANSWER')
        self.assertEqual(next_q, q2)

        # Conditional next, no default option:
        q_no = QuestionFactory.create(retrieval_key='NO')
        q_yes = QuestionFactory.create(retrieval_key='YES')
        conditional_graph = QuestionGraphFactory.create(first_question=q_start)
        EdgeFactory(graph=conditional_graph,
                    question=q_start,
                    next_question=q_no,
                    choice__payload='no',
                    choice__question=q_start)
        EdgeFactory(graph=conditional_graph,
                    question=q_start,
                    next_question=q_yes,
                    choice__payload='yes',
                    choice__question=q_start)

        session = SessionFactory.create(questionnaire__graph=conditional_graph)
        session_service = get_session_service(session.uuid)
        session_service.refresh_from_db()

        no_choice_question = session_service._get_next_question(
            session_service.question_graph_service._nx_graph,
            session_service.question_graph_service._questions_by_id, q_start,
            'ANSWER')
        self.assertIsNone(
            no_choice_question)  # consider whether this is useful
        yes_question = session_service._get_next_question(
            session_service.question_graph_service._nx_graph,
            session_service.question_graph_service._questions_by_id, q_start,
            'yes')
        self.assertEqual(q_yes, yes_question)
        no_question = session_service._get_next_question(
            session_service.question_graph_service._nx_graph,
            session_service.question_graph_service._questions_by_id, q_start,
            'no')
        self.assertEqual(q_no, no_question)

        # Conditional next with default option defined:
        q_default = QuestionFactory.create(retrieval_key='DEFAULT')
        conditional_with_default_graph = QuestionGraphFactory.create(
            first_question=q_start)
        EdgeFactory(graph=conditional_with_default_graph,
                    question=q_start,
                    next_question=q_no,
                    choice__payload='no',
                    choice__question=q_start)
        EdgeFactory(graph=conditional_with_default_graph,
                    question=q_start,
                    next_question=q_yes,
                    choice__payload='yes',
                    choice__question=q_start)
        EdgeFactory(graph=conditional_with_default_graph,
                    question=q_start,
                    next_question=q_default,
                    choice=None)

        session = SessionFactory.create(
            questionnaire__graph=conditional_with_default_graph)
        session_service = get_session_service(session.uuid)
        session_service.refresh_from_db()

        no_choice_question = session_service._get_next_question(
            session_service.question_graph_service._nx_graph,
            session_service.question_graph_service._questions_by_id, q_start,
            'ANSWER')
        self.assertEqual(no_choice_question, q_default)
        yes_question = session_service._get_next_question(
            session_service.question_graph_service._nx_graph,
            session_service.question_graph_service._questions_by_id, q_start,
            'yes')
        self.assertEqual(yes_question, q_yes)
        no_question = session_service._get_next_question(
            session_service.question_graph_service._nx_graph,
            session_service.question_graph_service._questions_by_id, q_start,
            'no')
        self.assertEqual(no_question, q_no)
    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())
Пример #21
0
def create_one(graph_name='one'):
    q1 = QuestionFactory.create(analysis_key='q1')
    # sketch:
    # q1 <- first_question
    return QuestionGraphFactory.create(name=graph_name, first_question=q1)
Пример #22
0
def create_empty(graph_name='empty'):
    return QuestionGraphFactory.create(name=graph_name, first_question=None)
    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())