def test_remove_last_person(self):
        with self.app_request_context():
            form = generate_household_composition_form(
                self.schema,
                self.block_json, {
                    'household-0-first-name': 'Joe',
                    'household-0-last-name': 'Bloggs',
                    'household-1-first-name': 'Bob',
                    'household-1-last-name': 'Seymour',
                    'household-2-first-name': 'Jane',
                    'household-2-last-name': 'Seymour',
                },
                metadata=self.metadata,
                group_instance=0)

            form.remove_person(2)

            self.assertEqual(len(form.household.entries), 2)
            self.assertEqual(form.household.entries[0].data, {
                'first-name': 'Joe',
                'middle-names': '',
                'last-name': 'Bloggs'
            })
            self.assertEqual(form.household.entries[1].data, {
                'first-name': 'Bob',
                'middle-names': '',
                'last-name': 'Seymour'
            })
    def test_remove_first_person(self):

        form = generate_household_composition_form(self.block_json, {
            'household-0-first-name': 'Joe',
            'household-0-last-name': 'Bloggs',
            'household-1-first-name': 'Bob',
            'household-1-middle-names': 'Michael',
            'household-1-last-name': 'Seymour',
            'household-2-first-name': 'Sophie',
            'household-2-last-name': 'Bloggs',
            'household-3-first-name': 'Jane',
            'household-3-last-name': 'Seymour',
        }, error_messages=self.error_messages)

        form.remove_person(0)

        self.assertEqual(len(form.household.entries), 3)
        self.assertEqual(form.household.entries[0].data, {
            'first-name': 'Bob',
            'middle-names': 'Michael',
            'last-name': 'Seymour'
        })
        self.assertEqual(form.household.entries[1].data, {
            'first-name': 'Sophie',
            'middle-names': '',
            'last-name': 'Bloggs'
        })
        self.assertEqual(form.household.entries[2].data, {
            'first-name': 'Jane',
            'middle-names': '',
            'last-name': 'Seymour'
        })
Ejemplo n.º 3
0
def post_form_for_location(block_json,
                           location,
                           answer_store,
                           request_form,
                           error_messages,
                           disable_mandatory=False):
    """
    Returns the form necessary for the location given a post request, plus any template arguments

    :param disable_mandatory: Make mandatory answers optional
    :param error_messages: The default error messages to use within the form
    :param block_json: The block json
    :param location: The location which this form is for
    :param answer_store: The current answer store
    :param request_form: form, template_args A tuple containing the form for this location and any additional template arguments
    """
    if disable_mandatory:
        block_json = disable_mandatory_answers(block_json)

    if location.block_id == 'household-composition':
        return generate_household_composition_form(block_json, request_form,
                                                   error_messages), None
    elif location.block_id in ['relationships', 'household-relationships']:
        choices = build_relationship_choices(answer_store,
                                             location.group_instance)
        form = generate_relationship_form(block_json, len(choices),
                                          request_form, error_messages)

        return form, {'relation_instances': choices}
    else:
        data = clear_other_text_field(
            request_form, SchemaHelper.get_questions_for_block(block_json))
        return generate_form(block_json, data, error_messages), None
Ejemplo n.º 4
0
    def test_remove_last_person(self):
        with self.test_request_context():
            form = generate_household_composition_form(
                self.block_json, {
                    'household-0-first-name': 'Joe',
                    'household-0-last-name': 'Bloggs',
                    'household-1-first-name': 'Bob',
                    'household-1-last-name': 'Seymour',
                    'household-2-first-name': 'Jane',
                    'household-2-last-name': 'Seymour',
                },
                error_messages=self.error_messages)

            form.remove_person(2)

            self.assertEqual(len(form.household.entries), 2)
            self.assertEqual(form.household.entries[0].data, {
                'first-name': 'Joe',
                'middle-names': '',
                'last-name': 'Bloggs'
            })
            self.assertEqual(form.household.entries[1].data, {
                'first-name': 'Bob',
                'middle-names': '',
                'last-name': 'Seymour'
            })
