Пример #1
0
 def test_evaluate_when_rule_raises_if_bad_when_condition(self):
     when = {"when": [{"condition": "not set"}]}
     answer_store = AnswerStore()
     with self.assertRaises(Exception):
         evaluate_when_rules(
             when["when"], get_schema(), {}, answer_store, ListStore(), None
         )
Пример #2
0
    def test_routing_ignores_answers_not_on_path(self):
        when = {
            'when': [{
                'id': 'some-answer',
                'condition': 'equals',
                'value': 'some value'
            }]
        }
        answer_store = AnswerStore({})
        answer_store.add_or_update(
            Answer(
                answer_id='some-answer',
                value='some value',
                group_instance=0,
            ))

        routing_path = [Location('test', 0, 'test_block_id')]
        with patch('app.questionnaire.rules._get_answers_on_path',
                   return_value=answer_store):
            self.assertTrue(
                evaluate_when_rules(when['when'], get_schema_mock(), {},
                                    answer_store, 0, None))

        with patch('app.questionnaire.rules._is_answer_on_path',
                   return_value=False):
            self.assertFalse(
                evaluate_when_rules(when['when'],
                                    get_schema_mock(), {},
                                    answer_store,
                                    0,
                                    None,
                                    routing_path=routing_path))
    def test_evaluate_when_rules_condition_is_not_met(self):
        # Given
        answer_1 = Answer(
            answer_id='my_answers',
            answer_instance=0,
            group_instance=0,
            value=10,
        )
        answer_2 = Answer(
            answer_id='my_answers',
            answer_instance=1,
            group_instance=0,
            value=20,
        )
        answer_store = AnswerStore({})
        answer_store.add(answer_1)
        answer_store.add(answer_2)

        when = {
            'id': 'next-question',
            'when': [
                {
                    'id': 'my_answers',
                    'condition': 'not set',
                    'value': '2'
                }
            ]
        }

        # When
        with self.assertRaises(Exception) as err:
            evaluate_when_rules(when['when'], get_schema_mock(), None, answer_store, 0)
        self.assertEqual('Multiple answers (2) found evaluating when rule for answer (my_answers)', str(err.exception))
    def test_id_when_rule_uses_passed_in_group_instance_if_present(self):  # pylint: disable=no-self-use
        when = [{'id': 'Some Id',
                 'group_instance': 0,
                 'condition': 'greater than',
                 'value': 0}]

        answer_store = AnswerStore({})
        with patch('app.questionnaire.rules.get_answer_store_value', return_value=False) as patch_val:
            evaluate_when_rules(when, get_schema_mock(), {}, answer_store, 3)  # passed in group instance ignored if present in when
            patch_val.assert_called_with('Some Id', answer_store, 0)
Пример #5
0
    def test_id_when_rule_uses_passed_in_group_instance_if_present(self):
        when = [{
            'id': 'Some Id',
            'group_instance': 0,
            'condition': 'greater than',
            'value': 0
        }]

        answer_store = AnswerStore({})
        with patch('app.questionnaire.rules.get_answer_store_value',
                   return_value=False) as patch_val:
            evaluate_when_rules(
                when, get_schema_mock(), {}, answer_store, 3,
                None)  # passed in group instance ignored if present in when
            self.assertEqual(patch_val.call_args[0][3], 0)
Пример #6
0
    def test_primary_person_checks_location(self):
        answer_store = AnswerStore()
        list_store = ListStore(existing_items=[{
            "name": "people",
            "primary_person": "abcdef",
            "items": ["abcdef", "12345"],
        }])

        current_location = RelationshipLocation(
            section_id="some-section",
            block_id="some-block",
            list_item_id="abcdef",
            to_list_item_id="12345",
        )

        when_rules = [{
            "list": "people",
            "id_selector": "primary_person",
            "condition": "equals",
            "comparison": {
                "source": "location",
                "id": "list_item_id"
            },
        }]

        self.assertTrue(
            evaluate_when_rules(
                when_rules=when_rules,
                schema=get_schema(),
                metadata={},
                answer_store=answer_store,
                list_store=list_store,
                current_location=current_location,
            ))
