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
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())