def get_form_for_location(schema, block_json, location, answer_store, metadata, disable_mandatory=False):  # pylint: disable=too-many-locals
    """
    Returns the form necessary for the location given a get request, plus any template arguments

    :param schema: schema
    :param block_json: The block json
    :param location: The location which this form is for
    :param answer_store: The current answer store
    :param metadata: metadata
    :param disable_mandatory: Make mandatory answers optional
    :return: form, template_args A tuple containing the form for this location and any additional template arguments
    """
    if disable_mandatory:
        block_json = disable_mandatory_answers(block_json)

    if location.block_id == 'household-composition':
        answer_ids = schema.get_answer_ids_for_block(location.block_id)
        answers = answer_store.filter(answer_ids, location.group_instance)

        data = deserialise_composition_answers(answers)

        return generate_household_composition_form(schema, block_json, data, metadata, location.group_instance)

    group_instance_id = get_group_instance_id(schema, answer_store, location)

    if schema.block_has_question_type(location.block_id, 'Relationship'):
        answer_ids = schema.get_answer_ids_for_block(location.block_id)
        group = schema.get_group(location.group_id)
        answers = answer_store.filter(answer_ids, location.group_instance)

        data = deserialise_relationship_answers(answers)

        # Relationship block only supports 1 question
        question = schema.get_question(block_json['questions'][0]['id'])

        answer_ids = []

        repeat_rule = group['routing_rules'][0]['repeat']
        if 'answer_ids' in repeat_rule:
            for answer_id in repeat_rule['answer_ids']:
                answer_ids.append(answer_id)
        if 'answer_id' in repeat_rule:
            answer_ids.append(repeat_rule['answer_id'])

        relationship_choices = build_relationship_choices(answer_ids, answer_store, location.group_instance, question.get('member_label'))

        form = generate_relationship_form(schema, block_json, relationship_choices, data, location.group_instance, group_instance_id)

        return form

    mapped_answers = get_mapped_answers(
        schema,
        answer_store,
        group_instance=location.group_instance,
        group_instance_id=group_instance_id,
        block_id=location.block_id,
    )

    return generate_form(schema, block_json, answer_store, metadata, location.group_instance, group_instance_id, data=mapped_answers)
Ejemplo n.º 6
0
def post_form_for_location(schema,
                           block_json,
                           location,
                           answer_store,
                           metadata,
                           request_form,
                           disable_mandatory=False):
    """
    Returns the form necessary for the location given a post request, plus any template arguments

    :param block_json: The block json
    :param location: The location which this form is for
    :param answer_store: The current answer store
    :param metadata: metadata
    :param request_form: form, template_args A tuple containing the form for this location and any additional template arguments
    :param error_messages: The default error messages to use within the form
    :param disable_mandatory: Make mandatory answers optional
    """

    if disable_mandatory:
        block_json = disable_mandatory_answers(block_json)

    if location.block_id == 'household-composition':
        return generate_household_composition_form(schema, block_json,
                                                   request_form, metadata,
                                                   location.group_instance)

    group_instance_id = get_group_instance_id(schema, answer_store, location)

    if schema.block_has_question_type(location.block_id, 'Relationship'):
        group = schema.get_group(location.group_id)

        answer_ids = []

        repeat_rule = group['routing_rules'][0]['repeat']
        if 'answer_ids' in repeat_rule:
            for answer_id in repeat_rule['answer_ids']:
                answer_ids.append(answer_id)
        if 'answer_id' in repeat_rule:
            answer_ids.append(repeat_rule['answer_id'])

        relationship_choices = build_relationship_choices(
            answer_ids, answer_store, location.group_instance)
        form = generate_relationship_form(schema, block_json,
                                          relationship_choices, request_form,
                                          location.group_instance,
                                          group_instance_id)

        return form

    data = clear_other_text_field(request_form,
                                  schema.get_questions_for_block(block_json))
    return generate_form(schema,
                         block_json,
                         answer_store,
                         metadata,
                         location.group_instance,
                         group_instance_id,
                         formdata=data)