Пример #7
0
 def test_evaluate_when_rule_raises_exception_if_invalid(self):
     """If there isn't an id, meta key, or a type with value answer_count when attempting to
     get the value of the when condition, an exception is thrown"""
     when = {
         'when': [{
             'type': 'answer_countinvalid',
             'answer_ids': ['id'],
             'condition': 'equals',
             'value': 1,
         }]
     }
     answer_store = AnswerStore({})
     with self.assertRaises(Exception) as err:
         evaluate_when_rules(when['when'], get_schema_mock(), {},
                             answer_store, 0, None)
         self.assertEqual('The when rule is invalid', str(err.exception))
Пример #8
0
    def test_primary_person_returns_false_on_invalid_id(self):
        answer_store = AnswerStore()
        list_store = ListStore(existing_items=[{
            "name": "people",
            "primary_person": "abcdef",
            "items": ["abcdef", "12345"],
        }])

        current_location = Location(section_id="some-section",
                                    block_id="some-block")

        when_rules = [{
            "list": "people",
            "id_selector": "primary_person",
            "condition": "equals",
            "comparison": {
                "source": "location",
                "id": "invalid-location-id"
            },
        }]

        self.assertFalse(
            evaluate_when_rules(
                when_rules,
                get_schema(),
                {},
                answer_store,
                list_store,
                current_location=current_location,
            ))
Пример #9
0
    def test_answer_count_when_rule_equal_2(self):
        """Assert that an `answer_count` can be used in a when block and the
            value is correctly matched """
        answer_group_id = 'repeated-answer'
        when = [{
            'type': 'answer_count',
            'answer_ids': [answer_group_id],
            'condition': 'equals',
            'value': 2,
        }]

        answer_store = AnswerStore({})
        answer_store.add_or_update(
            Answer(
                answer_id=answer_group_id,
                group_instance=0,
                group_instance_id='group-1-0',
                value=10,
            ))
        answer_store.add_or_update(
            Answer(
                answer_id=answer_group_id,
                group_instance=1,
                group_instance_id='group-1-1',
                value=20,
            ))

        self.assertTrue(
            evaluate_when_rules(when, get_schema_mock(), {}, answer_store, 0,
                                None))
Пример #10
0
    def test_evaluate_not_set_when_rules_should_return_true(self):
        when = {'when': [{'id': 'my_answers', 'condition': 'not set'}]}
        answer_store = AnswerStore({})

        self.assertTrue(
            evaluate_when_rules(when['when'], get_schema_mock(), {},
                                answer_store, 0, None))
Пример #11
0
    def test_evaluate_when_rule_with_invalid_list_item_id(self):
        when = {
            "when": [{
                "id": "my_answer",
                "condition": "equals",
                "value": "an answer"
            }]
        }

        answer_store = AnswerStore()
        answer_store.add_or_update(
            Answer(answer_id="my_answer",
                   value="an answer",
                   list_item_id="abc123"))

        current_location = Location(section_id="some-section",
                                    block_id="some-block",
                                    list_item_id="123abc")

        schema = Mock(get_schema())
        schema.get_list_item_id_for_answer_id = Mock(return_value="123abc")

        self.assertFalse(
            evaluate_when_rules(
                when_rules=when["when"],
                schema=schema,
                metadata={},
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))
Пример #12
0
    def test_evaluate_when_rule_fetches_answer_using_list_item_id(self):
        when = {
            "when": [{"id": "my_answer", "condition": "equals", "value": "an answer"}]
        }

        list_item_id = "abc123"

        answer_store = AnswerStore()
        answer_store.add_or_update(
            Answer(answer_id="my_answer", value="an answer", list_item_id=list_item_id)
        )

        current_location = Location(
            section_id="some-section", block_id="some-block", list_item_id=list_item_id
        )

        schema = Mock(get_schema())
        schema.is_repeating_answer = Mock(return_value=True)

        self.assertTrue(
            evaluate_when_rules(
                when_rules=when["when"],
                schema=schema,
                metadata={},
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            )
        )
Пример #13
0
    def test_when_rule_returns_first_item_in_list(self):
        answer_store = AnswerStore()
        list_store = ListStore(
            existing_items=[{"name": "people", "items": ["abcdef", "12345"]}]
        )

        current_location = Location(
            section_id="some-section",
            block_id="some-block",
            list_name="people",
            list_item_id="abcdef",
        )

        when_rules = [
            {
                "list": "people",
                "id_selector": "first",
                "condition": "equals",
                "comparison": {"source": "location", "id": "list_item_id"},
            }
        ]

        self.assertTrue(
            evaluate_when_rules(
                when_rules=when_rules,
                schema=get_schema(),
                metadata={},
                answer_store=answer_store,
                list_store=list_store,
                current_location=current_location,
            )
        )
