def test_repeating_groups(self):
        schema = load_schema_from_params('test', 'repeating_household')
        schema.answer_is_in_repeating_group = MagicMock(return_value=False)

        # Default is to count answers, so switch to using value
        schema.json['sections'][-2]['groups'][0]['routing_rules'][0]['repeat']['type'] = 'answer_value'

        expected_path = [
            Location('multiple-questions-group', 0, 'introduction'),
            Location('multiple-questions-group', 0, 'household-composition'),
            Location('repeating-group', 0, 'repeating-block-1'),
            Location('repeating-group', 0, 'repeating-block-2'),
            Location('repeating-group', 0, 'repeating-block-3'),
            Location('repeating-group', 1, 'repeating-block-1'),
            Location('repeating-group', 1, 'repeating-block-2'),
            Location('repeating-group', 1, 'repeating-block-3'),
            Location('summary-group', 0, 'summary'),
        ]

        answer = Answer(
            group_instance=0,
            answer_id='first-name',
            value='2'
        )
        answers = AnswerStore()
        answers.add(answer)

        path_finder = PathFinder(schema, answer_store=answers, metadata={}, completed_blocks=[])

        self.assertEqual(expected_path, path_finder.get_full_routing_path())
    def test_repeating_group_block_skip_correct_if_independent_answer_is_not_repeating_but_causes_a_skip(self):
        """ tests blocks are correctly added to path in the case where the blocks in a repeating group have
        skip conditions and those skip conditions are dependant on a non repeating answer which causes a skip
        condition to return true.
        """
        # Given
        independent_answer = '3'

        expected_path = [
            Location('about-household-group', 0, 'household-composition'),
            Location('independent-answer-group', 0, 'non-repeating-question-block'),
            Location('questionnaire-completed', 0, 'confirmation')
        ]

        schema = load_schema_from_params('test', 'skip_conditions_from_repeating_group_based_on_non_repeating_answer')
        answer_store = AnswerStore()

        # Set up some first names
        answer_store.add(Answer(answer_id='first-name', value='aaa', group_instance=0))
        answer_store.add(Answer(answer_id='first-name', value='bbb', group_instance=1))
        answer_store.add(Answer(answer_id='first-name', value='ccc', group_instance=2))

        # Set up the independent answer
        answer_store.add(Answer(answer_id='an-independent-answer', value=independent_answer, group_instance=0))

        path_finder = PathFinder(schema, answer_store=answer_store, metadata={}, completed_blocks=[])

        # When
        with patch('app.questionnaire.path_finder.evaluate_skip_conditions', return_value=True):
            new_path = path_finder.get_full_routing_path()

        # Then
        self.assertEqual(expected_path, new_path)
    def test_routing_basic_and_conditional_path(self):
        # Given
        schema = load_schema_from_params('0', 'star_wars')

        expected_path = [
            Location('star-wars', 0, 'introduction'),
            Location('star-wars', 0, 'choose-your-side-block'),
            Location('star-wars', 0, 'dark-side-pick-character-ship'),
            Location('star-wars', 0, 'light-side-ship-type'),
            Location('star-wars', 0, 'star-wars-trivia'),
            Location('star-wars', 0, 'star-wars-trivia-part-2'),
            Location('star-wars', 0, 'star-wars-trivia-part-3'),
            Location('star-wars', 0, 'summary'),
        ]

        answer_1 = Answer(
            answer_id='choose-your-side-answer',
            value='Dark Side'
        )
        answer_2 = Answer(
            answer_id='dark-side-pick-ship-answer',
            value='Can I be a pain and have a goodies ship',
        )

        answers = AnswerStore()
        answers.add(answer_1)
        answers.add(answer_2)
        schema.answer_is_in_repeating_group = MagicMock(return_value=False)

        # When
        path_finder = PathFinder(schema, answer_store=answers, metadata={}, completed_blocks=[])
        routing_path = path_finder.get_full_routing_path()

        # Then
        self.assertEqual(routing_path, expected_path)
def build_summary_rendering_context(schema, sections, answer_store, metadata,
                                    schema_context):
    """
    Build questionnaire summary context containing metadata and content from the answers of the questionnaire
    :param schema: schema of the current questionnaire
    :param sections: the sections of the current schema
    :param answer_store: all of the answers to the questionnaire
    :param metadata: all of the metadata
    :param schema_context: The schema context
    :return: questionnaire summary context
    """
    navigator = PathFinder(schema, answer_store, metadata, [])
    path = navigator.get_full_routing_path()
    groups = []

    group_lists = (section['groups'] for section in sections)

    group_ids_on_path = [location.group_id for location in path]

    for group in itertools.chain.from_iterable(group_lists):
        if (group['id'] in group_ids_on_path
                and schema.group_has_questions(group['id'])):
            no_of_repeats = _number_of_repeats(group, path)
            repeating_groups = []
            for instance_idx in range(0, no_of_repeats):
                summary_group = Group(group, path, answer_store, metadata,
                                      schema, instance_idx,
                                      schema_context).serialize()
                repeating_groups.append(summary_group)
            groups.extend(repeating_groups)

    return groups