Ejemplo n.º 7
0
def get_form_for_location(schema,
                          block_json,
                          location,
                          answer_store,
                          metadata,
                          disable_mandatory=False):  # pylint: disable=too-many-locals
    """
    Returns the form necessary for the location given a get request, plus any template arguments

    :param schema: schema
    :param block_json: The block json
    :param location: The location which this form is for
    :param answer_store: The current answer store
    :param metadata: metadata
    :param disable_mandatory: Make mandatory answers optional
    :return: form, template_args A tuple containing the form for this location and any additional template arguments
    """
    if disable_mandatory:
        block_json = disable_mandatory_answers(block_json)

    if location.block_id == 'household-composition':
        answer_ids = schema.get_answer_ids_for_block(location.block_id)
        answers = answer_store.filter(answer_ids, location.group_instance)

        data = deserialise_composition_answers(answers)

        return generate_household_composition_form(schema, block_json, data,
                                                   metadata,
                                                   location.group_instance)

    if location.block_id in ['relationships', 'household-relationships']:
        answer_ids = schema.get_answer_ids_for_block(location.block_id)
        answers = answer_store.filter(answer_ids, location.group_instance)

        data = deserialise_relationship_answers(answers)

        relationship_choices = build_relationship_choices(
            answer_store, location.group_instance)

        form = generate_relationship_form(schema, block_json,
                                          relationship_choices, data,
                                          location.group_instance)

        return form

    mapped_answers = get_mapped_answers(
        schema,
        answer_store,
        group_instance=location.group_instance,
        block_id=location.block_id,
    )

    return generate_form(schema,
                         block_json,
                         answer_store,
                         metadata,
                         location.group_instance,
                         data=mapped_answers)
    def test_form_errors_are_correctly_mapped(self):

        form = generate_household_composition_form(self.block_json, {}, error_messages=self.error_messages)

        form.validate()

        message = "Please enter a name or remove the person to continue"

        self.assertTrue(self._error_exists('household-0-first-name', message, form.map_errors()))
    def test_answer_errors_are_mapped(self):

        form = generate_household_composition_form(self.block_json, {}, error_messages=self.error_messages)

        form.validate()

        message = "Please enter a name or remove the person to continue"

        self.assertIn(message, form.answer_errors('household-0-first-name'))
Ejemplo n.º 10
0
def get_form_for_location(block_json,
                          location,
                          answer_store,
                          error_messages,
                          disable_mandatory=False):
    """
    Returns the form necessary for the location given a get request, plus any template arguments

    :param disable_mandatory: Make mandatory answers optional
    :param error_messages: The default error messages to use within the form
    :param block_json: The block json
    :param location: The location which this form is for
    :param answer_store: The current answer store
    :return: form, template_args A tuple containing the form for this location and any additional template arguments
    """
    if disable_mandatory:
        block_json = disable_mandatory_answers(block_json)

    if location.block_id == 'household-composition':
        answers = answer_store.filter(location=location)

        data = deserialise_composition_answers(answers)

        return generate_household_composition_form(block_json, data,
                                                   error_messages), None
    elif location.block_id in ['relationships', 'household-relationships']:

        answers = answer_store.filter(location=location)

        data = deserialise_relationship_answers(answers)

        choices = build_relationship_choices(answer_store,
                                             location.group_instance)

        form = generate_relationship_form(block_json, len(choices), data,
                                          error_messages)

        return form, {'relation_instances': choices}
    else:
        mapped_answers = answer_store.map(
            group_id=location.group_id,
            group_instance=location.group_instance,
            block_id=location.block_id,
        )

        # Form generation expects post like data, so cast answers to strings
        for answer_id, mapped_answer in mapped_answers.items():
            if isinstance(mapped_answer, list):
                for index, element in enumerate(mapped_answer):
                    mapped_answers[answer_id][index] = str(element)
            else:
                mapped_answers[answer_id] = str(mapped_answer)

        mapped_answers = deserialise_dates(block_json, mapped_answers)

        return generate_form(block_json, mapped_answers, error_messages), None