Пример #14
0
    def test_repeating_group_comparison_with_itself(self):
        """Assert that an `answer_count` can be used in a when block and the
            value is correctly matched """
        answer_group_id = 'repeated-answer'
        when = [{
            'id': answer_group_id,
            'condition': 'equals',
            'comparison_id': 'other'
        }]

        answer_store = AnswerStore({})
        answer_store.add_or_update(
            Answer(
                answer_id=answer_group_id,
                group_instance=0,
                group_instance_id='group-1-0',
                value=2,
            ))
        answer_store.add_or_update(
            Answer(
                answer_id=answer_group_id,
                group_instance=1,
                group_instance_id='group-1-1',
                value=20,
            ))
        answer_store.add_or_update(
            Answer(
                answer_id='other',
                group_instance=0,
                group_instance_id='group-1-0',
                value=0,
            ))
        answer_store.add_or_update(
            Answer(
                answer_id='other',
                group_instance=1,
                group_instance_id='group-1-1',
                value=20,
            ))

        self.assertTrue(
            evaluate_when_rules(when, get_schema_mock(), {}, answer_store, 1,
                                'group-1-1'))
        self.assertFalse(
            evaluate_when_rules(when, get_schema_mock(), {}, answer_store, 0,
                                'group-1-0'))
Пример #15
0
    def test_routing_ignores_answers_not_on_path(self):
        when = {
            "when": [{
                "id": "some-answer",
                "condition": "equals",
                "value": "some value"
            }]
        }
        answer_store = AnswerStore()
        answer_store.add_or_update(
            Answer(answer_id="some-answer", value="some value"))

        routing_path = [
            Location(section_id="some-section", block_id="test_block_id")
        ]
        current_location = Location(section_id="some-section",
                                    block_id="some-block")

        self.assertTrue(
            evaluate_when_rules(
                when_rules=when["when"],
                schema=get_schema(),
                metadata={},
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))

        current_location = Location(section_id="some-section",
                                    block_id="some-block")

        with patch("app.questionnaire.rules._is_answer_on_path",
                   return_value=False):
            self.assertFalse(
                evaluate_when_rules(
                    when_rules=when["when"],
                    schema=get_schema(),
                    metadata={},
                    answer_store=answer_store,
                    list_store=ListStore(),
                    current_location=current_location,
                    routing_path_block_ids=routing_path,
                ))
Пример #16
0
    def test_evaluate_not_set_when_rules_should_return_true(self):
        when = {
            'when': [
                {
                    'id': 'my_answers',
                    'condition': 'not set'
                }
            ]
        }
        answer_store = AnswerStore()

        self.assertTrue(evaluate_when_rules(when, {}, answer_store, 0))
    def test_id_when_rule_answer_count_equal_0(self):
        """Assert that an `answer_count` can be used in a when block and the
            correct value is fetched. """
        answer_group_id = 'repeated-answer'
        when = [{
            'answer_count': answer_group_id,
            'condition': 'equals',
            'value': 0,
        }]

        answer_store = AnswerStore({})
        self.assertTrue(evaluate_when_rules(when, get_schema_mock(), {}, answer_store, 0))
    def test_answer_count_when_rule_not_equal(self):  # pylint: disable=no-self-use
        """Assert that an `answer_count` can be used in a when block and the
            False is returned when the values do not match. """
        answer_group_id = 'repeated-answer'
        when = [{
            'answer_count': answer_group_id,
            'condition': 'equals',
            'value': 1,
        }]
        answer_store = AnswerStore({})

        self.assertFalse(evaluate_when_rules(when, get_schema_mock(), {}, answer_store, 0))
    def _is_section_enabled(self, section):
        if "enabled" not in section:
            return True

        for condition in section["enabled"]:
            if evaluate_when_rules(
                    condition["when"],
                    self._schema,
                    self._metadata,
                    self._answer_store,
                    self._list_store,
            ):
                return True
        return False
Пример #20
0
    def test_answer_count_when_rule_not_equal(self):
        """Assert that an `answer_count` can be used in a when block and the
            False is returned when the values do not match. """
        answer_group_id = 'repeated-answer'
        when = [{
            'type': 'answer_count',
            'answer_ids': [answer_group_id],
            'condition': 'equals',
            'value': 1,
        }]
        answer_store = AnswerStore({})

        self.assertFalse(
            evaluate_when_rules(when, get_schema_mock(), {}, answer_store, 0,
                                None))
