def test_post_form_for_household_composition(self): survey = load_schema_file("census_household.json") block_json = SchemaHelper.get_block(survey, 'household-composition') location = Location('who-lives-here', 0, 'household-composition') error_messages = SchemaHelper.get_messages(survey) form, _ = post_form_for_location( block_json, location, AnswerStore(), { 'household-0-first-name': 'Joe', 'household-0-last-name': '', 'household-1-first-name': 'Bob', 'household-1-last-name': 'Seymour', }, error_messages) self.assertEqual(len(form.household.entries), 2) self.assertEqual(form.household.entries[0].data, { 'first-name': 'Joe', 'middle-names': '', 'last-name': '' }) self.assertEqual(form.household.entries[1].data, { 'first-name': 'Bob', 'middle-names': '', 'last-name': 'Seymour' })
def get_block(eq_id, form_type, collection_id, group_id, group_instance, block_id): # pylint: disable=unused-argument # Filter answers down to those we may need to render answer_store = get_answer_store(current_user) path_finder = PathFinder(g.schema_json, answer_store, get_metadata(current_user)) current_location = Location(group_id, group_instance, block_id) valid_group = group_id in SchemaHelper.get_group_ids(g.schema_json) if not valid_group or current_location not in path_finder.get_routing_path(group_id, group_instance): raise NotFound block = _render_schema(current_location) error_messages = SchemaHelper.get_messages(g.schema_json) form, template_params = get_form_for_location(block, current_location, answer_store, error_messages) content = {'form': form, 'block': block} if template_params: content.update(template_params) template = block['type'] if block and 'type' in block and block['type'] else 'questionnaire' return _build_template(current_location, content, template)
def setUp(self): super().setUp() survey = load_schema_file("census_household.json") self.block_json = SchemaHelper.get_block(survey, 'household-composition') self.error_messages = SchemaHelper.get_messages(survey)
def test_get_form_deserialises_month_year_dates(self): survey = load_schema_file("test_dates.json") block_json = SchemaHelper.get_block(survey, "date-block") location = SchemaHelper.get_first_location(survey) error_messages = SchemaHelper.get_messages(survey) form, _ = get_form_for_location( block_json, location, AnswerStore([{ 'answer_id': 'month-year-answer', 'group_id': 'a23d36db-6b07-4ce0-94b2-a843369511e3', 'group_instance': 0, 'block_id': 'date-block', 'value': '05/2015', 'answer_instance': 0, }]), error_messages) self.assertTrue(hasattr(form, "month-year-answer")) month_year_field = getattr(form, "month-year-answer") self.assertEquals(month_year_field.data, { 'month': '5', 'year': '2015', })
def test_form_date_range_populates_data(self): with self.test_request_context(): survey = load_schema_file("1_0102.json") block_json = SchemaHelper.get_block(survey, "reporting-period") error_messages = SchemaHelper.get_messages(survey) data = { 'period-from-day': '01', 'period-from-month': '3', 'period-from-year': '2016', 'period-to-day': '31', 'period-to-month': '3', 'period-to-year': '2016' } expected_form_data = { 'csrf_token': '', 'period-from': { 'day': '01', 'month': '3', 'year': '2016' }, 'period-to': { 'day': '31', 'month': '3', 'year': '2016' } } form = generate_form(block_json, data, error_messages) self.assertEqual(form.data, expected_form_data)
def test_post_form_for_radio_other_selected(self): with self.test_request_context(): survey = load_schema_file("test_radio.json") block_json = SchemaHelper.get_block(survey, 'radio-mandatory') location = Location('radio', 0, 'radio-mandatory') error_messages = SchemaHelper.get_messages(survey) answer_store = AnswerStore([{ 'answer_id': 'radio-mandatory-answer', 'block_id': 'radio-mandatory', 'value': 'Other', 'answer_instance': 0, }, { 'answer_id': 'other-answer-mandatory', 'block_id': 'block-1', 'value': 'Other text field value', 'answer_instance': 0, }]) radio_answer = SchemaHelper.get_first_answer_for_block(block_json) text_answer = 'other-answer-mandatory' form, _ = post_form_for_location( block_json, location, answer_store, MultiDict({ '{answer_id}'.format(answer_id=radio_answer['id']): 'Other', '{answer_id}'.format(answer_id=text_answer): 'Other text field value', }), error_messages) other_text_field = getattr(form, 'other-answer-mandatory') self.assertEqual(other_text_field.data, 'Other text field value')
def test_generate_relationship_form_errors_are_correctly_mapped(self): with self.test_request_context(): survey = load_schema_file("test_relationship_household.json") block_json = SchemaHelper.get_block(survey, 'relationships') error_messages = SchemaHelper.get_messages(survey) answer = SchemaHelper.get_first_answer_for_block(block_json) generated_form = generate_relationship_form( block_json, 3, None, error_messages=error_messages) form = generate_relationship_form( block_json, 3, { 'csrf_token': generated_form.csrf_token.current_token, '{answer_id}-0'.format(answer_id=answer['id']): '1', '{answer_id}-1'.format(answer_id=answer['id']): '3', }, error_messages=error_messages) form.validate() mapped_errors = form.map_errors() message = "Not a valid choice" self.assertTrue( self._error_exists(answer['id'], message, mapped_errors))
def test_generate_relationship_form_creates_form_from_data(self): with self.test_request_context(): survey = load_schema_file("test_relationship_household.json") block_json = SchemaHelper.get_block(survey, 'relationships') error_messages = SchemaHelper.get_messages(survey) answer = SchemaHelper.get_first_answer_for_block(block_json) form = generate_relationship_form( block_json, 3, { '{answer_id}-0'.format(answer_id=answer['id']): 'Husband or Wife', '{answer_id}-1'.format(answer_id=answer['id']): 'Brother or Sister', '{answer_id}-2'.format(answer_id=answer['id']): 'Relation - other', }, error_messages=error_messages) self.assertTrue(hasattr(form, answer['id'])) expected_form_data = [ 'Husband or Wife', 'Brother or Sister', 'Relation - other' ] self.assertEqual(form.data[answer['id']], expected_form_data)
def setUp(self): self.app = create_app() self.app.config['SERVER_NAME'] = "test" self.app_context = self.app.app_context() self.app_context.push() survey = load_schema_file("census_household.json") self.block_json = SchemaHelper.get_block(survey, 'household-composition') self.error_messages = SchemaHelper.get_messages(survey)
def test_form_ids_match_block_answer_ids(self): survey = load_schema_file("1_0102.json") block_json = SchemaHelper.get_block(survey, "reporting-period") error_messages = SchemaHelper.get_messages(survey) form = generate_form(block_json, {}, error_messages) for answer in SchemaHelper.get_answers_for_block(block_json): self.assertTrue(hasattr(form, answer['id']))
def test_option_has_other(self): with self.test_request_context(): survey = load_schema_file("test_checkbox.json") block_json = SchemaHelper.get_block(survey, "mandatory-checkbox") error_messages = SchemaHelper.get_messages(survey) form = generate_form(block_json, {}, error_messages) self.assertFalse( form.option_has_other("mandatory-checkbox-answer", 1)) self.assertTrue( form.option_has_other("mandatory-checkbox-answer", 6))
def post_household_composition(eq_id, form_type, collection_id, group_id): # pylint: disable=too-many-locals answer_store = get_answer_store(current_user) if _household_answers_changed(answer_store): _remove_repeating_on_household_answers(answer_store, group_id) error_messages = SchemaHelper.get_messages(g.schema_json) disable_mandatory = any(x in request.form for x in [ 'action[add_answer]', 'action[remove_answer]', 'action[save_sign_out]' ]) current_location = Location(group_id, 0, 'household-composition') block = _render_schema(current_location) form, _ = post_form_for_location(block, current_location, answer_store, request.form, error_messages, disable_mandatory=disable_mandatory) if 'action[add_answer]' in request.form: form.household.append_entry() elif 'action[remove_answer]' in request.form: index_to_remove = int(request.form.get('action[remove_answer]')) form.remove_person(index_to_remove) elif 'action[save_sign_out]' in request.form: response = _save_sign_out(collection_id, eq_id, form_type, current_location, form) remove_empty_household_members_from_answer_store( answer_store, group_id) return response if _is_invalid_form( form ) or 'action[add_answer]' in request.form or 'action[remove_answer]' in request.form: context = {'form': form, 'block': block} return _build_template(current_location, context, template='questionnaire') else: questionnaire_store = get_questionnaire_store(current_user.user_id, current_user.user_ik) update_questionnaire_store_with_answer_data( questionnaire_store, current_location, form.serialise(current_location)) metadata = get_metadata(current_user) path_finder = PathFinder(g.schema_json, get_answer_store(current_user), metadata) next_location = path_finder.get_next_location( current_location=current_location) return redirect(next_location.url(metadata))
def test_generate_relationship_form_creates_empty_form(self): survey = load_schema_file("test_relationship_household.json") block_json = SchemaHelper.get_block(survey, 'relationships') error_messages = SchemaHelper.get_messages(survey) answer = SchemaHelper.get_first_answer_for_block(block_json) form = generate_relationship_form(block_json, 3, {}, error_messages=error_messages) self.assertTrue(hasattr(form, answer['id'])) self.assertEqual(len(form.data[answer['id']]), 3)
def test_get_other_answer_invalid(self): with self.test_request_context(): survey = load_schema_file("test_checkbox.json") block_json = SchemaHelper.get_block(survey, "mandatory-checkbox") error_messages = SchemaHelper.get_messages(survey) form = generate_form(block_json, {"other-answer-mandatory": "Some data"}, error_messages) field = form.get_other_answer("mandatory-checkbox-answer", 4) self.assertEqual(None, field)
def test_generate_month_year_date_form_creates_empty_form(self): survey = load_schema_file("test_dates.json") block_json = SchemaHelper.get_block(survey, 'date-block') error_messages = SchemaHelper.get_messages(survey) answers = SchemaHelper.get_answers_by_id_for_block(block_json) form = get_month_year_form(answers['month-year-answer'], error_messages=error_messages) self.assertFalse(hasattr(form, 'day')) self.assertTrue(hasattr(form, 'month')) self.assertTrue(hasattr(form, 'year'))
def test_answer_with_child_inherits_mandatory_from_parent(self): with self.test_request_context(): survey = load_schema_file("test_radio.json") block_json = SchemaHelper.get_block(survey, "radio-mandatory") error_messages = SchemaHelper.get_messages(survey) form = generate_form(block_json, {'radio-mandatory-answer': 'Other'}, error_messages) child_field = getattr(form, 'other-answer-mandatory') self.assertIsInstance(child_field.validators[0], ResponseRequired)
def test_get_form_for_household_relationship(self): with self.test_request_context(): survey = load_schema_file("census_household.json") block_json = SchemaHelper.get_block(survey, 'household-relationships') location = Location('who-lives-here-relationship', 0, 'household-relationships') error_messages = SchemaHelper.get_messages(survey) answer_store = AnswerStore([{ 'group_id': 'who-lives-here-relationship', 'group_instance': 0, 'answer_id': 'first-name', 'block_id': 'household-composition', 'value': 'Joe', 'answer_instance': 0, }, { 'group_id': 'who-lives-here-relationship', 'group_instance': 0, 'answer_id': 'last-name', 'block_id': 'household-composition', 'value': 'Bloggs', 'answer_instance': 0, }, { 'group_id': 'who-lives-here-relationship', 'group_instance': 1, 'answer_id': 'first-name', 'block_id': 'household-composition', 'value': 'Jane', 'answer_instance': 1, }, { 'group_id': 'who-lives-here-relationship', 'group_instance': 1, 'answer_id': 'last-name', 'block_id': 'household-composition', 'value': 'Bloggs', 'answer_instance': 1, }]) form, _ = get_form_for_location(block_json, location, answer_store, error_messages) answer = SchemaHelper.get_first_answer_for_block(block_json) self.assertTrue(hasattr(form, answer['id'])) field_list = getattr(form, answer['id']) # With two people, we need to define 1 relationship self.assertEqual(len(field_list.entries), 1)
def test_answer_with_child_inherits_mandatory_from_parent(self): survey = load_schema_file("test_radio.json") block_json = SchemaHelper.get_block(survey, "block-1") error_messages = SchemaHelper.get_messages(survey) form = generate_form(block_json, {'ca3ce3a3-ae44-4e30-8f85-5b6a7a2fb23c': 'Other'}, error_messages) child_field = getattr(form, 'other-answer-mandatory') self.assertIsInstance(child_field.validators[0], validators.InputRequired)
def test_post_form_for_household_relationship(self): with self.test_request_context(): survey = load_schema_file("census_household.json") block_json = SchemaHelper.get_block(survey, 'household-relationships') location = Location('who-lives-here-relationship', 0, 'household-relationships') error_messages = SchemaHelper.get_messages(survey) answer_store = AnswerStore([{ 'answer_id': 'first-name', 'block_id': 'household-composition', 'value': 'Joe', 'answer_instance': 0, }, { 'answer_id': 'last-name', 'block_id': 'household-composition', 'value': 'Bloggs', 'answer_instance': 0, }, { 'answer_id': 'first-name', 'block_id': 'household-composition', 'value': 'Jane', 'answer_instance': 1, }, { 'answer_id': 'last-name', 'block_id': 'household-composition', 'value': 'Bloggs', 'answer_instance': 1, }]) answer = SchemaHelper.get_first_answer_for_block(block_json) form, _ = post_form_for_location( block_json, location, answer_store, MultiDict( {'{answer_id}-0'.format(answer_id=answer['id']): '3'}), error_messages) self.assertTrue(hasattr(form, answer['id'])) field_list = getattr(form, answer['id']) # With two people, we need to define 1 relationship self.assertEqual(len(field_list.entries), 1) # Check the data matches what was passed from request self.assertEqual(field_list.entries[0].data, "3")
def validate_all_answers(answer_store, metadata): path_finder = PathFinder(g.schema_json, answer_store, metadata) error_messages = SchemaHelper.get_messages(g.schema_json) for location in path_finder.get_location_path(): if not location.is_interstitial(): block_json = _render_schema(location) form, _ = get_form_for_location(block_json, location, answer_store, error_messages) if not form.validate(): logger.debug("Failed validation", location=str(location)) return False, location return True, None
def test_answer_errors_are_mapped(self): survey = load_schema_file("1_0112.json") block_json = SchemaHelper.get_block(survey, "total-retail-turnover") error_messages = SchemaHelper.get_messages(survey) form = generate_form(block_json, {'total-retail-turnover-answer': "-1"}, error_messages) form.validate() answer_errors = form.answer_errors('total-retail-turnover-answer') self.assertIn( "The value cannot be negative. Please correct your answer.", answer_errors)
def post_block(eq_id, form_type, collection_id, group_id, group_instance, block_id): # pylint: disable=too-many-locals current_location = Location(group_id, group_instance, block_id) metadata = get_metadata(current_user) answer_store = get_answer_store(current_user) path_finder = PathFinder(g.schema_json, answer_store, metadata) valid_group = group_id in SchemaHelper.get_group_ids(g.schema_json) full_routing_path = path_finder.get_routing_path() is_valid_location = valid_group and current_location in path_finder.get_routing_path( group_id, group_instance) if not is_valid_location: latest_location = path_finder.get_latest_location( get_completed_blocks(current_user), routing_path=full_routing_path) return _redirect_to_location(collection_id, eq_id, form_type, latest_location) error_messages = SchemaHelper.get_messages(g.schema_json) block = _render_schema(current_location) disable_mandatory = 'action[save_sign_out]' in request.form form, _ = post_form_for_location(block, current_location, answer_store, request.form, error_messages, disable_mandatory=disable_mandatory) if 'action[save_sign_out]' in request.form: return _save_sign_out(collection_id, eq_id, form_type, current_location, form) elif _is_invalid_form(form): context = {'form': form, 'block': block} return _build_template(current_location, context, template=block['type'], routing_path=full_routing_path) else: _update_questionnaire_store(current_location, form) next_location = path_finder.get_next_location( current_location=current_location) if next_location is None and block['type'] in [ "Summary", "Confirmation" ]: return submit_answers(eq_id, form_type, collection_id, metadata, answer_store) return redirect(next_location.url(metadata))
def test_form_errors_are_correctly_mapped(self): survey = load_schema_file("1_0112.json") block_json = SchemaHelper.get_block(survey, "total-retail-turnover") error_messages = SchemaHelper.get_messages(survey) form = generate_form(block_json, {}, error_messages) form.validate() mapped_errors = form.map_errors() message = "Please provide a value, even if your value is 0." self.assertTrue( self._error_exists('total-retail-turnover-answer', message, mapped_errors))
def test_form_subfield_errors_are_correctly_mapped(self): survey = load_schema_file("1_0102.json") block_json = SchemaHelper.get_block(survey, "reporting-period") error_messages = SchemaHelper.get_messages(survey) form = generate_form(block_json, {}, error_messages) message = "Please provide an answer to continue." form.validate() mapped_errors = form.map_errors() self.assertTrue(self._error_exists('period-to', message, mapped_errors)) self.assertTrue( self._error_exists('period-from', message, mapped_errors))
def post_household_composition(eq_id, form_type, collection_id, group_id): path_finder = PathFinder(g.schema_json, get_answer_store(current_user), get_metadata(current_user)) answer_store = get_answer_store(current_user) questionnaire_store = get_questionnaire_store(current_user.user_id, current_user.user_ik) current_location = Location(group_id, 0, 'household-composition') block = _render_schema(current_location) if _household_answers_changed(answer_store): _remove_repeating_on_household_answers(answer_store, group_id) error_messages = SchemaHelper.get_messages(g.schema_json) if any(x in request.form for x in ['action[add_answer]', 'action[remove_answer]', 'action[save_sign_out]']): disable_mandatory = True else: disable_mandatory = False form, _ = post_form_for_location(block, current_location, answer_store, request.form, error_messages, disable_mandatory=disable_mandatory) if 'action[add_answer]' in request.form: form.household.append_entry() elif 'action[remove_answer]' in request.form: index_to_remove = int(request.form.get('action[remove_answer]')) form.remove_person(index_to_remove) elif 'action[save_sign_out]' in request.form: return _save_sign_out(collection_id, eq_id, form_type, current_location, form) if not form.validate() or 'action[add_answer]' in request.form or 'action[remove_answer]' in request.form: return _render_template({ 'form': form, 'block': block, }, current_location.block_id, current_location=current_location, template='questionnaire') update_questionnaire_store_with_answer_data(questionnaire_store, current_location, form.serialise(current_location)) next_location = path_finder.get_next_location(current_location=current_location) metadata = get_metadata(current_user) return redirect(next_location.url(metadata))
def test_get_form_for_household_composition(self): survey = load_schema_file("census_household.json") block_json = SchemaHelper.get_block(survey, 'household-composition') location = Location('who-lives-here', 0, 'household-composition') error_messages = SchemaHelper.get_messages(survey) form, _ = get_form_for_location(block_json, location, AnswerStore(), error_messages) self.assertTrue(hasattr(form, "household")) self.assertEquals(len(form.household.entries), 1) first_field_entry = form.household[0] self.assertTrue(hasattr(first_field_entry, "first-name")) self.assertTrue(hasattr(first_field_entry, "middle-names")) self.assertTrue(hasattr(first_field_entry, "last-name"))
def test_get_form_deserialises_dates(self): with self.test_request_context(): survey = load_schema_file("1_0102.json") block_json = SchemaHelper.get_block(survey, "reporting-period") location = Location('rsi', 0, 'reporting-period') error_messages = SchemaHelper.get_messages(survey) form, _ = get_form_for_location( block_json, location, AnswerStore([{ 'answer_id': 'period-from', 'group_id': 'rsi', 'group_instance': 0, 'block_id': 'reporting-period', 'value': '01/05/2015', 'answer_instance': 0, }, { 'answer_id': 'period-to', 'group_id': 'rsi', 'group_instance': 0, 'block_id': 'reporting-period', 'value': '01/09/2017', 'answer_instance': 0, }]), error_messages) self.assertTrue(hasattr(form, "period-to")) self.assertTrue(hasattr(form, "period-from")) period_to_field = getattr(form, "period-to") period_from_field = getattr(form, "period-from") self.assertEqual(period_from_field.data, { 'day': '01', 'month': '5', 'year': '2015', }) self.assertEqual(period_to_field.data, { 'day': '01', 'month': '9', 'year': '2017', })
def post_block(eq_id, form_type, collection_id, group_id, group_instance, block_id): path_finder = PathFinder(g.schema_json, get_answer_store(current_user), get_metadata(current_user)) current_location = Location(group_id, group_instance, block_id) valid_location = current_location in path_finder.get_routing_path(group_id, group_instance) block = _render_schema(current_location) error_messages = SchemaHelper.get_messages(g.schema_json) disable_mandatory = 'action[save_sign_out]' in request.form form, _ = post_form_for_location(block, current_location, get_answer_store(current_user), request.form, error_messages, disable_mandatory=disable_mandatory) if 'action[save_sign_out]' in request.form: return _save_sign_out(collection_id, eq_id, form_type, current_location, form) content = { 'form': form, 'block': block, } if not valid_location or not form.validate(): return _build_template(current_location, content, template='questionnaire') else: questionnaire_store = get_questionnaire_store(current_user.user_id, current_user.user_ik) if current_location.block_id in ['relationships', 'household-relationships']: update_questionnaire_store_with_answer_data(questionnaire_store, current_location, form.serialise(current_location)) else: update_questionnaire_store_with_form_data(questionnaire_store, current_location, form.data) next_location = path_finder.get_next_location(current_location=current_location) if next_location is None: raise NotFound metadata = get_metadata(current_user) return redirect(next_location.url(metadata))
def test_get_form_for_block_location(self): survey = load_schema_file("1_0102.json") block_json = SchemaHelper.get_block(survey, "reporting-period") location = SchemaHelper.get_first_location(survey) error_messages = SchemaHelper.get_messages(survey) form, _ = get_form_for_location(block_json, location, AnswerStore(), error_messages) self.assertTrue(hasattr(form, "period-to")) self.assertTrue(hasattr(form, "period-from")) period_from_field = getattr(form, "period-from") period_to_field = getattr(form, "period-to") self.assertIsInstance(period_from_field.day.validators[0], DateRequired) self.assertIsInstance(period_to_field.day.validators[0], DateRequired)
def test_get_date_range_fields(self): survey = load_schema_file("test_dates.json") error_messages = SchemaHelper.get_messages(survey) questions = SchemaHelper.get_questions_by_id(survey) from_field, to_field = get_date_range_fields( questions["date-range-question"], { 'day': '1', 'month': '01', 'year': '2016' }, error_messages) self.assertTrue(hasattr(from_field.args[0], 'day')) self.assertTrue(hasattr(from_field.args[0], 'month')) self.assertTrue(hasattr(from_field.args[0], 'year')) self.assertTrue(hasattr(to_field.args[0], 'day')) self.assertTrue(hasattr(to_field.args[0], 'month')) self.assertTrue(hasattr(to_field.args[0], 'year'))