Ejemplo n.º 11
0
    def test_serialise_answers(self):
        with self.app_request_context():
            form = generate_household_composition_form(
                self.schema,
                self.block_json, {
                    'household-0-first-name': 'Joe',
                    'household-0-last-name': 'Bloggs',
                    'household-1-first-name': 'Bob',
                    'household-1-last-name': 'Seymour',
                },
                metadata=self.metadata,
                group_instance=0)

            answers = form.serialise()

            expected_answers = [{
                'group_instance_id': None,
                'group_instance': 0,
                'answer_id': 'first-name',
                'answer_instance': 0,
                'value': 'Joe'
            }, {
                'group_instance_id': None,
                'group_instance': 0,
                'answer_id': 'middle-names',
                'answer_instance': 0,
                'value': ''
            }, {
                'group_instance_id': None,
                'group_instance': 0,
                'answer_id': 'last-name',
                'answer_instance': 0,
                'value': 'Bloggs'
            }, {
                'group_instance_id': None,
                'group_instance': 0,
                'answer_id': 'first-name',
                'answer_instance': 1,
                'value': 'Bob'
            }, {
                'group_instance_id': None,
                'group_instance': 0,
                'answer_id': 'middle-names',
                'answer_instance': 1,
                'value': ''
            }, {
                'group_instance_id': None,
                'group_instance': 0,
                'answer_id': 'last-name',
                'answer_instance': 1,
                'value': 'Seymour'
            }]

            for _, answer in enumerate(answers):
                self.assertIn(answer.__dict__, expected_answers)
    def test_answer_errors_are_mapped(self):
        with self.app_request_context():
            form = generate_household_composition_form(self.schema,
                                                       self.block_json, {},
                                                       metadata=self.metadata,
                                                       group_instance=0)
            form.validate()

            message = 'Please enter a name or remove the person to continue'

            self.assertIn(message,
                          form.answer_errors('household-0-first-name'))
    def test_get_name_form_generates_name_form(self):

        form = generate_household_composition_form(self.block_json, {}, error_messages=self.error_messages)

        self.assertEqual(len(form.household.entries), 1)

        first_name_field = getattr(form.household.entries[0], 'first-name')
        middle_names_field = getattr(form.household.entries[0], 'middle-names')
        last_name_field = getattr(form.household.entries[0], 'last-name')

        self.assertIsInstance(first_name_field.validators[0], validators.InputRequired)
        self.assertIsInstance(middle_names_field.validators[0], validators.Optional)
        self.assertIsInstance(last_name_field.validators[0], validators.Optional)
    def test_get_name_form_generates_name_form_with_titles(self):
        block_json = {
            'type':
            'Question',
            'id':
            'household-composition',
            'questions': [{
                'id':
                'household-composition-question',
                'titles': [{
                    'value': 'First Name Default'
                }],
                'type':
                'RepeatingAnswer',
                'answers': [{
                    'id': 'first-name',
                    'mandatory': True,
                    'type': 'TextField'
                }, {
                    'id': 'middle-names',
                    'mandatory': False,
                    'type': 'TextField'
                }, {
                    'id': 'last-name',
                    'mandatory': False,
                    'type': 'TextField'
                }]
            }]
        }

        with self.app_request_context():
            form = generate_household_composition_form(self.schema,
                                                       block_json, {},
                                                       metadata=self.metadata,
                                                       group_instance=0)

            self.assertEqual(len(form.household.entries), 1)

            first_name_field = getattr(form.household.entries[0], 'first-name')
            middle_names_field = getattr(form.household.entries[0],
                                         'middle-names')
            last_name_field = getattr(form.household.entries[0], 'last-name')

            self.assertIsInstance(first_name_field.validators[0],
                                  ResponseRequired)
            self.assertIsInstance(middle_names_field.validators[0],
                                  validators.Optional)
            self.assertIsInstance(last_name_field.validators[0],
                                  validators.Optional)
