def test_repeat_with_answer_value_not_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': 'Number' }] }] }] }, { 'id': 'dependent-group', 'routing_rules': [{ 'repeat': { 'type': 'answer_value', '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), 0) self.assertEqual(dependencies['group_drivers'], []) self.assertEqual(dependencies['block_drivers'], [])
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_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_id='group-1', group_instance=1, value=25, ) for i in range(0, 100): answer.answer_instance = i self.store.add_or_update(answer) last_instance = -1 self.assertEqual(len(self.store), 100) mapped = get_mapped_answers(schema, self.store, block_id='block1', group_instance=1, group_instance_id='group-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_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_is_repeating_answer_type_checkbox(self): survey_json = { 'sections': [{ 'id': 'section1', 'groups': [{ 'id': 'question-group', 'blocks': [ { 'id': 'question-block', 'type': 'Question', 'questions': [{ 'id': 'question', 'type': 'General', 'answers': [{ 'id': 'frequency-answer', 'options': [{ 'value': 'Weekly' }], 'type': 'Checkbox' }] }] } ] }] }] } # STANDARD CHECKBOX schema = QuestionnaireSchema(survey_json) self.assertTrue(schema.is_repeating_answer_type('frequency-answer')) # MUTUALLY EXCLUSIVE CHECKBOX survey_json['sections'][0]['groups'][0]['blocks'][0]['questions'][0]['answers'][0]['type'] = 'MutuallyExclusiveCheckbox' schema = QuestionnaireSchema(survey_json) self.assertTrue(schema.is_repeating_answer_type('frequency-answer'))
def test_dropdown_answer(self): with self._app.test_request_context(): routing_path = [ Location(group_id='dropdown-group', group_instance=0, block_id='dropdown-block') ] user_answer = [ create_answer('dropdown-answer', 'Rugby is better!', group_id='dropdown-group', block_id='dropdown-block') ] questionnaire = make_schema( '0.0.2', 'section-1', 'dropdown-group', 'dropdown-block', [{ 'id': 'dropdown-question', 'answers': [{ 'id': 'dropdown-answer', 'type': 'Dropdown', 'options': [{ 'label': 'Liverpool', 'value': 'Liverpool' }, { 'label': 'Chelsea', 'value': 'Chelsea' }, { 'label': 'Rugby is better!', 'value': 'Rugby is better!' }] }] }]) # When answer_object = convert_answers(self.metadata, self.collection_metadata, QuestionnaireSchema(questionnaire), AnswerStore(user_answer), routing_path) # Then self.assertEqual(len(answer_object['data']), 1) self.assertEqual(answer_object['data'][0]['value'], 'Rugby is better!') self.assertEqual(answer_object['data'][0]['group_instance'], 0) self.assertEqual(answer_object['data'][0]['answer_instance'], 0)
def test_get_summary_for_section(section_with_custom_summary): schema = QuestionnaireSchema(section_with_custom_summary) section_summary = schema.get_summary_for_section("section") expected_keys = { "type", "for_list", "title", "add_link_text", "empty_list_text", "item_title", } assert len(section_summary["items"]) == 1 assert set(section_summary["items"][0].keys()) == expected_keys
def test_convert_payload_0_0_2_multiple_answers(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', 'Sweet chilli'], group_id='favourite-food', block_id='crisps') ] questionnaire = make_schema( '0.0.2', 'section-1', 'favourite-food', 'crisps', [{ 'id': 'crisps-question', 'answers': [{ 'id': 'crisps-answer', 'type': 'Checkbox', 'options': [{ 'label': 'Ready salted', 'value': 'Ready salted' }, { 'label': 'Sweet chilli', 'value': 'Sweet chilli' }, { 'label': 'Cheese and onion', 'value': 'Cheese and onion' }] }] }]) # When answer_object = convert_answers(self.metadata, self.collection_metadata, QuestionnaireSchema(questionnaire), AnswerStore(answers), routing_path) # Then self.assertEqual(len(answer_object['data']), 1) self.assertEqual(answer_object['data'][0]['group_instance'], 0) self.assertEqual(answer_object['data'][0]['answer_instance'], 0) self.assertEqual(answer_object['data'][0]['value'], ['Ready salted', 'Sweet chilli'])
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'} collection_metadata_copy = copy.copy(self.collection_metadata) metadata = self.metadata.copy() metadata.pop('started_at', None) del collection_metadata_copy['started_at'] answer_object = convert_answers(metadata, collection_metadata_copy, QuestionnaireSchema(questionnaire), AnswerStore(), {}) self.assertFalse('started_at' in answer_object)
def load_schema_from_url(survey_url, language_code): language_code = language_code or DEFAULT_LANGUAGE_CODE logger.info( "loading schema from URL", survey_url=survey_url, language_code=language_code ) constructed_survey_url = "{}?language={}".format(survey_url, language_code) req = requests.get(constructed_survey_url) schema_response = req.content.decode() if req.status_code == 404: logger.error("no schema exists", survey_url=constructed_survey_url) raise NotFound return QuestionnaireSchema(json.loads(schema_response), language_code)
def test_questionnaire_store_delete_called(self): questionnaire_store = self.questionnaire_store_mock() questionnaire_store.delete = Mock() with self.app_request_context(): with patch( "app.views.handlers.submission.get_session_store", return_value=self.session_store, ): submission_handler = SubmissionHandler(QuestionnaireSchema({}), questionnaire_store, full_routing_path=[]) submission_handler.submit_questionnaire() assert questionnaire_store.delete.called
def test_only_question_blocks_counted_for_completeness(self): schema_data = { 'sections': [{ 'id': 'section_1', 'groups': [{ 'id': 'group_1', 'blocks': [ { 'id': 'question-block', 'type': 'Question', 'questions': [{ 'id': 'question', 'title': 'foo', 'type': 'general', 'answers': [] }] }, { 'id': 'interstitial-block', 'type': 'Interstitial', 'questions': [{ 'id': 'interstitial-question', 'title': 'bar', 'type': 'general', 'answers': [] }] } ] }] }] } schema = QuestionnaireSchema(schema_data) completed_blocks = [ Location('group_1', 0, 'question-block'), ] routing_path = [ Location('group_1', 0, 'question-block'), Location('group_1', 0, 'interstitial-block'), ] progress = Completeness( schema, AnswerStore(), completed_blocks, routing_path, metadata={}) self.assertEqual(Completeness.COMPLETED, progress.get_state_for_group('group_1')) self.assertEqual(Completeness.COMPLETED, progress.get_state_for_section('section_1')) self.assertTrue(progress.all_sections_complete())
def test_date_answer(self): with self._app.test_request_context(): routing_path = [ Location(group_id='date-group', group_instance=0, block_id='date-block') ] user_answer = [ create_answer('single-date-answer', '1990-02-01', group_id='date-group', block_id='date-block'), create_answer('month-year-answer', '1990-01', group_id='date-group', block_id='date-block') ] questionnaire = make_schema('0.0.1', 'section-1', 'date-block', 'date-block', [{ 'id': 'single-date-question', 'answers': [{ 'id': 'single-date-answer', 'type': 'Date', 'q_code': '1' }] }, { 'id': 'month-year-question', 'answers': [{ 'id': 'month-year-answer', 'type': 'MonthYearDate', 'q_code': '2' }] }]) # When answer_object = convert_answers(self.metadata, self.collection_metadata, QuestionnaireSchema(questionnaire), AnswerStore(user_answer), routing_path) # Then self.assertEqual(len(answer_object['data']), 2) self.assertEqual(answer_object['data']['1'], '01/02/1990') self.assertEqual(answer_object['data']['2'], '01/1990')
def test_convert_answers_to_payload_0_0_1_with_key_error( fake_questionnaire_store): fake_questionnaire_store.answer_store = AnswerStore([ Answer("ABC", "2016-01-01").to_dict(), Answer("DEF", "2016-03-30").to_dict(), Answer("GHI", "2016-05-30").to_dict(), ]) question = { "id": "question-1", "answers": [ { "id": "LMN", "type": "TextField", "q_code": "001" }, { "id": "DEF", "type": "TextField", "q_code": "002" }, { "id": "JKL", "type": "TextField", "q_code": "003" }, ], } questionnaire = make_schema("0.0.1", "section-1", "group-1", "block-1", question) full_routing_path = [ RoutingPath(["block-1"], section_id="section-1", list_item_id=None) ] answer_object = convert_answers_to_payload_0_0_1( fake_questionnaire_store.metadata, fake_questionnaire_store.response_metadata, fake_questionnaire_store.answer_store, fake_questionnaire_store.list_store, QuestionnaireSchema(questionnaire), full_routing_path, ) assert answer_object["002"] == "2016-03-30" assert len(answer_object) == 1
def test_should_minus_one_from_maximum_repeats(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 = { 'answer_id': 'my_answer', 'type': 'answer_count_minus_one' } answer_store = AnswerStore({}) for i in range(27): answer_store.add(Answer(answer_id='my_answer', value='3', answer_instance=i)) current_path = [Location('group-1', 0, 'block-1')] # When answer_on_path = get_answer_ids_on_routing_path(schema, current_path) number_of_repeats = evaluate_repeat(repeat, answer_store, answer_on_path) self.assertEqual(number_of_repeats, 24)
def test_convert_payload_0_0_3_multiple_answers(fake_questionnaire_store): full_routing_path = [RoutingPath(["crisps"], section_id="section-1")] answers = AnswerStore( [Answer("crisps-answer", ["Ready salted", "Sweet chilli"]).to_dict()]) fake_questionnaire_store.answer_store = answers questionnaire = make_schema( "0.0.3", "section-1", "favourite-food", "crisps", { "id": "crisps-question", "answers": [{ "id": "crisps-answer", "type": "Checkbox", "options": [ { "label": "Ready salted", "value": "Ready salted" }, { "label": "Sweet chilli", "value": "Sweet chilli" }, { "label": "Cheese and onion", "value": "Cheese and onion" }, ], }], }, ) # When answer_object = convert_answers(QuestionnaireSchema(questionnaire), fake_questionnaire_store, full_routing_path) # Then assert len(answer_object["data"]["answers"]) == 1 assert answer_object["data"]["answers"][0].value == [ "Ready salted", "Sweet chilli" ]
def test_dropdown_answer(fake_questionnaire_store): full_routing_path = [ RoutingPath(["dropdown-block"], section_id="section-1") ] answers = AnswerStore( [Answer("dropdown-answer", "Rugby is better!").to_dict()]) fake_questionnaire_store.answer_store = answers questionnaire = make_schema( "0.0.3", "section-1", "dropdown-group", "dropdown-block", { "id": "dropdown-question", "answers": [{ "id": "dropdown-answer", "type": "Dropdown", "options": [ { "label": "Liverpool", "value": "Liverpool" }, { "label": "Chelsea", "value": "Chelsea" }, { "label": "Rugby is better!", "value": "Rugby is better!" }, ], }], }, ) answer_object = convert_answers(QuestionnaireSchema(questionnaire), fake_questionnaire_store, full_routing_path) # Then assert len(answer_object["data"]["answers"]) == 1 assert answer_object["data"]["answers"][0].value == "Rugby is better!"
def test_submission_language_code_uses_default_language_if_session_data_language_none( self, ): self.session_data.language_code = None self.session_data.launch_language_code = None session_store = SessionStore("user_ik", "pepper", "eq_session_id").create( "eq_session_id", "user_id", self.session_data, self.expires_at) with patch( "app.views.handlers.submission.get_session_store", return_value=session_store, ): submission_handler = SubmissionHandler( QuestionnaireSchema({}), self.questionnaire_store_mock(), {}) assert submission_handler.get_payload( )["submission_language_code"] == "en"
def test_convert_answers_to_payload_0_0_1_with_key_error(self): with self._app.test_request_context(): user_answer = [ create_answer('ABC', '2016-01-01', group_id='group-1', block_id='block-1'), create_answer('DEF', '2016-03-30', group_id='group-1', block_id='block-1'), create_answer('GHI', '2016-05-30', group_id='group-1', block_id='block-1') ] questionnaire = make_schema('0.0.1', 'section-1', 'group-1', 'block-1', [{ 'id': 'question-1', 'answers': [{ 'id': 'LMN', 'type': 'TextField', 'q_code': '001' }, { 'id': 'DEF', 'type': 'TextField', 'q_code': '002' }, { 'id': 'JKL', 'type': 'TextField', 'q_code': '003' }] }]) routing_path = [ Location(group_id='group-1', group_instance=0, block_id='block-1') ] answer_object = (convert_answers_to_payload_0_0_1( AnswerStore(user_answer), QuestionnaireSchema(questionnaire), routing_path)) self.assertEqual(answer_object['002'], '2016-03-30') self.assertEqual(len(answer_object), 1)
def test_converter_q_codes_for_empty_strings(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', '', group_id='favourite-food', block_id='crisps') ] answers += [ create_answer('other-crisps-answer', 'Ready salted', group_id='favourite-food', block_id='crisps') ] questionnaire = make_schema('0.0.1', 'section-1', 'favourite-food', 'crisps', [{ 'id': 'crisps-question', 'answers': [{ 'id': 'crisps-answer', 'type': 'TextArea', 'options': [], 'q_code': '1' }, { 'id': 'other-crisps-answer', 'type': 'TextArea', 'options': [], 'q_code': '2' }] }]) # When answer_object = convert_answers(self.metadata, self.collection_metadata, QuestionnaireSchema(questionnaire), AnswerStore(answers), routing_path) # Then self.assertEqual(len(answer_object['data']), 1) self.assertEqual(answer_object['data']['2'], 'Ready salted')
def test_submission_language_code_in_payload(self): session_store = self.session_store.create("eq_session_id", "user_id", self.session_data, self.expires_at) storage = Mock() storage.get_user_data = Mock(return_value=("{}", 1)) with patch( "app.views.handlers.submission.get_session_store", return_value=session_store, ): with patch("app.views.handlers.submission.convert_answers", return_value={}): submission_handler = SubmissionHandler( QuestionnaireSchema({}), QuestionnaireStore(storage), {}) assert (submission_handler.get_payload() ["submission_language_code"] == "cy")
def test_confirmation_questions_checked_for_completeness(self): schema_data = { 'sections': [{ 'id': 'section_1', 'groups': [{ 'id': 'group_1', 'blocks': [ { 'id': 'question-block', 'type': 'Question', 'questions': [{ 'id': 'question', 'title': 'foo', 'type': 'general', 'answers': [] }] }, { 'id': 'confirm-question-block', 'type': 'ConfirmationQuestion', 'questions': [{ 'id': 'confirm-question', 'title': 'bar', 'type': 'general', 'answers': [] }] } ] }] }] } schema = QuestionnaireSchema(schema_data) completed_blocks = [ Location('group_1', 0, 'question-block'), ] routing_path = [ Location('group_1', 0, 'question-block'), Location('group_1', 0, 'confirm-question-block'), ] progress = Completeness( schema, AnswerStore(), completed_blocks, routing_path, metadata={}) self.assertEqual(Completeness.STARTED, progress.get_state_for_group('group_1')) self.assertEqual(Completeness.STARTED, progress.get_state_for_section('section_1'))
def test_radio_answer(self): with self._app.test_request_context(): routing_path = [ Location(group_id='radio-group', group_instance=0, block_id='radio-block') ] user_answer = [ create_answer('radio-answer', 'Coffee', group_id='radio-group', block_id='radio-block') ] questionnaire = make_schema('0.0.2', 'section-1', 'radio-group', 'radio-block', [{ 'id': 'radio-question', 'answers': [{ 'type': 'Radio', 'id': 'radio-answer', 'options': [{ 'label': 'Coffee', 'value': 'Coffee' }, { 'label': 'Tea', 'value': 'Tea' }] }] }]) # When answer_object = convert_answers(self.metadata, self.collection_metadata, QuestionnaireSchema(questionnaire), AnswerStore(user_answer), routing_path) # Then self.assertEqual(len(answer_object['data']), 1) self.assertEqual(answer_object['data'][0]['value'], 'Coffee') self.assertEqual(answer_object['data'][0]['group_instance'], 0) self.assertEqual(answer_object['data'][0]['answer_instance'], 0)
def test_transform_variants_with_no_variants(question_schema): schema = QuestionnaireSchema(question_schema) answer_store = AnswerStore({}) 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
def test_get_list_collector_for_list(list_collector_variant_schema): schema = QuestionnaireSchema(list_collector_variant_schema) section = schema.get_section("section") result = QuestionnaireSchema.get_list_collector_for_list(section, for_list="people") assert result["id"] == "block1" filtered_result = QuestionnaireSchema.get_list_collector_for_list( section, for_list="people") assert filtered_result == result no_result = QuestionnaireSchema.get_list_collector_for_list( section, for_list="not-valid") assert no_result is None
def test_should_repeat_for_answer_answer_count_minus_one(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 = {'answer_id': 'my_answer', 'type': 'answer_count_minus_one'} answer_store = AnswerStore({}) answer_store.add_or_update(Answer(answer_id='my_answer', value='3')) answer_store.add_or_update( Answer(answer_id='my_answer', value='4', answer_instance=1)) current_path = [Location('group-1', 0, 'block-1')] # When number_of_repeats = evaluate_repeat(repeat, answer_store, schema, current_path) self.assertEqual(number_of_repeats, 1)
def load_schema_from_url(survey_url, language_code): language_code = language_code or DEFAULT_LANGUAGE_CODE cache_key = (survey_url, language_code) if cache_key not in url_schema_cache: logger.info('loading schema from URL', survey_url=survey_url, language_code=language_code) constructed_survey_url = '{}?language={}'.format(survey_url, language_code) req = requests.get(constructed_survey_url) schema_response = req.content.decode() if req.status_code == 404: logger.error('no schema exists', survey_url=constructed_survey_url) raise NotFound url_schema_cache[cache_key] = QuestionnaireSchema(json.loads(schema_response), language_code) return url_schema_cache[cache_key]
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_radio_answer(fake_questionnaire_store): full_routing_path = [ RoutingPath(["radio-block"], section_id="section-1", list_item_id=None) ] fake_questionnaire_store.answer_store = AnswerStore( [Answer("radio-answer", "Coffee").to_dict()]) question = { "id": "radio-question", "answers": [{ "type": "Radio", "id": "radio-answer", "q_code": "1", "options": [ { "label": "Coffee", "value": "Coffee" }, { "label": "Tea", "value": "Tea" }, ], }], } questionnaire = make_schema("0.0.1", "section-1", "radio-block", "radio-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"] == "Coffee"
def test_unit_answer(fake_questionnaire_store): full_routing_path = [RoutingPath(["unit-block"], section_id="section-1")] answers = AnswerStore([Answer("unit-answer", 10).to_dict()]) fake_questionnaire_store.answer_store = answers questionnaire = make_schema( "0.0.3", "section-1", "unit-group", "unit-block", {"id": "unit-question", "answers": [{"id": "unit-answer", "type": "Unit"}]}, ) answer_object = convert_answers( QuestionnaireSchema(questionnaire), fake_questionnaire_store, full_routing_path ) assert len(answer_object["data"]["answers"]) == 1 assert answer_object["data"]["answers"][0].value == 10