Ejemplo n.º 1
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
Ejemplo n.º 2
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
Ejemplo n.º 3
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
    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)
Ejemplo n.º 5
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
Ejemplo n.º 6
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
    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)
Ejemplo n.º 8
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
Ejemplo n.º 9
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
Ejemplo n.º 10
0
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
Ejemplo n.º 11
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
Ejemplo n.º 12
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)
Ejemplo n.º 13
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
Ejemplo n.º 14
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)
Ejemplo n.º 15
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())
    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())