Пример #21
0
    def test_evaluate_not_set_when_rules_should_return_true(self):
        when = {"when": [{"id": "my_answers", "condition": "not set"}]}
        answer_store = AnswerStore()

        current_location = Location(section_id="some-section",
                                    block_id="some-block")

        self.assertTrue(
            evaluate_when_rules(
                when_rules=when["when"],
                schema=get_schema(),
                metadata={},
                answer_store=answer_store,
                list_store=ListStore(),
                current_location=current_location,
            ))
def get_title_from_titles(metadata,
                          schema,
                          answer_store,
                          titles,
                          group_instance,
                          group_instance_id=None):
    """returns a title from titles available by evaluating the when rules , if all fail returns default"""
    for when, value in ((title['when'], title['value']) for title in titles
                        if 'when' in title):
        if evaluate_when_rules(when,
                               schema,
                               metadata,
                               answer_store,
                               group_instance,
                               group_instance_id=group_instance_id):
            return value
    return titles[-1]['value']
Пример #23
0
    def test_list_rules_equals(self):
        answer_store = AnswerStore()
        list_store = ListStore(existing_items=[{"name": "people", "items": ["abcdef"]}])

        when_rules = [{"list": "people", "condition": "equals", "value": 1}]

        current_location = Location(section_id="some-section", block_id="some-block")

        self.assertTrue(
            evaluate_when_rules(
                when_rules=when_rules,
                schema=get_schema(),
                metadata={},
                answer_store=answer_store,
                list_store=list_store,
                current_location=current_location,
            )
        )
Пример #24
0
    def test_routing_answer_not_on_path_when_in_a_repeat(self):
        when = {
            "when": [
                {"id": "some-answer", "condition": "equals", "value": "some value"}
            ]
        }

        answer_store = AnswerStore()
        answer = Answer(answer_id="some-answer", value="some value")
        answer_store.add_or_update(answer)

        routing_path = [
            Location(
                section_id="some-section",
                block_id="test_block_id",
                list_name="people",
                list_item_id="abc123",
            )
        ]
        current_location = Location(
            section_id="some-section",
            block_id="some-block",
            list_name="people",
            list_item_id="abc123",
        )

        with patch(
            "app.questionnaire.rules.get_answer_for_answer_id", return_value=answer
        ):
            with patch(
                "app.questionnaire.rules._is_answer_on_path", return_value=False
            ):

                self.assertFalse(
                    evaluate_when_rules(
                        when_rules=when["when"],
                        schema=get_schema(),
                        metadata={},
                        answer_store=answer_store,
                        list_store=ListStore(),
                        current_location=current_location,
                        routing_path_block_ids=routing_path,
                    )
                )
    def test_answer_count_when_rule_id_takes_precident(self):
        """Assert that if somehow, both `id` and `answer_count` are present in a when clause
            the `id` takes precident and no errors are thrown. """
        answer_group_id = 'repeated-answer'
        ref_id = 'just-a-regular-answer'
        when = [{
            'id': ref_id,
            'answer_count': answer_group_id,
            'condition': 'equals',
            'value': 10,
        }]
        answer_store = AnswerStore({})
        answer_store.add(Answer(
            answer_id=ref_id,
            group_instance=0,
            value=10,
        ))

        self.assertTrue(evaluate_when_rules(when, get_schema_mock(), {}, answer_store, 0))
Пример #26
0
    def get_question(block_schema, answer_store, list_store, metadata, schema,
                     location):
        """ Taking question variants into account, return the question which was displayed to the user """
        list_item_id = location.list_item_id
        for variant in block_schema.get("question_variants", []):
            display_variant = evaluate_when_rules(
                variant.get("when"),
                schema,
                metadata,
                answer_store,
                list_store,
                location,
            )
            if display_variant:
                return Question(variant["question"], answer_store, schema,
                                list_item_id).serialize()

        return Question(block_schema["question"], answer_store, schema,
                        list_item_id).serialize()