Exemplo n.º 5
0
def build_summary_rendering_context(schema, sections, answer_store, metadata):
    """
    Build questionnaire summary context containing metadata and content from the answers of the questionnaire
    :param schema: schema of the current questionnaire
    :param sections: the sections of the current schema
    :param answer_store: all of the answers to the questionnaire
    :param metadata: all of the metadata
    :return: questionnaire summary context
    """
    navigator = PathFinder(schema, answer_store, metadata, [])
    path = navigator.get_full_routing_path()
    groups = []

    group_lists = (section['groups'] for section in sections)

    group_ids_on_path = [location.group_id for location in path]

    for group in itertools.chain.from_iterable(group_lists):
        if group['id'] in group_ids_on_path \
                and schema.group_has_questions(group['id']):
            groups.extend([
                Group(group, path, answer_store, metadata, schema).serialize()
            ])

    return groups
    def test_introduction_in_path_when_in_schema(self):
        schema = load_schema_from_params('test', '0102')

        path_finder = PathFinder(schema, AnswerStore(), metadata={}, completed_blocks=[])

        blocks = [b.block_id for b in path_finder.get_full_routing_path()]

        self.assertIn('introduction', blocks)
    def test_introduction_not_in_path_when_not_in_schema(self):
        schema = load_schema_from_params('census', 'individual')

        path_finder = PathFinder(schema, AnswerStore(), metadata={}, completed_blocks=[])

        with patch('app.questionnaire.rules.evaluate_when_rules', return_value=False):
            blocks = [b.block_id for b in path_finder.get_full_routing_path()]

        self.assertNotIn('introduction', blocks)
    def test_repeating_group_block_skip_correct_if_independent_answer_is_repeating(self):
        """ tests blocks are correctly added to path in the case where the blocks have
        skip conditions and those skip conditions are dependant on a repeating answer
        tests various combinations of independent answers being set , since we saw different
        behaviours for group_instance 0 as it was the default"""

        # The skip pattern controls the return values from `evaluate_skip_conditions`
        param_list = [
            (0, 2, [False, True, False, True]),
            (1, 3, [True, False, True, False])
        ]

        for first_group_instance, second_group_instance, skip_pattern in param_list:

            # Given
            with self.subTest(first_group_instance=first_group_instance,
                              second_group_instance=second_group_instance):
                expected_path = [
                    Location('about-household-group', 0, 'household-composition'),
                    Location('household-member-group', 0, 'date-of-birth'),
                    Location('household-member-group', 1, 'date-of-birth'),
                    Location('household-member-group', 2, 'date-of-birth'),
                    Location('household-member-group', 3, 'date-of-birth'),
                    Location('dependant-group', first_group_instance, 'additional-question-block'),
                    Location('dependant-group', second_group_instance, 'additional-question-block'),
                    Location('questionnaire-completed', 0, 'confirmation')
                ]

                schema = load_schema_from_params('test', 'skip_conditions_on_blocks_repeating_group')
                answer_store = AnswerStore()

                # Set up some first names

                answer_store.add(Answer(answer_id='first-name', value='aaa', group_instance=0))
                answer_store.add(Answer(answer_id='first-name', value='bbb', group_instance=1))
                answer_store.add(Answer(answer_id='first-name', value='ccc', group_instance=2))
                answer_store.add(Answer(answer_id='first-name', value='ddd', group_instance=3))

                # Now set a date of birth for the two group instances

                answer_store.add(Answer(answer_id='date-of-birth-answer', value='01-01-1980',
                                        group_instance=first_group_instance))
                answer_store.add(Answer(answer_id='date-of-birth-answer', value='01-01-1980',
                                        group_instance=second_group_instance))

                path_finder = PathFinder(schema, answer_store=answer_store, metadata={}, completed_blocks=[])

                # When
                with patch('app.questionnaire.path_finder.evaluate_skip_conditions', side_effect=skip_pattern):
                    actual_path = path_finder.get_full_routing_path()

                # Then
                self.assertEqual(expected_path, actual_path)
    def test_interstitial_post_blocks(self):
        schema = load_schema_from_params('0', 'star_wars')

        answer = Answer(
            answer_id='choose-your-side-answer',
            value='Light Side'
        )

        answers = AnswerStore()
        answers.add(answer)

        path_finder = PathFinder(schema, answer_store=answers, metadata={}, completed_blocks=[])

        self.assertFalse(Location('star-wars', 0, 'summary') in path_finder.get_full_routing_path())
    def test_repeating_groups_no_of_answers(self):
        schema = load_schema_from_params('test', 'repeating_household')

        expected_path = [
            Location('multiple-questions-group', 0, 'introduction'),
            Location('multiple-questions-group', 0, 'household-composition'),
            Location('repeating-group', 0, 'repeating-block-1'),
            Location('repeating-group', 0, 'repeating-block-2'),
            Location('repeating-group', 0, 'repeating-block-3'),
            Location('repeating-group', 1, 'repeating-block-1'),
            Location('repeating-group', 1, 'repeating-block-2'),
            Location('repeating-group', 1, 'repeating-block-3'),
            Location('repeating-group', 2, 'repeating-block-1'),
            Location('repeating-group', 2, 'repeating-block-2'),
            Location('repeating-group', 2, 'repeating-block-3'),
            Location('summary-group', 0, 'summary'),
        ]

        answer = Answer(
            group_instance=0,
            answer_instance=0,
            answer_id='first-name',
            value='Joe Bloggs'
        )

        answer_2 = Answer(
            group_instance=0,
            answer_instance=1,
            answer_id='first-name',
            value='Sophie Bloggs'
        )

        answer_3 = Answer(
            group_instance=0,
            answer_instance=2,
            answer_id='first-name',
            value='Gregg Bloggs'
        )

        answers = AnswerStore()

        answers.add(answer)
        answers.add(answer_2)
        answers.add(answer_3)

        path_finder = PathFinder(schema, answer_store=answers, metadata={}, completed_blocks=[])

        self.assertEqual(expected_path, path_finder.get_full_routing_path())
    def test_routing_basic_path(self):
        schema = load_schema_from_params('test', '0112')

        expected_path = [
            Location('rsi', 0, 'introduction'),
            Location('rsi', 0, 'reporting-period'),
            Location('rsi', 0, 'total-retail-turnover'),
            Location('rsi', 0, 'internet-sales'),
            Location('rsi', 0, 'changes-in-retail-turnover'),
            Location('rsi', 0, 'number-of-employees'),
            Location('rsi', 0, 'changes-in-employees'),
            Location('rsi', 0, 'summary')
        ]

        path_finder = PathFinder(schema, AnswerStore(), metadata={}, completed_blocks=[])
        routing_path = path_finder.get_full_routing_path()

        self.assertEqual(routing_path, expected_path)
    def test_excessive_repeating_groups_conditional_location_path(self):
        schema = load_schema_from_params('test', 'repeating_and_conditional_routing')
        schema.answer_is_in_repeating_group = MagicMock(return_value=False)

        answers = AnswerStore()

        answers.add(Answer(
            answer_id='no-of-repeats-answer',
            value='10000'
        ))

        for i in range(50):
            answers.add(Answer(
                group_instance=i,
                answer_id='conditional-answer',
                value='Shoe Size Only'
            ))

        path_finder = PathFinder(schema, answer_store=answers, metadata={}, completed_blocks=[])

        self.assertEqual('summary', path_finder.get_full_routing_path().pop().block_id)
    def test_repeating_groups_conditional_location_path(self):
        schema = load_schema_from_params('test', 'repeating_and_conditional_routing')
        schema.answer_is_in_repeating_group = MagicMock(return_value=True)

        expected_path = [
            Location('repeat-value-group', 0, 'introduction'),
            Location('repeat-value-group', 0, 'no-of-repeats'),
            Location('repeated-group', 0, 'repeated-block'),
            Location('repeated-group', 0, 'age-block'),
            Location('repeated-group', 0, 'shoe-size-block'),
            Location('repeated-group', 1, 'repeated-block'),
            Location('repeated-group', 1, 'shoe-size-block'),
            Location('summary-group', 0, 'summary')
        ]

        answer_1 = Answer(
            answer_id='no-of-repeats-answer',
            value='2'
        )

        answer_2 = Answer(
            group_instance=0,
            answer_id='conditional-answer',
            value='Age and Shoe Size'
        )

        answer_3 = Answer(
            group_instance=1,
            answer_id='conditional-answer',
            value='Shoe Size Only'
        )

        answers = AnswerStore()
        answers.add(answer_1)
        answers.add(answer_2)
        answers.add(answer_3)

        path_finder = PathFinder(schema, answer_store=answers, metadata={}, completed_blocks=[])

        self.assertEqual(expected_path, path_finder.get_full_routing_path())