Ejemplo n.º 15
0
    def test_whitespace_in_first_name_invalid(self):
        with self.test_request_context():
            form = generate_household_composition_form(
                self.block_json, {
                    'household-0-first-name': '     ',
                    'household-0-last-name': 'Bloggs',
                },
                error_messages=self.error_messages)

            form.validate()

            message = "Please enter a name or remove the person to continue"

            self.assertIn(message,
                          form.answer_errors('household-0-first-name'))
    def test_remove_person(self):
        with self.app_request_context():
            form = generate_household_composition_form(
                self.schema,
                self.block_json, {
                    'household-0-first-name': 'Joe',
                    'household-0-last-name': 'Bloggs',
                    'household-1-first-name': 'Bob',
                    'household-1-last-name': 'Seymour',
                },
                metadata=self.metadata,
                group_instance=0)

            self.assertEqual(len(form.household.entries), 2)

            with self.assertRaises(IndexError):
                form.remove_person(3)
    def test_form_creation_with_data(self):

        form = generate_household_composition_form(self.block_json, {
            'household-0-first-name': 'Joe',
            'household-0-last-name': 'Bloggs',
            'household-1-first-name': 'Jane',
            'household-1-last-name': 'Seymour',
        }, error_messages=self.error_messages)

        self.assertEqual(len(form.household.entries), 2)
        self.assertEqual(form.household.entries[0].data, {
            'first-name': 'Joe',
            'middle-names': '',
            'last-name': 'Bloggs'
        })
        self.assertEqual(form.household.entries[1].data, {
            'first-name': 'Jane',
            'middle-names': '',
            'last-name': 'Seymour'
        })
    def test_get_name_form_generates_name_form(self):
        with self.app_request_context():
            form = generate_household_composition_form(self.schema,
                                                       self.block_json, {},
                                                       metadata=self.metadata,
                                                       group_instance=0)

            self.assertEqual(len(form.household.entries), 1)

            first_name_field = getattr(form.household.entries[0], 'first-name')
            middle_names_field = getattr(form.household.entries[0],
                                         'middle-names')
            last_name_field = getattr(form.household.entries[0], 'last-name')

            self.assertIsInstance(first_name_field.validators[0],
                                  ResponseRequired)
            self.assertIsInstance(middle_names_field.validators[0],
                                  validators.Optional)
            self.assertIsInstance(last_name_field.validators[0],
                                  validators.Optional)
    def test_serialise_answers(self):

        form = generate_household_composition_form(self.block_json, {
            'household-0-first-name': 'Joe',
            'household-0-last-name': 'Bloggs',
            'household-1-first-name': 'Bob',
            'household-1-last-name': 'Seymour',
        }, error_messages=self.error_messages)

        location = Location('who-lives-here', 0, 'household-composition')

        answers = form.serialise(location)

        expected_answers = [
            {
                'group_id': 'who-lives-here',
                'group_instance': 0,
                'block_id': 'household-composition',
                'answer_id': 'first-name',
                'answer_instance': 0,
                'value': 'Joe'
            }, {
                'group_id': 'who-lives-here',
                'group_instance': 0,
                'block_id': 'household-composition',
                'answer_id': 'middle-names',
                'answer_instance': 0,
                'value': ''
            }, {
                'group_id': 'who-lives-here',
                'group_instance': 0,
                'block_id': 'household-composition',
                'answer_id': 'last-name',
                'answer_instance': 0,
                'value': 'Bloggs'
            }, {
                'group_id': 'who-lives-here',
                'group_instance': 0,
                'block_id': 'household-composition',
                'answer_id': 'first-name',
                'answer_instance': 1,
                'value': 'Bob'
            }, {
                'group_id': 'who-lives-here',
                'group_instance': 0,
                'block_id': 'household-composition',
                'answer_id': 'middle-names',
                'answer_instance': 1,
                'value': ''
            }, {
                'group_id': 'who-lives-here',
                'group_instance': 0,
                'block_id': 'household-composition',
                'answer_id': 'last-name',
                'answer_instance': 1,
                'value': 'Seymour'
            }
        ]

        for i, answer in enumerate(answers):
            self.assertIn(answer.__dict__, expected_answers)