Esempio n. 1
0
def get_schema():
    schema = QuestionnaireSchema(
        {
            "questionnaire_flow": {
                "type": "Linear",
                "options": {"summary": {"collapsible": False}},
            }
        }
    )
    return schema
Esempio n. 2
0
def test_get_group_for_list_collector_child_block():
    survey_json = {
        "sections": [
            {
                "id": "section1",
                "groups": [
                    {
                        "id": "group",
                        "blocks": [
                            {
                                "id": "list-collector",
                                "type": "ListCollector",
                                "for_list": "list",
                                "question": {},
                                "add_block": {
                                    "id": "add-block",
                                    "type": "ListAddQuestion",
                                    "question": {},
                                },
                                "edit_block": {
                                    "id": "edit-block",
                                    "type": "ListEditQuestion",
                                    "question": {},
                                },
                                "remove_block": {
                                    "id": "remove-block",
                                    "type": "ListRemoveQuestion",
                                    "question": {},
                                },
                            }
                        ],
                    }
                ],
            }
        ]
    }

    schema = QuestionnaireSchema(survey_json)

    group = schema.get_group_for_block_id("add-block")

    assert group is not None
    assert group["id"] == "group"
    def test_submission_language_code_in_payload(self):
        with patch(
                "app.views.handlers.submission.get_session_store",
                return_value=self.session_store,
        ):

            submission_handler = SubmissionHandler(
                QuestionnaireSchema({}), self.questionnaire_store_mock(), {})
            assert submission_handler.get_payload(
            )["submission_language_code"] == "cy"
def load_schema_from_params(eq_id, form_type, language_code=None):
    language_code = language_code or DEFAULT_LANGUAGE_CODE
    cache_key = (eq_id, form_type, language_code)

    if cache_key not in schema_cache:
        schema_json = _load_schema_file('{}_{}.json'.format(eq_id, form_type), language_code)

        schema_cache[cache_key] = QuestionnaireSchema(schema_json, language_code)

    return schema_cache[cache_key]