Пример #27
0
    def test_answer_count_when_rule_equal_1(self):
        """Assert that an `answer_count` can be used in a when block and the
            correct value is fetched. """
        answer_group_id = 'repeated-answer'
        when = [{
            'type': 'answer_count',
            'answer_ids': [answer_group_id],
            'condition': 'equals',
            'value': 1,
        }]

        answer_store = AnswerStore({})
        answer_store.add(
            Answer(
                answer_id=answer_group_id,
                group_instance=0,
                value=10,
            ))

        self.assertTrue(
            evaluate_when_rules(when, get_schema_mock(), {}, answer_store, 0,
                                None))
Пример #28
0
def _choose_variant(
    block,
    schema,
    metadata,
    answer_store,
    list_store,
    variants_key,
    single_key,
    current_location,
):
    if block.get(single_key):
        return block[single_key]

    for variant in block.get(variants_key, []):
        when_rules = variant.get("when", [])
        if evaluate_when_rules(
            when_rules,
            schema,
            metadata,
            answer_store,
            list_store,
            current_location=current_location,
        ):
            return variant[single_key]
Пример #29
0
    def test_when_rule_comparing_answer_values(self):
        answers = {
            "low":
            Answer(answer_id="low", value=1),
            "medium":
            Answer(answer_id="medium", value=5),
            "high":
            Answer(answer_id="high", value=10),
            "list_answer":
            Answer(answer_id="list_answer", value=["a", "abc", "cba"]),
            "other_list_answer":
            Answer(answer_id="other_list_answer", value=["x", "y", "z"]),
            "other_list_answer_2":
            Answer(answer_id="other_list_answer_2", value=["a", "abc", "cba"]),
            "text_answer":
            Answer(answer_id="small_string", value="abc"),
            "other_text_answer":
            Answer(answer_id="other_string", value="xyz"),
        }

        # An answer that won't be added to the answer store.
        missing_answer = Answer(answer_id="missing", value=1)

        param_list = [
            (answers["medium"], "equals", answers["medium"], True),
            (answers["medium"], "equals", answers["low"], False),
            (answers["medium"], "greater than", answers["low"], True),
            (answers["medium"], "greater than", answers["high"], False),
            (answers["medium"], "less than", answers["high"], True),
            (answers["medium"], "less than", answers["low"], False),
            (answers["medium"], "equals", missing_answer, False),
            (answers["list_answer"], "contains", answers["text_answer"], True),
            (answers["list_answer"], "contains", answers["other_text_answer"],
             False),
            (
                answers["list_answer"],
                "not contains",
                answers["other_text_answer"],
                True,
            ),
            (answers["list_answer"], "not contains", answers["text_answer"],
             False),
            (
                answers["list_answer"],
                "contains any",
                answers["other_list_answer_2"],
                True,
            ),
            (
                answers["list_answer"],
                "contains any",
                answers["other_list_answer"],
                False,
            ),
            (
                answers["list_answer"],
                "contains all",
                answers["other_list_answer"],
                False,
            ),
            (
                answers["list_answer"],
                "contains all",
                answers["other_list_answer_2"],
                True,
            ),
            (answers["text_answer"], "equals any", answers["list_answer"],
             True),
            (answers["text_answer"], "equals any",
             answers["other_list_answer"], False),
            (
                answers["text_answer"],
                "not equals any",
                answers["other_list_answer"],
                True,
            ),
            (answers["text_answer"], "not equals any", answers["list_answer"],
             False),
        ]

        for lhs, comparison, rhs, expected_result in param_list:
            # Given
            with self.subTest(lhs=lhs,
                              comparison=comparison,
                              rhs=rhs,
                              expected_result=expected_result):
                answer_store = AnswerStore()
                for answer in answers.values():
                    answer_store.add_or_update(answer)

                when = [{
                    "id": lhs.answer_id,
                    "condition": comparison,
                    "comparison": {
                        "id": rhs.answer_id,
                        "source": "answers"
                    },
                }]

                current_location = Location(section_id="some-section",
                                            block_id="some-block")

                self.assertEqual(
                    evaluate_when_rules(
                        when_rules=when,
                        schema=get_schema(),
                        metadata={},
                        answer_store=answer_store,
                        list_store=ListStore(),
                        current_location=current_location,
                        routing_path_block_ids=None,
                    ),
                    expected_result,
                )
Пример #30
0
 def test_evaluate_when_rule_raises_if_bad_when_condition(self):
     when = {'when': [{'condition': 'not set'}]}
     answer_store = AnswerStore({})
     with self.assertRaises(Exception):
         evaluate_when_rules(when['when'], get_schema_mock(), {},
                             answer_store, 0, None)