def test_post_form_for_household_composition(self): with self.app_request_context(): schema = load_schema_from_params('census', 'household') block_json = schema.get_block('household-composition') location = Location('who-lives-here', 0, 'household-composition') form = post_form_for_location(schema, block_json, location, AnswerStore(), metadata=None, request_form={ 'household-0-first-name': 'Joe', 'household-0-last-name': '', 'household-1-first-name': 'Bob', 'household-1-last-name': 'Seymour', }) 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 test_post_form_for_radio_other_selected(self): with self.app_request_context(): schema = load_schema_from_params('test', 'radio_mandatory_with_mandatory_other') block_json = schema.get_block('radio-mandatory') location = Location('radio', 0, 'radio-mandatory') answer_store = AnswerStore([ { 'answer_id': 'radio-mandatory-answer', 'block_id': 'radio-mandatory', 'value': 'Other', 'answer_instance': 0, }, { 'answer_id': 'other-answer-mandatory', 'block_id': 'radio-mandatory', 'value': 'Other text field value', 'answer_instance': 0, } ]) request_form = MultiDict({ 'radio-mandatory-answer': 'Other', 'other-answer-mandatory': 'Other text field value', }) form = post_form_for_location(schema, block_json, location, answer_store, metadata=None, request_form=request_form) other_text_field = getattr(form, 'other-answer-mandatory') self.assertEqual(other_text_field.data, 'Other text field value')
def test_post_form_and_disable_mandatory(self): with self.app_request_context(): schema = load_schema_from_params('test', '0102') block_json = schema.get_block('reporting-period') location = Location(group_id='rsi', group_instance=0, block_id='introduction') form = post_form_for_location(schema, block_json, location, AnswerStore(), metadata=None, request_form={}, disable_mandatory=True) self.assertTrue(hasattr(form, 'period-from')) self.assertTrue(hasattr(form, 'period-to')) period_from_field = getattr(form, 'period-from') period_to_field = getattr(form, 'period-to') self.assertIsInstance(period_from_field.month.validators[0], OptionalForm) self.assertIsInstance(period_to_field.month.validators[0], OptionalForm)
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 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_post_form_for_block_location(self): with self.app_request_context(): schema = load_schema_from_params('test', '0102') block_json = schema.get_block('reporting-period') location = Location(group_id='rsi', group_instance=0, block_id='introduction') form = post_form_for_location(schema, block_json, location, AnswerStore(), metadata=None, request_form={ 'period-from-day': '1', 'period-from-month': '05', 'period-from-year': '2015', 'period-to-day': '1', 'period-to-month': '09', 'period-to-year': '2017', }) 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.assertIsInstance(period_from_field.month.validators[0], DateRequired) self.assertIsInstance(period_to_field.month.validators[0], DateRequired) self.assertEqual(period_from_field.data, '2015-05-01') self.assertEqual(period_to_field.data, '2017-09-01')
def _generate_wtf_form(form, block, location, schema): disable_mandatory = 'action[save_sign_out]' in form wtf_form = post_form_for_location(schema, block, location, get_answer_store(current_user), get_metadata(current_user), request.form, disable_mandatory) return wtf_form
def test_post_form_for_household_relationship(self): with self.app_request_context(): schema = load_schema_from_params('census', 'household') block_json = schema.get_block('household-relationships') location = Location('who-lives-here-relationship', 0, 'household-relationships') answer_store = AnswerStore([{ 'answer_id': 'first-name', 'group_instance': 0, 'group_instance_id': 'who-lives-here-relationship-0', 'value': 'Joe', 'answer_instance': 0, }, { 'answer_id': 'last-name', 'group_instance': 0, 'group_instance_id': 'who-lives-here-relationship-0', 'value': 'Bloggs', 'answer_instance': 0, }, { 'answer_id': 'first-name', 'group_instance': 0, 'group_instance_id': 'who-lives-here-relationship-0', 'value': 'Jane', 'answer_instance': 1, }, { 'answer_id': 'last-name', 'group_instance': 0, 'group_instance_id': 'who-lives-here-relationship-0', 'value': 'Bloggs', 'answer_instance': 1, }]) answer = schema.get_answers_for_block('household-relationships')[0] form = post_form_for_location( schema, block_json, location, answer_store, metadata=None, request_form=MultiDict( {'{answer_id}-0'.format(answer_id=answer['id']): '3'})) 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 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_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 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 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 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_post_form_for_block_location(self): with self.test_request_context(): 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, _ = post_form_for_location( block_json, location, AnswerStore(), { 'period-from-day': '1', 'period-from-month': '05', 'period-from-year': '2015', 'period-to-day': '1', 'period-to-month': '09', 'period-to-year': '2017', }, 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.assertIsInstance(period_from_field.month.validators[0], DateRequired) self.assertIsInstance(period_to_field.month.validators[0], DateRequired) self.assertEqual(period_from_field.data, { 'day': '1', 'month': '05', 'year': '2015', }) self.assertEqual(period_to_field.data, { 'day': '1', 'month': '09', 'year': '2017', })
def test_post_form_and_disable_mandatory(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, _ = post_form_for_location(block_json, location, AnswerStore(), {}, error_messages, disable_mandatory=True) self.assertTrue(hasattr(form, "period-from")) self.assertTrue(hasattr(form, "period-to")) period_from_field = getattr(form, "period-from") period_to_field = getattr(form, "period-to") self.assertIsInstance(period_from_field.day.validators[0], validators.Optional) self.assertIsInstance(period_to_field.day.validators[0], validators.Optional)
def post_household_composition(routing_path, schema, metadata, answer_store, **kwargs): # pylint: disable=too-many-locals group_id = kwargs['group_id'] current_location = Location(group_id, 0, 'household-composition') questionnaire_store = get_questionnaire_store(current_user.user_id, current_user.user_ik) answer_store_updater = AnswerStoreUpdater(current_location, schema, questionnaire_store) answer_store_updater.remove_repeats_for_changed_household_answers( request.form.copy()) disable_mandatory = any(x in request.form for x in [ 'action[add_answer]', 'action[remove_answer]', 'action[save_sign_out]' ]) block = _get_block_json(current_location, schema, answer_store, metadata) form = post_form_for_location(schema, block, current_location, answer_store, metadata, request.form, disable_mandatory=disable_mandatory) form.validate( ) # call validate here to keep errors in the form object on the context context = _get_context(routing_path, block, current_location, schema, form) if 'action[add_answer]' in request.form: form.household.append_entry() return _render_page(block['type'], context, current_location, schema, answer_store, metadata, routing_path) if 'action[remove_answer]' in request.form: index_to_remove = int(request.form.get('action[remove_answer]')) form.remove_person(index_to_remove) return _render_page(block['type'], context, current_location, schema, answer_store, metadata, routing_path) if 'action[save_sign_out]' in request.form: response = _save_sign_out(routing_path, current_location, form, schema, answer_store, metadata) answer_store_updater.remove_empty_household_members() return response if form.validate(): answer_store_updater.save_answers(form) metadata = get_metadata(current_user) next_location = path_finder.get_next_location( current_location=current_location) return redirect(next_location.url(metadata)) return _render_page(block['type'], context, current_location, schema, answer_store, metadata, routing_path)
def test_post_form_for_household_relationship_driven_by_multiple_answers( self): with self.app_request_context(): schema = load_schema_from_params( 'test', 'routing_on_answer_from_driving_repeating_group') block_json = schema.get_block('relationships') location = Location('household-relationships', 0, 'relationships') primary_group_instance_id = str(uuid.uuid4()) repeating_group_1_instance_id = str(uuid.uuid4()) repeating_group_2_instance_id = str(uuid.uuid4()) answer_store = AnswerStore({}) answer_store.add( Answer(answer_id='primary-name', value='Jon', group_instance=0, group_instance_id=primary_group_instance_id)) answer_store.add( Answer(answer_id='primary-live-here', value='No', group_instance=0, group_instance_id=primary_group_instance_id)) answer_store.add( Answer( answer_id='repeating-anyone-else', answer_instance=0, value='Yes', group_instance=0, )) answer_store.add( Answer(answer_id='repeating-name', answer_instance=0, value='Adam', group_instance=0, group_instance_id=repeating_group_1_instance_id)) answer_store.add( Answer( answer_id='repeating-anyone-else', answer_instance=0, value='Yes', group_instance=1, )) answer_store.add( Answer(answer_id='repeating-name', answer_instance=0, value='Ben', group_instance=1, group_instance_id=repeating_group_2_instance_id)) answer_store.add( Answer( answer_id='repeating-anyone-else', answer_instance=0, value='No', group_instance=2, )) answer = schema.get_answers_for_block('relationships')[0] form = post_form_for_location( schema, block_json, location, answer_store, metadata=None, request_form=MultiDict( {'{answer_id}-0'.format(answer_id=answer['id']): '3'})) self.assertTrue(hasattr(form, answer['id'])) field_list = getattr(form, answer['id']) # With three people, we need to define 2 relationships self.assertEqual(len(field_list.entries), 2) # Check the data matches what was passed from request self.assertEqual(field_list.entries[0].data, '3')
def post_household_composition(routing_path, schema, metadata, answer_store, **kwargs): group_id = kwargs['group_id'] if _household_answers_changed(answer_store, schema): _remove_repeating_on_household_answers(answer_store, schema) 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 = _get_block_json(current_location, schema, answer_store, metadata) form = post_form_for_location(schema, block, current_location, answer_store, metadata, request.form, disable_mandatory=disable_mandatory) form.validate( ) # call validate here to keep errors in the form object on the context context = _get_context(routing_path, block, current_location, schema, form) if 'action[add_answer]' in request.form: form.household.append_entry() return _render_page(block['type'], context, current_location, schema, answer_store, metadata, routing_path) if 'action[remove_answer]' in request.form: index_to_remove = int(request.form.get('action[remove_answer]')) form.remove_person(index_to_remove) return _render_page(block['type'], context, current_location, schema, answer_store, metadata, routing_path) if 'action[save_sign_out]' in request.form: response = _save_sign_out(routing_path, current_location, form, schema, answer_store, metadata) remove_empty_household_members_from_answer_store(answer_store, schema) return response if form.validate(): 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(), schema) metadata = get_metadata(current_user) next_location = path_finder.get_next_location( current_location=current_location) return redirect(next_location.url(metadata)) return _render_page(block['type'], context, current_location, schema, answer_store, metadata, routing_path)