Esempio n. 5
0
def test_transform_variants_list_collector(list_collector_variant_schema):
    schema = QuestionnaireSchema(list_collector_variant_schema)
    answer_store = AnswerStore({})
    answer_store.add_or_update(Answer(answer_id="when-answer", value="no"))
    metadata = {}

    block = schema.get_block("block1")
    section_id = schema.get_section_id_for_block_id(block["id"])

    transformed_block = transform_variants(
        block,
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    compare_transformed_block(block["add_block"],
                              transformed_block["add_block"], "Add, No")
    compare_transformed_block(block["remove_block"],
                              transformed_block["remove_block"], "Remove, No")
    compare_transformed_block(block["edit_block"],
                              transformed_block["edit_block"], "Edit, No")

    answer_store.add_or_update(Answer(answer_id="when-answer", value="yes"))

    transformed_block = transform_variants(
        block,
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    compare_transformed_block(block["add_block"],
                              transformed_block["add_block"], "Add, Yes")
    compare_transformed_block(block["remove_block"],
                              transformed_block["remove_block"], "Remove, Yes")
    compare_transformed_block(block["edit_block"],
                              transformed_block["edit_block"], "Edit, Yes")
Esempio n. 6
0
    def get_state_for_group(self, group, group_instance=None):
        if isinstance(group, str):
            # lookup group by group ID
            group = self.schema.get_group(group)

        if (QuestionnaireSchema.is_confirmation_group(group)
                or QuestionnaireSchema.is_summary_group(group)):
            # summary/confirmations are special cases as we don't want to
            # render until the whole survey is complete. They're also never
            # show as complete
            return self.NOT_STARTED if self.all_sections_complete(
            ) else self.SKIPPED

        if self._should_skip(group):
            return self.SKIPPED

        block_states = [
            state for location, state in self._get_block_states_for_group(
                group, group_instance)
        ]

        def eval_state(state_to_compare):
            return (state == state_to_compare for state in block_states)

        group_state = self.NOT_STARTED

        if all(eval_state(self.SKIPPED)):
            group_state = self.SKIPPED

        elif not self.routing_path:
            group_state = self.NOT_STARTED

        elif all(eval_state(self.INVALID)):
            group_state = self.INVALID

        elif all(state in self.COMPLETED_STATES for state in block_states):
            group_state = self.COMPLETED

        elif any(eval_state(self.COMPLETED)):
            group_state = self.STARTED

        return group_state
Esempio n. 7
0
    def test_relationship_answer(self):
        with self._app.test_request_context():
            routing_path = [Location(group_id='relationship-group', group_instance=0, block_id='relationship-block')]
            user_answer = [create_answer('relationship-answer', 'Unrelated', group_id='relationship-group', block_id='relationship-block'),
                           create_answer('relationship-answer', 'Partner', group_id='relationship-group', block_id='relationship-block',
                                         answer_instance=1),
                           create_answer('relationship-answer', 'Husband or wife', group_id='relationship-group', block_id='relationship-block',
                                         answer_instance=2)]

            questionnaire = make_schema('0.0.2', 'section-1', 'relationship-group', 'relationship-block', [
                {
                    'id': 'relationship-question',
                    'type': 'Relationship',
                    'answers': [
                        {
                            'id': 'relationship-answer',
                            'q_code': '1',
                            'type': 'Relationship',
                            'options': [
                                {
                                    'label': 'Husband or wife',
                                    'value': 'Husband or wife'
                                },
                                {
                                    'label': 'Partner',
                                    'value': 'Partner'
                                },
                                {
                                    'label': 'Unrelated',
                                    'value': 'Unrelated'
                                }
                            ]
                        }
                    ]
                }
            ])

            # When
            answer_object = convert_answers(self.metadata, self.collection_metadata, QuestionnaireSchema(questionnaire), AnswerStore(user_answer), routing_path)

            # Then
            self.assertEqual(len(answer_object['data']), 3)
            self.assertEqual(answer_object['data'][0]['value'], 'Unrelated')

            self.assertEqual(answer_object['data'][0]['group_instance'], 0)
            self.assertEqual(answer_object['data'][0]['answer_instance'], 0)

            self.assertEqual(answer_object['data'][1]['value'], 'Partner')
            self.assertEqual(answer_object['data'][1]['group_instance'], 0)
            self.assertEqual(answer_object['data'][1]['answer_instance'], 1)

            self.assertEqual(answer_object['data'][2]['value'], 'Husband or wife')
            self.assertEqual(answer_object['data'][2]['group_instance'], 0)
            self.assertEqual(answer_object['data'][2]['answer_instance'], 2)
def test_transform_variants_with_no_variants(question_schema):
    schema = QuestionnaireSchema(question_schema)
    answer_store = AnswerStore({})
    metadata = {}
    response_metadata = {}

    block = schema.get_block("block1")
    section_id = schema.get_section_id_for_block_id(block["id"])

    transformed_block = transform_variants(
        block,
        schema,
        metadata,
        response_metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    assert transformed_block == block
Esempio n. 9
0
    def test_get_checkbox_answer_with_duplicate_child_answer_ids(self):
        with self._app.test_request_context():
            routing_path = [
                Location(group_id='favourite-food',
                         group_instance=0,
                         block_id='crisps')
            ]
            answers = [
                create_answer('crisps-answer', ['Ready salted', 'Other'],
                              group_id='favourite-food',
                              block_id='crisps')
            ]

            answers += [
                create_answer('other-answer-mandatory',
                              'Other',
                              group_id='favourite-food',
                              block_id='crisps',
                              group_instance=1)
            ]
            answers += [
                create_answer('other-answer-mandatory',
                              'Other',
                              group_id='favourite-food',
                              block_id='crisps',
                              group_instance=1)
            ]

            questionnaire = make_schema(
                '0.0.1', 'section-1', 'favourite-food', 'crisps', [{
                    'id':
                    'crisps-question',
                    'answers': [{
                        'id':
                        'crisps-answer',
                        'type':
                        'Checkbox',
                        'options': [{
                            'label': 'Other',
                            'q_code': '4',
                            'description': 'Choose any other flavour',
                            'value': 'Other',
                            'child_answer_id': 'other-answer-mandatory'
                        }]
                    }]
                }])

        with self.assertRaises(Exception) as err:
            convert_answers(self.metadata, self.collection_metadata,
                            QuestionnaireSchema(questionnaire),
                            AnswerStore(answers), routing_path)
        self.assertEqual(
            'Multiple answers found for {}'.format('other-answer-mandatory'),
            str(err.exception))
def test_has_expired_no_submitted_at_return_false(storage, language, app):
    with app.app_context():
        set_storage_data(storage)
        questionnaire_store = QuestionnaireStore(storage)
        schema = QuestionnaireSchema(
            {"post_submission": {
                "view_response": True
            }})
        view_submitted_response = ViewSubmittedResponse(
            schema, questionnaire_store, language)
        assert view_submitted_response.has_expired is False
Esempio n. 11
0
    def test_returns_ordered_map(self):

        questionnaire = {
            'sections': [{
                'id':
                'section1',
                'groups': [{
                    'id':
                    'group1',
                    'blocks': [{
                        'id':
                        'block1',
                        'questions': [{
                            'id':
                            'question1',
                            'answers': [{
                                'id': 'answer1',
                                'type': 'TextArea'
                            }]
                        }]
                    }]
                }]
            }]
        }
        schema = QuestionnaireSchema(questionnaire)

        answer = Answer(
            answer_id='answer1',
            group_instance=1,
            value=25,
        )

        for i in range(0, 100):
            answer.answer_instance = i

            self.store.add(answer)

        last_instance = -1

        self.assertEqual(len(self.store.answers), 100)

        mapped = get_mapped_answers(schema,
                                    self.store,
                                    block_id='block1',
                                    group_instance=1)

        for key, _ in mapped.items():
            pos = key.find('_')

            instance = 0 if pos == -1 else int(key[pos + 1:])

            self.assertGreater(instance, last_instance)

            last_instance = instance
    def test_convert_answers_flushed_flag_default_is_false(self):
        with self._app.test_request_context():
            user_answer = [create_answer('GHI', 0)]

            questionnaire = {'survey_id': '021', 'data_version': '0.0.2'}

            answer_object = convert_answers(self.metadata,
                                            QuestionnaireSchema(questionnaire),
                                            AnswerStore(user_answer), {})

            self.assertFalse(answer_object['flushed'])
    def test_case_ref_should_be_set_in_payload(self):
        with self._app.test_request_context():

            questionnaire = {'survey_id': '021', 'data_version': '0.0.2'}

            answer_object = convert_answers(self.metadata,
                                            QuestionnaireSchema(questionnaire),
                                            AnswerStore(), {})

            self.assertEqual(answer_object['case_ref'],
                             self.metadata['case_ref'])
    def test_converter_raises_runtime_error_for_unsupported_version(self):
        with self._app.test_request_context():
            questionnaire = {'survey_id': '021', 'data_version': '-0.0.1'}

            with self.assertRaises(DataVersionError) as err:
                convert_answers(self.metadata,
                                QuestionnaireSchema(questionnaire),
                                AnswerStore(), {})

            self.assertEqual(str(err.exception),
                             'Data version -0.0.1 not supported')
def test_converter_raises_runtime_error_for_unsupported_version(
    fake_questionnaire_store,
):
    questionnaire = {"survey_id": "021", "data_version": "-0.0.1"}

    with pytest.raises(DataVersionError) as err:
        convert_answers(
            QuestionnaireSchema(questionnaire), fake_questionnaire_store, {}
        )

    assert "Data version -0.0.1 not supported" in str(err.value)
    def test_ref_period_end_date_is_not_in_output(self):
        with self._app.test_request_context():
            user_answer = [create_answer('GHI', 0)]

            questionnaire = {'survey_id': '021', 'data_version': '0.0.2'}
            self.metadata['ref_p_end_date'] = None
            answer_object = convert_answers(self.metadata,
                                            self.collection_metadata,
                                            QuestionnaireSchema(questionnaire),
                                            AnswerStore(user_answer), {})
            self.assertFalse(
                'ref_period_end_date' in answer_object['metadata'])

            del self.metadata['ref_p_end_date']
            answer_object = convert_answers(self.metadata,
                                            self.collection_metadata,
                                            QuestionnaireSchema(questionnaire),
                                            AnswerStore(user_answer), {})
            self.assertFalse(
                'ref_period_end_date' in answer_object['metadata'])
    def test_should_repeat_for_answer_until(self):
        questionnaire = {
            'survey_id': '021',
            'data_version': '0.0.1',
            'sections': [{
                'id': 'section1',
                'groups': [
                    {
                        'id': 'group-1',
                        'blocks': [
                            {
                                'id': 'block-1',
                                'questions': [{
                                    'id': 'question-2',
                                    'answers': [
                                        {
                                            'id': 'my_answer',
                                            'type': 'TextField'
                                        }
                                    ]
                                }]
                            }
                        ]
                    }
                ]
            }]
        }

        schema = QuestionnaireSchema(questionnaire)

        # Given
        repeat = {
            'type': 'until',
            'when': [
                {
                    'id': 'my_answer',
                    'condition': 'equals',
                    'value': 'Done'
                }
            ]
        }

        answer_store = AnswerStore({})
        current_path = [Location('group-1', 0, 'block-1')]
        answer_on_path = get_answer_ids_on_routing_path(schema, current_path)

        self.assertEqual(evaluate_repeat(repeat, answer_store, answer_on_path), 1)

        answer_store.add(Answer(answer_id='my_answer', value='Not Done', group_instance=0))
        self.assertEqual(evaluate_repeat(repeat, answer_store, answer_on_path), 2)

        answer_store.add(Answer(answer_id='my_answer', value='Done', group_instance=1))
        self.assertEqual(evaluate_repeat(repeat, answer_store, answer_on_path), 2)
Esempio n. 18
0
    def test_path_finder_instantiated_once(self, mock_path_finder, _, __, ___):
        g.schema = QuestionnaireSchema({})

        # Werkzeug LocalProxy only instantiates an object on
        # attribute access. We use an example of a fake
        # method call to check the mock (which will be the PathFinder
        # class outside of this test) is only called once.
        with self.app_request_context():
            path_finder.some_method_call()
            path_finder.some_method_call()

        self.assertEqual(1, len(mock_path_finder.mock_calls))
    def test_group_has_questions_returns_false_when_group_doesnt_have_questionnaire_blocks(self):
        survey_json = {
            'sections': [{
                'id': 'section1',
                'groups': [{
                    'id': 'non-question-group',
                    'blocks': [
                        {
                            'id': 'summary-block',
                            'type': 'Summary'
                        }
                    ]
                }]
            }]
        }

        schema = QuestionnaireSchema(survey_json)

        has_questions = schema.group_has_questions('non-question-group')

        self.assertFalse(has_questions)
Esempio n. 20
0
def test_transform_variants_with_content(content_variant_schema):
    schema = QuestionnaireSchema(content_variant_schema)
    answer_store = AnswerStore({})
    answer_store.add_or_update(Answer(answer_id="age-answer", value="18"))
    metadata = {}

    block = schema.get_block("block1")
    section_id = schema.get_section_id_for_block_id(block["id"])

    transformed_block = transform_variants(
        block,
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    assert transformed_block != block
    assert "content_variants" not in transformed_block
    assert transformed_block["content"][0]["title"] == "You are over 16"
    def test_is_confirmation(self):
        survey_json = {
            'sections': [{
                'id': 'section-1',
                'groups': [{
                    'id': 'group-1',
                    'blocks': [
                        {
                            'id': 'block-1',
                            'type': 'Confirmation'
                        }
                    ]
                }]
            }]
        }

        schema = QuestionnaireSchema(survey_json)
        self.assertTrue(schema.is_confirmation_section(schema.get_section('section-1')))
        self.assertTrue(schema.is_confirmation_group(schema.get_group('group-1')))
        self.assertFalse(schema.is_summary_section(schema.get_section('section-1')))
        self.assertFalse(schema.is_summary_group(schema.get_group('group-1')))
Esempio n. 22
0
def test_choose_question_to_display(question_variant_schema):
    schema = QuestionnaireSchema(question_variant_schema)
    answer_store = AnswerStore({})
    answer_store.add_or_update(Answer(answer_id="when-answer", value="yes"))
    metadata = {}

    block = schema.get_block("block1")
    section_id = schema.get_section_id_for_block_id(block["id"])

    question_to_display = choose_question_to_display(
        schema.get_block("block1"),
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    assert question_to_display["title"] == "Question 1, Yes"

    answer_store = AnswerStore({})

    question_to_display = choose_question_to_display(
        schema.get_block("block1"),
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    assert question_to_display["title"] == "Question 1, No"
Esempio n. 23
0
def test_choose_content_to_display(content_variant_schema):
    schema = QuestionnaireSchema(content_variant_schema)
    answer_store = AnswerStore({})
    answer_store.add_or_update(Answer(answer_id="age-answer", value="18"))
    metadata = {}

    block = schema.get_block("block1")
    section_id = schema.get_section_id_for_block_id(block["id"])

    content_to_display = choose_content_to_display(
        schema.get_block("block1"),
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    assert content_to_display[0]["title"] == "You are over 16"

    answer_store = AnswerStore({})

    content_to_display = choose_content_to_display(
        schema.get_block("block1"),
        schema,
        metadata,
        answer_store,
        ListStore({}),
        Location(section_id=section_id, block_id=block["id"]),
    )

    assert content_to_display[0]["title"] == "You are ageless"
    def test_started_at_should_be_set_in_payload_if_present_in_collection_metadata(
            self):
        with self._app.test_request_context():

            questionnaire = {'survey_id': '021', 'data_version': '0.0.2'}

            answer_object = convert_answers(self.metadata,
                                            self.collection_metadata,
                                            QuestionnaireSchema(questionnaire),
                                            AnswerStore(), {})

            self.assertEqual(answer_object['started_at'],
                             self.collection_metadata['started_at'])
    def test_convert_answers_flushed_flag_overriden_to_true(self):
        with self._app.test_request_context():
            user_answer = [create_answer('GHI', 0)]

            questionnaire = {'survey_id': '021', 'data_version': '0.0.2'}

            answer_object = convert_answers(self.metadata,
                                            self.collection_metadata,
                                            QuestionnaireSchema(questionnaire),
                                            AnswerStore(user_answer), {},
                                            flushed=True)

            self.assertTrue(answer_object['flushed'])
    def test_started_at_should_not_be_set_in_payload_if_absent_in_metadata(
            self):
        with self._app.test_request_context():

            questionnaire = {'survey_id': '021', 'data_version': '0.0.2'}
            metadata_copy = copy.copy(self.metadata)
            del metadata_copy['started_at']

            answer_object = convert_answers(metadata_copy,
                                            QuestionnaireSchema(questionnaire),
                                            AnswerStore(), {})

            self.assertFalse('started_at' in answer_object)
    def test_repeat_with_answer_count_minus_one_added_to_dependencies(self):
        survey_json = {
            'sections': [{
                'id': 'default-section',
                'groups': [
                    {
                        'id': 'driving-group',
                        'blocks': [{
                            'type': 'Question',
                            'id': 'driving-block',
                            'questions': [{
                                'id': 'driving-question',
                                'type': 'General',
                                'answers': [{
                                    'id': 'driving-answer',
                                    'type': 'TextField'
                                }]
                            }]
                        }]
                    },
                    {
                        'id': 'dependent-group',
                        'routing_rules': [{
                            'repeat': {
                                'type': 'answer_count_minus_one',
                                'answer_id': 'driving-answer'
                            }
                        }],
                        'blocks': [{
                            'type': 'Question',
                            'id': 'dependent-block',
                            'questions': [{
                                'id': 'dependent-question',
                                'type': 'General',
                                'answers': [{
                                    'id': 'dependent-answer',
                                    'type': 'TextField'
                                }]
                            }]
                        }]
                    }]
            }]
        }

        schema = QuestionnaireSchema(survey_json)
        dependencies = get_group_dependencies(schema)

        self.assertEqual(len(dependencies), 1)
        self.assertEqual(dependencies['dependent-group'], ['driving-block'])
        self.assertEqual(dependencies['group_drivers'], [])
        self.assertEqual(dependencies['block_drivers'], ['driving-block'])
    def test_ref_period_start_and_end_date_is_in_output(self):
        with self._app.test_request_context():
            user_answer = [create_answer('GHI', 0)]

            questionnaire = {'survey_id': '021', 'data_version': '0.0.2'}

            answer_object = convert_answers(self.metadata,
                                            QuestionnaireSchema(questionnaire),
                                            AnswerStore(user_answer), {})
            self.assertEqual(
                answer_object['metadata']['ref_period_start_date'],
                '2016-02-02')
            self.assertEqual(answer_object['metadata']['ref_period_end_date'],
                             '2016-03-03')
    def test_submitted_at_should_be_set_in_payload(self):
        with self._app.test_request_context():
            user_answer = [create_answer('GHI', 0)]

            questionnaire = {'survey_id': '021', 'data_version': '0.0.2'}

            answer_object = convert_answers(self.metadata,
                                            QuestionnaireSchema(questionnaire),
                                            AnswerStore(user_answer), {})

            self.assertLess(
                datetime.now(timezone.utc) -
                dateutil.parser.parse(answer_object['submitted_at']),
                timedelta(seconds=5))
def test_dropdown_answer(fake_questionnaire_store):
    full_routing_path = [
        RoutingPath(["dropdown-block"],
                    section_id="section-1",
                    list_item_id=None)
    ]
    fake_questionnaire_store.answer_store = AnswerStore(
        [Answer("dropdown-answer", "Liverpool").to_dict()])

    question = {
        "id":
        "dropdown-question",
        "answers": [{
            "id":
            "dropdown-answer",
            "type":
            "Dropdown",
            "q_code":
            "1",
            "options": [
                {
                    "label": "Liverpool",
                    "value": "Liverpool"
                },
                {
                    "label": "Chelsea",
                    "value": "Chelsea"
                },
                {
                    "label": "Rugby is better!",
                    "value": "Rugby is better!"
                },
            ],
        }],
    }

    questionnaire = make_schema("0.0.1", "section-1", "dropdown-block",
                                "dropdown-block", question)

    # When
    answer_object = convert_answers(
        QuestionnaireSchema(questionnaire),
        fake_questionnaire_store,
        full_routing_path,
        SUBMITTED_AT,
    )

    # Then
    assert len(answer_object["data"]) == 1
    assert answer_object["data"]["1"] == "Liverpool"